JavaScript로 Scroll Reveal Animation 구현하기
Next.js 로 프로젝트 중 토스 홈페이지를 보고 스크롤 이벤트 시 요소들이 여러 방향으로 나타나는 애니메이션을 프로젝트 소개 페이지(Intro Page)에 적용하고 싶었습니다. 그래서 React로 만들기에 앞서 JavaScript로 구현하여 원리를 파악하려 합니다. 다음 자료를 참고하여 구현해 보았습니다.
✅ 구현하고 싶은 내용
Scroll Reveal Animation를 적용하고 싶은 요소가 viewport에 들어왔을 때 애니메이션이 실행되게 하려고 합니다.
✅ transition, transform, animation
transition
transition: property duration timing-function delay;
- transition은 hover나 onClick과 같은 이벤트 트리거에 의해 동작합니다.
- 예시
div {
width: 100px;
height: 50px;
background-color: red;
margin-bottom: 10px;
transition-property: width,
background-color; /* 어떤 css 프로퍼티(width)를 transition할지 지정 */
transition-duration: 2s, 2s; /* width와 bg-color가 2초동안 변화 */
}
div:hover { /* 마우스를 올리면 transition발동해서 적용될 상태 */
width: 300px;
background-color: blue;
}
transform
transform : scale(x,y) translate(x,y) rotate(deg) skew(xdeg,ydeg);
CSS animation
- 애니메이션을 사용하면 트랜지션보다 화려한 css를 구현할 수 있습니다.
- 트랜지션은 시작하기 위해 이벤트가 필요하지만 애니메이션은 시작, 정지, 반복까지 제어할 수 있습니다.
animation : @keyframes의 이름 animation-delay animation-duration animation-timing-function
animation-name
: 키프레임 이름 (필수)animation-iteration-count
: 애니메이션 반복 횟수, infinite를 적어주면 무한반복 됩니다.animation-direction
: 애니메이션 방향으로 normal, reverse, alternate, alternate-reverse가 있습니다.- normal: 정방향
- reverse: 역방향
- alternate: 정방향 ➡️ 역방향 ➡️ 정방향 ... (alternate는 반복이 2이상 일 때부터 확인할 수 있습니다.)
- alternate-reverse: 역방향 ➡️ 정방향 ➡️ 역방향...
animation-fill-mode
: 애니메이션이 재생되지 않을 때 (애니메이션 시작 전(대기), 끝난 후(종료)) element의 스타일을 지정합니다.- none: 애니메이션 실행 전후 요소에 스타일 반영 x (애니메이션 종료 후 속성 값을 되돌림)
- forwards: 마지막 키 프레임에서 설정한 스타일 값을 유지
- backwards: 첫 번째 키 프레임(애니메이션 방향에 따라 다릅니다.)에 의해 설정된 스타일 값을 가져오고 애니메이션 지연 기간 동안 이를 유지
- both: forwards, backwards를 모두 따름
@keyframes [키프레임 이름] {
0% {background-color:red; left:0px; top:0px;}
25% {background-color:yellow; left:200px; top:0px;}
50% {background-color:blue; left:200px; top:200px;}
75% {background-color:green; left:0px; top:200px;}
100% {background-color:red; left:0px; top:0px;}
}
✅ getBoundingClientRect(), window.innerHeight() ,clientHeight() 을 이용하여 구현하기
el.getBoundingClientRect().top() 값과 document.document.clientHeight() (= 뷰포트 높이 값) 값을 이용해서 스크롤시 element가 나타나고 사라지는 순간을 포착하고, element가 viewport에 노출되는 순간 스타일(".js-scroll")을 추가해 애니메이션이 시작하게 하고, 끝나면 제거하는 방법으로 구현했습니다. IE8 이하 버전에서는 window.innerHeight가 지원되지 않기 때문에 window.innerHeight()를 이용한 조건도 함께 달아줄 수 있습니다.
const scrollElements = document.querySelectorAll('.js-scroll')
const elementInView = (el, dividend = 1) => {
const elementTop = el.getBoundingClientRect().top
// viewport 기준 element top이 보이기 시작할때는 감지한다.
return (
elementTop <=
(window.innerHeight || document.documentElement.clientHeight / dividend) // dividend // 4/5 배
)
}
// el가 viewport 아래로 사라질때를 감지한다.
const elementOutofView = (el) => {
const elementTop = el.getBoundingClientRect().top
return (
elementTop > window.innerHeight || document.documentElement.clientHeight
)
}
const displayScrollElement = (el) => {
el.classList.add('scrolled')
}
const hideScrollElement = (el) => {
el.classList.remove('scrolled')
}
const handleScrollAnimation = () => {
scrollElements.forEach((el) => {
if (elementInView(el, 1.25)) {
displayScrollElement(el)
} else if (elementOutofView(el)) {
hideScrollElement(el)
}
})
}
window.addEventListener('scroll', () => {
handleScrollAnimation()
})
✅ 결과물
다음 게시물에서는 React로 구현해보고 애니메이션 실행 방향을 props으로 받아서 component로 만들어 보려고 합니다.
React로 Scroll Reveal Animation 구현하고 컴포넌트화 하기
<figure id="og_1714447333650" contenteditable="false" data-ke-type="opengraph" data-ke-align="alignCenter" data-og-type="article" data-og-title="JavaScript로 Scroll Reveal Animation 구현하기" data-og-description="Next.js 로 프로젝트 중 토스
dev-ea-jung.tistory.com