진스
휠 이벤트,터치 이벤트,스크롤을 원하는 속도로 부드럽게 이동하기 본문
메인 상단에 영상 + 이미지 스와이프 배너가 있음
pc와 모바일에서 휠을 내리거나 , 밑으로 스와이프를 하면 자연스럽게 메인배너 밑으로 스크롤 이동되길 원함
기본적으로 모바일에서 touch이벤트시에
window.scrollTo({
top: targetScrollY,
behavior: 'smooth'
}); 이부분만으로는 좀더 빠른 스크롤이동이 안됨
그래서 작성한 코드:
///////////////////////////메인슬라이드 휠 동작
let isScrolling = false;
let isWheeling = false;
const mainVisualElement = document.querySelector('.mainVisual');
const mainVisualHeight = mainVisualElement.clientHeight;
document.addEventListener('wheel', function(event) {
const scrollTop = window.scrollY;
const SCROLL_THRESHOLD = 0;
if (!isWheeling && event.deltaY > SCROLL_THRESHOLD && scrollTop < mainVisualHeight) {
event.preventDefault();
isWheeling = true;
isScrolling = true;
const targetScrollY = mainVisualHeight;
const duration = 500; // 애니메이션 지속 시간 (ms)
const startTime = performance.now();
const startScrollY = window.scrollY;
function scroll() {
const elapsed = performance.now() - startTime;
const progress = Math.min(elapsed / duration, 1); // 진행률 계산 (0~1 사이 값)
const easeInOutQuad = t => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; // 이징 함수 정의 (선택 사항)
const easedProgress = easeInOutQuad(progress); // 선택적으로 이징 함수를 적용할 수 있습니다.
const newScrollY = startScrollY + (targetScrollY - startScrollY) * easedProgress;
window.scrollTo(0, newScrollY);
if (progress < 1) {
requestAnimationFrame(scroll);
} else {
isScrolling = false;
}
}
requestAnimationFrame(scroll);
setTimeout(() => {
isWheeling = false;
}, 500); // 휠 애니메이션이 끝날 때까지 대기
}
}, { passive: false });
window.addEventListener('scroll', function() {
const scrollTop = window.scrollY;
// 메인 비주얼을 벗어나면 isScrolling 상태를 해제
if (scrollTop >= mainVisualHeight) {
isScrolling = false;
}
});
///////////////////////////메인슬라이드 모바일 스와이프 동작
let touchStartY = 0;
let touchEndY = 0;
const swipeThreshold = 50;
const duration = 500; // 애니메이션 지속 시간 (ms)
mainVisualElement.addEventListener('touchstart', function(event) {
touchStartY = event.touches[0].clientY;
});
mainVisualElement.addEventListener('touchmove', function(event) {
touchEndY = event.touches[0].clientY;
// 위로 스와이프할 때 preventDefault 활성화
if (touchStartY > touchEndY && window.pageYOffset < mainVisualHeight) {
event.preventDefault();
}
});
mainVisualElement.addEventListener('touchend', function(event) {
touchEndY = event.changedTouches[0].clientY;
if (Math.abs(touchStartY - touchEndY) > swipeThreshold) {
if (touchStartY > touchEndY && window.pageYOffset < mainVisualHeight) {
moveMainVisual(mainVisualHeight); // 위로 스와이프할 때
} else if (touchStartY < touchEndY && window.pageYOffset >= mainVisualHeight) {
moveMainVisual(0); // 아래로 스와이프할 때
}
}
});
function moveMainVisual(targetScrollY) {
const startScrollY = window.scrollY;
const startTime = performance.now();
function scroll() {
const elapsed = performance.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
const easeInOutQuad = t => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
const easedProgress = easeInOutQuad(progress);
const newScrollY = startScrollY + (targetScrollY - startScrollY) * easedProgress;
window.scrollTo(0, newScrollY);
if (progress < 1) {
requestAnimationFrame(scroll);
}
}
scroll();
}
'JavaScript' 카테고리의 다른 글
숫자 키패드 입력시 다음 input으로 이동 (0) | 2024.01.17 |
---|---|
swiper.js 가운데 정렬 및 기타 옵션 (0) | 2023.08.10 |
find 함수에서 Arrow Function(화살표 함수)에서 undefined 일때 확인해볼 내용 (0) | 2023.02.19 |
es6 유용한 문법 (0) | 2022.11.09 |
페이지마다 해당 메뉴명에 색상 다르게 주기(속성값에 문자열이 포함확인) (0) | 2022.08.04 |