스크롤 애니메이션으로 동적 웹 페이지 만들기(Java Script)

Blackeichi·2022년 12월 14일
0

스크롤을 내리다가 해당 target에 도착하면 애니메이션이 발생하는 웹페이지를 구현해보자.

자바스크립트를 이용하여 스크롤 애니메이션을 만들 때 사용할 수 있는 것이 Intersection Observer API 이다.

#intersection observer 생성하기

intersection observer를 생성하기 위해서는 생성자 호출 시 콜백 함수를 제공해야 합니다. 이 콜백 함수는 threshold가 한 방향 혹은 다른 방향으로 교차할 때 실행됩니다.

let options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: 1.0
}
let observer = new IntersectionObserver(callback, options);

여기서 option이 무엇인지 알아보자.

공식 문서에 나와있는 내용이다.

Intersection observer 설정
IntersectionObserver() 생성자에 전달되는 options 객체는 observer 콜백이 호출되는 상황을 조작할 수 있습니다. 이는 아래와 같은 필드를 가집니다:

root
대상 객체의 가시성을 확인할 때 사용되는 뷰포트 요소입니다. 이는 대상 객체의 조상 요소여야 합니다. 기본값은 브라우저 뷰포트이며, root 값이 null 이거나 지정되지 않을 때 기본값으로 설정됩니다.

rootMargin
root 가 가진 여백입니다. 이 속성의 값은 CSS의 margin 속성과 유사합니다. e.g. "10px 20px 30px 40px" (top, right, bottom, left). 이 값은 퍼센티지가 될 수 있습니다. 이것은 root 요소의 각 측면의 bounding box를 수축시키거나 증가시키며, 교차성을 계산하기 전에 적용됩니다. 기본값은 0입니다.

threshold
observer의 콜백이 실행될 대상 요소의 가시성 퍼센티지를 나타내는 단일 숫자 혹은 숫자 배열입니다. 만일 50%만큼 요소가 보여졌을 때를 탐지하고 싶다면, 값을 0.5로 설정하면 됩니다. 혹은 25% 단위로 요소의 가시성이 변경될 때마다 콜백이 실행되게 하고 싶다면 [0, 0.25, 0.5, 0.75, 1] 과 같은 배열을 설정하세요. 기본값은 0이며(이는 요소가 1픽셀이라도 보이자 마자 콜백이 실행됨을 의미합니다). 1.0은 요소의 모든 픽셀이 화면에 노출되기 전에는 콜백을 실행시키지 않음을 의미합니다.

간단한 사용법은 다음과 같다.

여기에 옵션 추가 및 원하는 내용으로 수정.

let observer = new IntersectionObserver((e)=>{
	e.forEach((box))=>{
    	if(box.isIntersecting){
        	box.target.style.opacity = 1
        }
    	else{
        	box.target.style.opacity = 0
        }
    }
})
let target = document.querySelector('div');
observer.observe(target[0]);
observer.observe(target[1]);
observer.observe(target[2]);

물론 이렇게 자바스크립트로만 작성하면 너무 복잡하므로 라이브러리를 이용하자.

아래는 framer-motion을 이용한 스크롤 이벤트이다.

import { motion, Variants } from "framer-motion";

const cardVariants: Variants = {
  offscreen: {
    y: 300,
  },
  onscreen: {
    y: 50,
    rotate: -10,
    transition: {
      type: "spring",
      bounce: 0.4,
      duration: 0.8,
    },
  },
};

export const testApp = () =>{
	return (
	  <motion.div
        className="card-container h-screen w-full bg-black"
        initial="offscreen"
        whileInView="onscreen"
        viewport={{ once: false, amount: 0.5 }}
        //amount = 이 div가 얼마나 보였을 때 작동할지. 0.5 = 50%
        //once는 한 번만 실행할지 아닐지 설정
        //부모 div에서 initial(시작), whileInView(보였을때), viewport 설정하고
      >
        <motion.div
          className="card h-52 w-52 bg-white"
          variants={cardVariants}
        >
       //애니메이션을 구현할 자식요소에서 variants 설정
        </motion.div>
      </motion.div>    
    )
}

div가 화면의 50%가 넘는 순간 아래 사진처럼 애니메이션 작동!

profile
프론트엔드 주니어 개발자 한정우입니다. 😁

0개의 댓글