IntersectionObserver를 사용하여 Javascript에서 애니메이션 스크롤

당신의 서류 가방 사이트에서 애니메이션을 사용하는 것은 사용자의 주의를 끌고 그들이 당신의 사이트에서 더 오래 머무르게 하는 좋은 방법일 것이다.
이 문서에서 사이트에 특수한 유형의 자바스크립트 스크롤 애니메이션을 추가하는 방법을 보여 드리겠습니다. 아래로/위로 스크롤하면 이 애니메이션이 활성화됩니다.이것은 '교차점 관찰자' 라는 기능을 사용하여 인코딩할 것이다.다음은 끝 애니메이션의 빠른 미리보기입니다.

Youtube에는 다음과 같은 동영상이 있습니다.

첫 번째 단계] 우선 기본적인 카드 사용자 인터페이스를 위해 HTML 태그와 스타일을 디자인합시다
<!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>Document</title>
    <link rel='stylesheet' type='text/css' href='./style.css'>
 </head>
 <body>
    <div class="wrapper">
        <div class="card">
            <div class="image"></div>
            <h2>Profile picture</h2>
            <p>Some text goes here. Some text goes here.Some text goes here.Some text goes here....</p>
        </div>
    </div>
  </body>
<html>
그리고 스타일.css는 다음과 같이 보입니다.
.wrapper {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: space-around;
    background-color: #5dafb8;
    color:white;
    font-family: Verdana, Geneva, Tahoma, sans-serif;
}

.card {
    height: 50vh;
    border-radius: 13px;
    box-shadow: 20px 40px 33px rgba(0,0,0,0.3);
    padding: 2rem;
    width: 35vh;
    background-color:  #6cc2ce;

}

/* Style a div with gradient as Background image */
.image {
    width: 35vh;
    height: 20vh;
    background-image: linear-gradient(70deg, RoyalBlue   , DarkTurquoise );
    background-size: cover;
    background-position: center center;
    box-shadow:  10px 15px 15px 6px #3891b4;
    border-radius: 15px;

}
이 예에서는 배경 이미지를 그래디언트로 설정합니다.background-image: linear-gradient(70deg, RoyalBlue , DarkTurquoise );여기에서 프로젝트의 실제 이미지를 설정할 수 있습니다.이것이 바로 그의 모습이다.


2단계] 이제 키프레임 애니메이션이 있는 기본 애니메이션을 CSS에 추가합니다.
우선 키 프레임 애니메이션이 있는 기본 css 애니메이션을 추가합니다.제목 (h2 태그) 과 내용 텍스트 (p 태그) 를 시작합니다.
.card h2 {
        /* Animate Heading, fades in from left to right */
    animation: animTitle 2s infinite;
} 

.card p {
        /* Animate Paragraph, fades in from right to left */
    animation: animContent 2s infinite;
}


@keyframes animTitle {
    from {
            /* Add starting values for animation */
            transform: translateX(-50px);
            opacity: 0;
    } 
    to  {
            /* Add Ending values for animation */
            transform: translateX(0);
            opacity: 1;
   } 
 }

 @keyframes animContent {
    from {
            /* Add starting values for animation */
            transform: translateX(50px);
            opacity: 0;
    } 
    to  {
            /* Add Ending values for animation */
            transform: translateX(0);
            opacity: 1;
   } 
 }
위에서 볼 수 있듯이 두 가지 키프레임 애니메이션 기능이 있습니다.@keyframes animTitle {...} and @keyframes animContent { ...}이것들은 css 선택기 규칙에서 호출됩니다.card h2 {animation: animContent 2s infinite;} and .card p{animation: animContent 2s infinite;}보시다시피 그들은 2초 동안 운행한 후에 무한 순환을 할 것이다.이것들은 원소의 수평 x 값의 간단한 변환/평이입니다.
우리는 또한 그림에 특수한 신축성 스트레칭 애니메이션을 추가할 것이다.CSS 규칙 및 애니메이션 키프레임 함수는 다음과 같습니다.
.card .image {
      /* Animate image */
    animation: animImage 2s infinite;
}

@keyframes animImage {
    0% {
      -webkit-transform: scale3d(1, 1, 1);
              transform: scale3d(1, 1, 1);
    }
    30% {
      -webkit-transform: scale3d(1.25, 0.75, 1);
              transform: scale3d(1.25, 0.75, 1);
    }
    40% {
      -webkit-transform: scale3d(0.75, 1.25, 1);
              transform: scale3d(0.75, 1.25, 1);
    }
    50% {
      -webkit-transform: scale3d(1.15, 0.85, 1);
              transform: scale3d(1.15, 0.85, 1);
    }
    65% {
      -webkit-transform: scale3d(0.95, 1.05, 1);
              transform: scale3d(0.95, 1.05, 1);
    }
    75% {
      -webkit-transform: scale3d(1.05, 0.95, 1);
              transform: scale3d(1.05, 0.95, 1);
    }
    100% {
      -webkit-transform: scale3d(1, 1, 1);
              transform: scale3d(1, 1, 1);
    }
  }

나는 online animation generator called Animista를 사용하여 이 애니메이션을 만들었다.너도 거기에 가서 다른 애니메이션을 시도해 볼 수 있다.이 사이트는 애니메이션을 설정할 용기에 키 프레임 코드를 추가할 수 있습니다.내가 위에서 한 것처럼.

지금까지 저희가 뭐가 있었죠?
지금까지 우리의 모든 애니메이션은 CSS가 제어했기 때문에 두루마리에 애니메이션을 만들려면 자바스크립트를 사용해야 한다.css 규칙과 HTML 요소를 다시 구성하거나 변경해야 합니다.이것이 바로 우리가 다음에 해야 할 일이다.

3단계 intersectionObserver를 추가하기 전에 HTML 태그 변경
Javascript를 통해 애니메이션을 활성화하는 관건적인 문제 중 하나는 애니메이션 키 프레임 함수 이름과 적용할 규칙에 접근하는 것입니다.본 프레젠테이션에서는 다음과 같은 css 규칙을 통해 이러한 이점을 실현할 수 있습니다.


.card h2 {
        /* Amimate Heading, fades in from left to right */
    animation: animTitle 2s infinite;
} 

.card p {
        /* Animate Paragraph, fades in from right to left */
    animation: animContent 2s infinite;
}

.card .image {
      /* Animate image */
    animation: animImage 2s infinite;
}

자바스크립트에서 이 점을 동적 응용하기 위해서, 우리는 이러한 css 규칙을 포기하고 htmls 데이터 속성을 사용하여 위에 표시된 애니메이션 값을 저장해야 한다.우리는 애니메이션을 제작할 세 가지 요소에'animate'라는 클래스를 추가할 것이다.따라서 카드의 HTML 태그는 다음과 같습니다.
<div class="wrapper">
        <div class="card">
            <div class="image animate" data-animate="animImage 2s"></div>
            <h2 class="animate" data-animate="animTitle 2s ">Profile picture</h2>
            <p class="animate" data-animate="animContent 2s ">Some text goes here.Some text goes here....</p>

        </div>
  </div>

여기서 가져온 객체는 데이터 속성입니다. 예를 들어, 이미지 컨테이너 데이터 속성은 다음과 같습니다.data-animate="animImage 2s", 여기에서 animate라는 데이터 항목을 만들고, 이 값을 css 스타일시트에 정의된 애니메이션 설정으로 설정합니다.If this is a bit strange, you can read more about using data attributes here
애니메이션을 활성화하기 위해 더 많은 내용을 추가해야 하기 때문에 나는 세 개의 카드 포장을 복사할 것이다.
<div class="wrapper">
        <div class="card">
            <div class="image animate" data-animate="animImage 2s"></div>
            <h2 class="animate" data-animate="animTitle 2s ">Profile picture</h2>
            <p class="animate" data-animate="animContent 2s ">Some text goes here.Some text goes here....</p>

        </div>
  </div>
 <div class="wrapper">
        <div class="card">
            <div class="image animate" data-animate="animImage 2s "></div>
            <h2 class="animate" data-animate="animTitle 2s ">Profile picture</h2>
            <p class="animate" data-animate="animContent 2s ">Some text goes here....Some text goes here....Some text goes here....Some text goes here....</p>

        </div>
  </div>
  <div class="wrapper">
        <div class="card">
            <div class="image animate" data-animate="animImage 2s "></div>
            <h2 class="animate" data-animate="animTitle 2s ">Profile picture</h2>
            <p class="animate" data-animate="animContent 2s ">Some text goes here....Some text goes here....Some text goes here....Some text goes here....</p>

        </div>
  </div>
  <div class="wrapper">
        <div class="card">
            <div class="image animate" data-animate="animImage 2s "></div>
            <h2 class="animate" data-animate="animTitle 2s ">Profile picture</h2>
            <p class="animate" data-animate="animContent 2s ">Some text goes here....Some text goes here....Some text goes here....Some text goes here....</p>

        </div>
    </div>


