Last active
June 14, 2022 16:46
-
-
Save kobitoDevelopment/d979a4dab2bb0eda175dc05b62e6e7ac to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <button class="prev">prev</button> | |
| <button class="next">next</button> | |
| <div class="circle-wrap"> | |
| <div class="circle-item">1</div> | |
| <div class="circle-item">2</div> | |
| <div class="circle-item">3</div> | |
| <div class="circle-item">4</div> | |
| <div class="circle-item">5</div> | |
| <div class="circle-item">6</div> | |
| <div class="circle-item">7</div> | |
| <div class="circle-item">8</div> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const deviceWidth = window.innerWidth; | |
| const circleWrap = document.querySelector(".circle-wrap"); | |
| const circleItem = document.querySelectorAll(".circle-item"); | |
| const circleItemLength = circleItem.length; | |
| const deg = 360.0 / circleItemLength; | |
| const red = (deg * Math.PI) / 180.0; | |
| let xArray = []; | |
| let maxDiameter; | |
| const buttonPrev = document.querySelector(".prev"); | |
| const buttonNext = document.querySelector(".next"); | |
| const rotateSize = 360 / circleItemLength; | |
| let nextRotateSize = 0; | |
| const slideTime = 4000; | |
| let timer; | |
| // 自動スライドを設定 | |
| function startTimer() { | |
| timer = setInterval(function () { | |
| buttonNext.click(); | |
| }, slideTime); | |
| } | |
| // 自動スライドの停止を設定 | |
| function stopTimer() { | |
| clearInterval(timer); | |
| } | |
| window.addEventListener("load", function () { | |
| circleItem.forEach(function (elem, index) { | |
| const circleR = elem.offsetWidth * 1.4; // 要素同士の感覚比率 | |
| const x = Math.cos(red * index) * circleR + circleR; | |
| const y = Math.sin(red * index) * circleR + circleR; | |
| elem.style.left = x + "px"; | |
| elem.style.top = y + "px"; | |
| const circleWidth = document.defaultView.getComputedStyle(elem, null).width; | |
| const circleLeft = document.defaultView.getComputedStyle(elem, null).left; | |
| const circleWidthNum = Number(parseFloat(circleWidth)); | |
| const circleLeftNum = Number(parseFloat(circleLeft)); | |
| xArray.push(circleLeftNum); | |
| // Math.max Math.min は複数の数値を比較できるが配列を比較できないためスプレッド構文で渡す | |
| const maxLeft = Math.max(...xArray); | |
| // 最もleftの大きい要素+要素幅を合計する事で円周上に配置された要素全体の横幅を算出 | |
| maxDiameter = maxLeft + circleWidthNum; | |
| }); | |
| circleWrap.style.width = maxDiameter + "px"; | |
| circleWrap.style.height = maxDiameter + "px"; | |
| // コンテンツ幅が画面幅を超えた場合 | |
| if (deviceWidth < maxDiameter) { | |
| // 両橋を見切れさせて中央寄せ | |
| const dif = (deviceWidth - maxDiameter) / 2; | |
| circleWrap.style.left = dif + "px"; | |
| } | |
| buttonNext.addEventListener("click", function () { | |
| nextRotateSize = nextRotateSize + rotateSize; | |
| circleWrap.style.transform = `rotate(${nextRotateSize}deg)`; | |
| circleItem.forEach(function (elem, index) { | |
| /// -(x)でxが正数なら負数へ、xが負数なら正数へ変換する事でwrapとitemのrotate数値を反転 | |
| elem.style.transform = `rotate(${-nextRotateSize}deg)`; | |
| }); | |
| }); | |
| buttonPrev.addEventListener("click", function () { | |
| nextRotateSize = nextRotateSize - rotateSize; | |
| circleWrap.style.transform = `rotate(${nextRotateSize}deg)`; | |
| circleItem.forEach(function (elem, index) { | |
| /// -(x)でxが正数なら負数へ、xが負数なら正数へ変換する事でwrapとitemのrotate数値を反転 | |
| elem.style.transform = `rotate(${-nextRotateSize}deg)`; | |
| }); | |
| }); | |
| // 自動スライド発火 | |
| startTimer(); | |
| circleItem.forEach(function (elem, index) { | |
| // マウスオンで自動スライド停止 | |
| elem.addEventListener("mouseover", function () { | |
| stopTimer(); | |
| }); | |
| // マウスリーブで自動スライド再開 | |
| elem.addEventListener("mouseleave", function () { | |
| startTimer(); | |
| }); | |
| }); | |
| }); | |
| // リザイズ時に円周場の要素を再配置 | |
| window.addEventListener("resize", function () { | |
| stopTimer(); | |
| xArray = []; | |
| const deviceWidth = window.innerWidth; | |
| circleItem.forEach(function (elem, index) { | |
| const circleR = elem.offsetWidth * 1.4; | |
| const x = Math.cos(red * index) * circleR + circleR; | |
| const y = Math.sin(red * index) * circleR + circleR; | |
| elem.style.left = x + "px"; | |
| elem.style.top = y + "px"; | |
| const circleWidth = document.defaultView.getComputedStyle(elem, null).width; | |
| const circleLeft = document.defaultView.getComputedStyle(elem, null).left; | |
| const circleWidthNum = Number(parseFloat(circleWidth)); | |
| const circleLeftNum = Number(parseFloat(circleLeft)); | |
| xArray.push(circleLeftNum); | |
| // Math.max Math.min は複数の数値を比較できるが配列を比較できないためスプレッド構文で渡す | |
| const maxLeft = Math.max(...xArray); | |
| maxDiameter = maxLeft + circleWidthNum; | |
| }); | |
| circleWrap.style.width = maxDiameter + "px"; | |
| circleWrap.style.height = maxDiameter + "px"; | |
| if (deviceWidth < maxDiameter) { | |
| const dif = (deviceWidth - maxDiameter) / 2; | |
| circleWrap.style.left = dif + "px"; | |
| } | |
| startTimer(); | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| .circle-wrap { | |
| position: relative; | |
| top: 0; | |
| left: 0; | |
| z-index: 1; | |
| margin-right: auto; | |
| margin-left: auto; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| transform-origin: center; | |
| transition: 1s 0.1s; | |
| .circle-item { | |
| width: 30vw; //希望の円形要素1つの横幅 | |
| max-width: 200px; // 希望の最大幅 | |
| aspect-ratio: 1/1; | |
| background-color: orange; //デバッグ用背景 | |
| border-radius: 50%; | |
| position: absolute; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| transform-origin: center; | |
| transition: 1s 0.1s; | |
| } | |
| } | |
| .prev { | |
| z-index: 2; | |
| } | |
| .next { | |
| z-index: 2; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment