728x90
기본적인 아이디어는 아래 링크로 걸어둔 Easing 기법을 이용한다.
https://spicyyoghurt.com/tools/easing-functions
Easing Functions for JavaScript - Animation Tool | Spicy Yoghurt
Get easing function for JavaScript and try them out on your own custom motions, using the animation tool. You can create animations in an interactive way and see the effects of using different easing functions. When satisfied, look-up the matching equation
spicyyoghurt.com
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>자바스크립트 연습</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<div class="actions">
<span class="prev"><</span>
<span class="next">></span>
</div>
<div class="carousel">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
<div class="card">6</div>
<div class="card">7</div>
<div class="card">8</div>
<div class="card">9</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
<div class="card">13</div>
<div class="card">14</div>
<div class="card">15</div>
<div class="card">16</div>
<div class="card">17</div>
<div class="card">18</div>
<div class="card">19</div>
<div class="card">20</div>
</div>
</div>
<script src='app.js'></script>
</body>
</html>
.container{
width: 50%; height: 300px;
position: relative;
}
span{
position: absolute;
top: 50%; transform: translateY(-50%);
color: white;
font-size: 2rem;
background-color: rgba(0, 0, 0, .3);
width: 50px; height: 50px;
border-radius: 50%;
text-align: center;
cursor: pointer;
}
span.prev{
left: 1rem;
}
span.next{
right: 1rem;
}
.carousel{
width: 100%; height: 100%;
display: flex;
grid-gap: 10px;
background-color: bisque;
overflow-x: scroll;
}
.card{
min-width: 200px; height: 100%;
background-color: aquamarine;
text-align: center;
line-height: 300px;
font-weight: bold;
font-size: 10rem;
color: white;
/* border: 1px solid red; */
}
아래와 같이 setInterval 타이머를 걸어두고 스크롤이 끝나기 전에 다시 next 버튼을 클릭하면 타이머가 새로 생성되면서 timer id 가 새로 할당된다. 이렇게 되면 스크롤이 끝났을때 새로 생성된 타이머는 해제가 되지만 이전에 생성된 타이머는 ID 값을 더이상 조회할 수 없기 때문에 해제되지 않고 백그라운드에서 계속 실행된다. 그래서 스크롤이 멈추지 않고 반복적으로 계속 실행된다.
const prevBtn = document.querySelector('.prev')
const nextBtn = document.querySelector('.next')
const carousel = document.querySelector('.carousel')
let timerId = null
let currentTime = 0
function changePosition(unitTime, start, destination){
currentTime += unitTime
if(currentTime < 1){
console.log('ongoing')
carousel.scrollLeft = easeOutExpo(currentTime, start, destination, 1)
// nextBtn.removeEventListener('click', toNextSlides)
}else{
console.log('end')
currentTime = 0
clearInterval(timerId)
// nextBtn.addEventListener('click', toNextSlides)
}
}
function toNextSlides(){
timerId = setInterval(() => changePosition(0.03, 0, 500), 100)
}
prevBtn.addEventListener('click', function(){
})
nextBtn.addEventListener('click', toNextSlides)
function easeOutExpo (t, b, c, d) {
return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
}
이런 문제를 해결하려면 스크롤이 되고 있는중에는 사용자가 버튼을 클릭하지 못하도록 잠깐 클릭 이벤트를 해제했다가 스크롤이 끝났을때 다시 등록해야 한다.
const prevBtn = document.querySelector('.prev')
const nextBtn = document.querySelector('.next')
const carousel = document.querySelector('.carousel')
let timerId = null
let currentTime = 0
function changePosition(unitTime, start, destination){
currentTime += unitTime
if(currentTime < 1){
console.log('ongoing')
carousel.scrollLeft = easeOutExpo(currentTime, start, destination, 1)
nextBtn.removeEventListener('click', toNextSlides)
}else{
console.log('end')
currentTime = 0
clearInterval(timerId)
nextBtn.addEventListener('click', toNextSlides)
}
}
function toNextSlides(){
timerId = setInterval(() => changePosition(0.03, 0, 500), 100)
}
prevBtn.addEventListener('click', function(){
})
nextBtn.addEventListener('click', toNextSlides)
function easeOutExpo (t, b, c, d) {
return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
}
728x90
'프론트엔드 > 컴포넌트' 카테고리의 다른 글
부드러운 가로 스크롤링 (3) - ease 함수 사용 (0) | 2023.07.06 |
---|---|
로딩 애니메이션 (0) | 2023.07.05 |
부드러운 가로 스크롤링 (0) | 2023.06.27 |
자동 슬라이드 만들기 (1) (0) | 2023.04.24 |
자바스크립트없이 드롭다운 메뉴 만들기 (3) (0) | 2023.04.14 |