4] 스크롤 위치를 탐지하기 위해 Javascript의 교차점 관찰 기능을 추가합니다.
교차점 관찰자는 기본적으로 네가 알려준 원소를 관찰한다.그것은 목표 원소와 조상 원소가 교차하는 변화를 관찰할 것이다.우리의 조상 요소는 브라우저 뷰포트가 될 것입니다. 우리가 관찰한 교차 목표 요소는 카드의 세 가지 요소입니다. 즉.그림, p 탭, h2 탭입니다.
You can read more about Intersection Observer API here . API 문서에는 루트 요소를 정의하는 예가 있습니다. 예를 들면 브라우저 뷰포트로 기본값으로 설정하기를 원하기 때문에 생략합니다. 루트 요소를 정의하지 않으면 선조를 루트로 가정합니다.따라서 우리가 사용하는 기본 코드 구조는 다음과 같다.
    <script>
        const callback = (entries) => {
                   //4] Callback code goes here
         }

        //1]Create a new intersectionObserver object, 
        //which will accept a callback function as 
        //a parameter.

        let observer = new IntersectionObserver(callback);


        //2]Select all elements that have ".animate" 
        //class.In our case we have three 
        //elements (.image,<p> and h<2>).

        const animationItems = document.querySelectorAll('.animate');


          //3]Loop through selected elements and add to the
          //observer watch list.      

          animationItems.forEach(item => {
            observer.observe(item)         
        })


    </script>
이 코드를 태그에 추가합니다. 바디 태그의 맨 끝에 있습니다.간소화하기 위해서 너는 네 가지 절차가 있다
1] IntersectionObserver 객체 만들기
2] 관찰할 항목 조회 및 선택
3] 선택한 항목을 IntersectionObserver 객체의 모니터링 목록에 추가
4] 교차 이벤트가 발생할 때 일부 작업을 수행하는 콜백 함수를 제공합니다.우리의 예에서, 우리는 그것이 관건적인 프레임 애니메이션을 추가하기를 바란다.
위의 코드에서, 나는 리셋 함수의 코드를 작성하지 않았다.이게 저희의 다음 미션입니다.

단계 5] IntersectionObserver 콜백 함수
        const callback = (entries) => {

           // The entries variable will contain the list of
           // elements that you are observing. When ever 
           // intersection occurs, you need to do forEach loop 
           // to find which one intersected. 
           // For this we check a flag on the element called "isIntersecting"
            entries.forEach(
                (entry) => {
                    if (entry.isIntersecting) {
                        console.log("The element is intersecting >");
                        //If intersecting then attach keyframe animation.
                       //We do this by assigning the data attribute 
                       //we coded in the markup to the style.animation 
                       //of the element
                        entry.target.style.animation = 
                        entry.target.dataset.animate;
                    } else {
                        //We take of the animation if not in view
                        entry.target.style.animation="none";
                    }
                }
            );       
        }
inetrsection이 발생할 때마다 리셋을 호출합니다.리셋은 관찰자 목록에서 보이는 모든 요소를 방문합니다.다이얼 백 중에 우리는 어느 교차점을 순환해서 찾아야 한다.우리는 isIntersecting이라는 요소의 로고를 검사함으로써 이 점을 실현했다.If 문을 확인하면 이 점이 표시됩니다.if (entry.isIntersecting) {...}교차하는 경우 요소에 키프레임 애니메이션을 첨부합니다. 이것이 바로 다음 선의 역할입니다.entry.target.style.animation = entry.target.dataset.animate여기서 요소 스타일을 설정합니다.애니메이션은 3단계에서 설정한 '데이터 animate' 라는 데이터 속성을 가져옵니다.예를 들어, 이미지의 경우 요소 태그의 데이터 속성에서 문자열 부분을 제거합니다.
` <div class="image animate" data-animate="animImage 2s"></div>이 예에서는 animImage 2s입니다.
코드의 ELSE 섹션은 교차하지 않으므로 애니메이션을 삭제합니다.

  entry.target.style.animation="none"; 

따라서, 만약 네가 왔다갔다 스크롤한다면, 애니메이션은 다시 실행될 것이다.

최종 제품
이 강좌를 좋아하시고,codepen에서 최종 코드를 보실 수 있기를 바랍니다.

좋은 웹페이지 즐겨찾기