A Pen by KumJungMin on CodePen.
Created
September 24, 2022 07:51
-
-
Save TongilKim/35119c77f98802cfd92cb0fb94e8303c to your computer and use it in GitHub Desktop.
vanilla js carosal silder
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
| <div id="slider"> | |
| <button class="btn prev"><</button> | |
| <div class="wrapper"> | |
| <div class="items"> | |
| <div class="item"></div> | |
| <div class="item"><div class="content pink">1</div></div> | |
| <div class="item"><div class="content yellow">2</div></div> | |
| <div class="item"><div class="content skyblue">3</div></div> | |
| <div class="item"><div class="content orange">4</div></div> | |
| <div class="item"></div> | |
| </div> | |
| </div> | |
| <button class="btn next">></button> | |
| </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 silder = document.querySelector('#slider'); | |
| const wrapper = document.querySelector('.wrapper'); | |
| const items = document.querySelector('.items'); | |
| const item = document.querySelectorAll('.item'); | |
| const next = document.querySelector('.next'); | |
| const prev = document.querySelector('.prev'); | |
| const itemCount = item.length - 2; | |
| let startX = 0; //mousedown시 위치 | |
| let moveX = 0; //움직인 정도 | |
| let currentIdx = 0; //현재 위치(index) | |
| let positions = []; | |
| function initializeData() { | |
| const isActive = items.classList.contains('active'); | |
| if (isActive) items.classList.remove('active'); | |
| const width = wrapper.clientWidth; | |
| const interval = item[1].clientWidth; | |
| const margin = (width - interval) / 2 | |
| const initX = Math.floor((interval - margin) * -1); | |
| let pos = []; | |
| for (let i=0; i<itemCount; i++) { | |
| pos.push(initX - interval * i); | |
| } | |
| positions = pos; | |
| items.style.width = (itemCount + 1)*100 + '%'; | |
| items.style.left = positions[currentIdx] + 'px'; | |
| silder.style.visibility = 'visible'; | |
| } | |
| window.addEventListener('resize', initializeData); | |
| window.addEventListener('load', initializeData); | |
| // btn click event | |
| next.addEventListener('click', (e) => { | |
| if (currentIdx === itemCount - 1) return; | |
| const isActive = items.classList.contains('active'); | |
| if (!isActive) items.classList.add('active'); | |
| currentIdx = currentIdx + 1; | |
| items.style.left = positions[currentIdx] + 'px'; | |
| }); | |
| prev.addEventListener('click', (e) => { | |
| if (currentIdx === 0) return; | |
| const isActive = items.classList.contains('active'); | |
| if (!isActive) items.classList.add('active'); | |
| currentIdx = currentIdx - 1; | |
| items.style.left = positions[currentIdx] + 'px'; | |
| }); | |
| wrapper.onmousedown =(e)=> { | |
| const rect = wrapper.getBoundingClientRect(); | |
| startX = e.clientX - rect.left; | |
| const isActive = items.classList.contains('active'); | |
| if (!isActive) items.classList.add('active'); | |
| items.addEventListener('mousemove', onMouseMove); | |
| document.onmouseup =(e)=> { | |
| if (wrapper.classList.contains('active')) wrapper.classList.remove('active'); | |
| items.removeEventListener('mousemove', onMouseMove); | |
| document.onmouseup = null; | |
| if (moveX > -70 && moveX <= 70) { | |
| // 만약 -70~70이면 초기위치로 이동 | |
| return items.style.left = positions[currentIdx] + 'px'; | |
| } | |
| if (moveX > 0 && currentIdx > 0) { | |
| currentIdx = currentIdx - 1; | |
| items.style.left = positions[currentIdx] + 'px'; | |
| } | |
| if (moveX < 0 && currentIdx < itemCount - 1){ | |
| currentIdx = currentIdx + 1; | |
| items.style.left = positions[currentIdx] + 'px'; | |
| } | |
| } | |
| } | |
| function onMouseMove(e) { | |
| if (!wrapper.classList.contains('active')) wrapper.classList.add('active'); | |
| const rect = wrapper.getBoundingClientRect(); | |
| moveX = e.clientX - rect.left - startX; | |
| const left = positions[currentIdx] + moveX; | |
| if (currentIdx === 0 && moveX > 0) return; | |
| else if(currentIdx === itemCount - 1 && moveX < 0) return; | |
| items.style.left = left + 'px'; | |
| } |
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
| #slider { | |
| position: relative; | |
| width: 100%; | |
| margin: 0 auto; | |
| visibility: hidden; | |
| } | |
| .btn { | |
| position: absolute; | |
| width: 3rem; | |
| height: 100%; | |
| top: 50%; | |
| transform: translateY(-50%); | |
| z-index: 1; | |
| border: 0; | |
| background: rgba(250, 250, 250, 0.3); | |
| transition: 0.2s; | |
| cursor: pointer; | |
| font-size: 2rem; | |
| background: #c3c3c3; | |
| opacity: 0.3; | |
| &:hover { | |
| background: rgba(250, 250, 250, 0.5); | |
| } | |
| &.prev { | |
| left: 0; | |
| } | |
| &.next { | |
| right: 0; | |
| } | |
| } | |
| .wrapper { | |
| position: relative; | |
| width: 100%; | |
| height: 18rem; | |
| overflow: hidden; | |
| padding: 3px 0; | |
| cursor: grab; | |
| &.active { | |
| cursor: grabbing; | |
| } | |
| } | |
| .items { | |
| position: absolute; | |
| width: 500%; //itemCount - 1 | |
| left: 0; | |
| top: 0; | |
| display: flex; | |
| } | |
| .items.active { | |
| transition: 0.3s; | |
| } | |
| .item { | |
| width: 100%; | |
| pointer-events: none; | |
| position: relative; | |
| padding: 0 1rem; | |
| .content { | |
| width: 100%; | |
| height: 18rem; | |
| border: 1px solid #c8c8c8; | |
| box-shadow: 0 1rem 2.8rem rgba(0, 0, 0, 0.05); | |
| border-radius: 1rem; | |
| background-color: #fff; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-weight: 700; | |
| font-size: 5rem; | |
| color: #fff; | |
| } | |
| } | |
| .content { | |
| &.pink { | |
| background: linear-gradient(315deg, #e899dc 0%, #d387ab 74%); | |
| } | |
| &.yellow { | |
| background: linear-gradient(315deg, #fce043 0%, #fb7ba2 74%); | |
| } | |
| &.skyblue { | |
| background-image: linear-gradient(315deg, #5de6de 0%, #b58ecc 74%); | |
| } | |
| &.orange { | |
| background-image: linear-gradient(315deg, #fc9842 0%, #fe5f75 74%); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment