Skip to content

Instantly share code, notes, and snippets.

@TongilKim
Created September 24, 2022 07:51
Show Gist options
  • Save TongilKim/35119c77f98802cfd92cb0fb94e8303c to your computer and use it in GitHub Desktop.
Save TongilKim/35119c77f98802cfd92cb0fb94e8303c to your computer and use it in GitHub Desktop.
vanilla js carosal silder
<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>
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';
}
#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