ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스크롤 트리거 - 플러그인 | GSAP
    Interactive/GSAP 2021. 4. 5. 18:06
    반응형

     

    ScrollTrigger는 최소한의 코드로 놀라운 스크롤 기반 애니메이션을 만듭니다 . 또는 애니메이션과 무관하더라도 스크롤과 관련된 모든 것을 트리거합니다.

     

    가장 일반적인 ScrollTrigger 실수에 대해서도 학습하여 게임에서 앞서 나가세요.

     

     

    주요 기능

    • 특정 요소에 애니메이션을 연결하여 해당 요소가 뷰포트에 있을 때만 재생되도롭 합니다. 이렇게 하면 성능이 향상되고 아름다운 애니메이션을 실제로 볼 수 있습니다.
    • ScrollTrigger는 정의된 영역에 들어가거나 나갈 때 애니메이션에 대한 작업(재생, 일시 중지, 다시 시작, 되감기, 완료, 재설정)을 수행하거나 스크러버(scrub: true)처럼 작동하도록 스크롤바에 직접 연결할 수 있습니다.
    • 애니메이션과 스크롤바 사이의 연결을 부드럽게하여 "추적"하는 데 일정 시간이 걸리도록합니다. scrub: 1은 따라 잡는 데 1 초가 걸립니다.
    • 속도에 따라 애니메이션의 특정 지점을 스냅합니다. 사실, 스크롤링의 getVelocity()는 언제든지 가능합니다. 타임라인에서 가장 가까운 레이블 또는 어레이의 진행률 값에 스냅하거나 사용자 지정 함수 기반 로직을 실행하여 스냅합니다.
    • 스크롤 트리거를 GSAP 애니메이션에(타임라인 포함) 직접 포함하거나 독립 실행형 인스턴스를 만들고 풍부한 콜백 시스템을 활용하여 원하는 작업을 수행 할 수 있습니다.
    • 고급 고정 기능은 특정 스크롤 위치 사이에서 요소를 잠글 수 있습니다. 그에 따라 다른 요소를 아래로 밀어 내기 위해 패딩이 자동으로 추가되므로 요소가 고정 해제되면 따라 잡습니다 (pinSpacing : false로 비활성화). 동일한 요소를 다른 지점에 여러 번 고정 할 수도 있습니다.
    • 스크롤 위치를 정의하는 놀라운 유연성 - "이 요소의 중심이 뷰포트의 중앙에 닿으면 시작하고 다른 요소의 하단이 뷰포트의 하단에 닿으면 종료"와 같이 키워드 (top, center, bottom, left), 백분율, 픽셀 또는 "+ = 300px"와 같은 상대 값을 사용합니다. 구문에 익숙해지면 매우 직관적입니다.
    • 수직 또는 수평 스크롤을 수용합니다.
    • onEnter, onLeave, onEnterBack, onLeaveBack, onToggle, onUpdate, onScrubComplete 및 onRefresh를 포함한 풍부한 콜백 시스템.
    • 창 크기가 조정되면 자동으로 위치를 다시 계산합니다.
    • 개발 중에 시각적 마커를 활성화하여 시작 / 종료 / 트리거 지점의 정확한 위치를 확인합니다. markers: {startColor : "green", endColor : "red", fontSize : "12px"}와 같은 사용자 지정 옵션이 풍부합니다.
    • CSS 클래스를 전환합니다. 예를 들어 toggleClass : "active"는 ScrollTrigger가 활성화 된 동안 트리거 요소에 "active"클래스를 추가합니다. 다른 요소에도 영향을 미칠 수 있습니다.
    • 반응형 - matchMedia() 메서드를 사용하여 표준 미디어 쿼리를 사용하여 다양한 화면 크기에 대해 다른 설정을 만듭니다.
    • 커스텀 컨테이너 - 뷰포트를 사용할 필요가 없습니다. 대신 <div>와 같은 사용자 지정 스크롤러를 정의하십시오.
    • 최대 성능을 위해 고도로 최적화 됨 - 스크롤 이벤트가 디 바운스되고 업데이트가 GSAP와 동기화 되며, 화면 새로 고침, 크기 조정 재계산 등이 조절됩니다.
    • 스크롤 재킹이 없으므로 CSS 스크롤 스냅과 같은 기본 기술과 결합 할 수 있습니다. 스크롤 재킹을 원하는 경우 scrollerProxy() 메서드를 사용하여 타른 스크롤 라이브러리와 통합 할 수 있습니다.
    • 대략 6.5kb gzip입니다.

     

    간단한 예

    gsap.to(".box", {
      scrollTrigger: ".box", // ".box"가 뷰포트에 들어갈 때 애니메이션을 시작합니다(한 번).
      x: 500
    });

     

    고급 예

    let tl = gsap.timeline({
        // 전체 타임라인에 추가할 수 있습니다!
        scrollTrigger: {
          trigger: ".container",
          pin: true,   // 활성 상태에서 트리거 요소 고정
          start: "top top", // 트리거 상단이 뷰포트 상단에 닿을 때
          end: "+=500", // 시작 부분에서 500px 까지 스크롤 한 후 종료
          scrub: 1, // 부드러운 스크러빙, 스크롤바를 "잡는"데 1초가 걸립니다.
          snap: {
            snapTo: "labels", // 타임라인에서 가장 가까운 레이블에 스냅
            duration: {min: 0.2, max: 3}, // 스냅 애니메이션은 0.2초 이상 3초 이하이어야 합니다(속도에 따라 결정됨).
            delay: 0.2, // 스냅을 수행하기 전에 마지막 스크롤 이벤트에서 0.2 초를 기다립니다.
            ease: "power1.inOut" // 스냅 애니메이션의 ease (기본적으로 "power3")
          }
        }
      });
    
    // 애니메이션 및 레이블을 타임라인에 추가합니다.
    tl.addLabel("start")
      .from(".box p", {scale: 0.3, rotation:45, autoAlpha: 0})
      .addLabel("color")
      .from(".box", {backgroundColor: "#28a92b"})
      .addLabel("spin")
      .to(".box", {rotation: 360})
      .addLabel("end");

     

    독립형 / 사용자 지정 예

    ScrollTrigger를 애니메이션에 직접 넣을 필요는 없습니다(가장 일반적인 사용 사례일 수도 있음). 아무거나 콜백을 이용하세요.

    ScrollTrigger.create({
      trigger: "#id",
      start: "top top",
      endTrigger: "#otherID",
      end: "bottom 50%+=100px",
      onToggle: self => console.log("toggled, isActive:", self.isActive),
      onUpdate: self => {
        console.log("progress:", self.progress.toFixed(3), "direction:", self.direction, "velocity", self.getVelocity());
      }
    });

     

    사용 및 특수 속성

    scrollTrigger는 트리거(아래 설명)의 약자로 사용하거나 다음 속성 중 하나를 사용하여 구성 객체로 사용할 수 있습니다.

    GSAP 공식 문서 참조

     

    ScrollTrigger는 어떻게 작동합니까? IntersectionObserver와 똑같습니까?

    Scroll Trigger(스크롤 트리거)가 모든 요소를 지속적으로 감시하고 각 체크 표시의 뷰포트에서 해당 위치를 확인하는 것은 아닙니다. 우리는 성능에 집착하고 있고, 그것은 비용이 너무 많이 들 것입니다. 대신, Scroll Trigger(스크롤 트리거)는 문서 흐름에서 시작점/끝점의 위치를 파악하기 위해 사전 처리를 수행합니다. 즉, "스크롤바가 ___와 ___ 사이에 있을 때 이 스크롤 트리거가 활성화됩니다." 그런 다음, "스크롤" 이벤트를 디바운스하고 GSAP와 완벽하게 동기화된 다음 requestAnimationFrame에서만 업데이트를 수행합니다. 스크롤 위치만 봅니다. 기간. 즉, 속도가 빠릅니다.

     

    ScrollTrigger는 자동으로 뷰포트/스크롤러 "크기 조정" 이벤트를 수신하고 그에 따라 모든 시작/종료 위치를 다시 계산합니다 (onRefresh). 실제로 크기 조정/새로 고침은 CPU 집약적이므로 크기 조정 이벤트에 200ms의 간격이 있을 때까지 기다린 후 작업을 시작합니다. 우리는 성능을 극대화 할 수있는 모든 기회를 찾았습니다.

     

    IntersectionObserver 는 다음과 같은 면에서 다른 최신 브라우저의 기본 기능입니다.

    • 스크롤에 관계없이 요소가 들어가거나 나갈 때 감지하기 위해 지속적으로 요소를 "감시"합니다.
    • 그에 따라 애니메이션을 스크러빙하는 것과 같이 두 지점 사이의 요소 위치를 추적하는 데는 도움이되지 않습니다.
    • 예를 들어, 여러 요소를 보고 단일 콜백이 트리거되어 입력한 요소에서만 시차 애니메이션을 실행할 수 있습니다.

     

    ScrollTrigger는 필요한 기능과 호환성이 없기 때문에 내부적으로 IntersectionObserver를 사용하지 않습니다. IntersectionObserver와 ScrollTrigger를 함께 사용할 수 있습니다.

     

     

    내부에서 고정은 어떻게 작동합니까?

    • 고정된 요소는 일치하는 고정 너비 / 높이로 <div>에 즉시 래핑됩니다. "pin-spacer" 클래스가 해당 래퍼에 추가됩니다. DOM 내의 고정 요소가 "position: fixed"으로 전환되었을 때 붕괴되지 않도록 고정 요소가 DOM 내의 공간을 지탱하는 프록시 요소처럼 생각하세요.
    • 기본적으로 패딩은 pin-spacer의 하단(또는 오른쪽의 경우 horizontal: true)에 추가되어 [대부분의 경우] 사물이 더 아래/오른쪽으로 밀리게 됩니다. 고정된 요소의 고정이 풀리면 아래/오른쪽 컨텐츠가 따라잡힙니다. 예를 들어, 고정된 요소가 300px 동안 고정되어 있다면 300px의 패딩이 추가됩니다.
    • ScrollTrigger가 활성화되면(스크롤 위치가 시작과 끝 사이에 있을 때) 고정된 요소를 "position: fixed"로 설정하고 고정된 top/left/width/height 값으로 배치합니다. 스크롤러가 해당 뷰포트가 아닌 경우 "position: fixed"를 사용하지 않는 이유는 sub-scrolling이 깨지기 때문에, 순수 transform을 사용합니다. pinReparent가 true로 설정되면 (가능한 경우 피하는 것이 좋습니다), 고정 요소는 <body>로 재배치되고 스타일은 모양이 유지되도록 인라인으로 이동됩니다.
    • ScrollTrigger가 비활성화되면 고정된 요소가 원래 position 값으로 돌아가고 올바르게 배치하기 위해 transform이 적용됩니다.
    • 창/스크롤러의 크기가 조정되면 모든 ScrollTrigger가 시작/종료 위치를 다시 계산합니다(onRefresh). 이 프로세스의 일부로, pin-spacer가 DOM에서 제거되고 고정된 요소가 원래 CSS로 정확하게 측정되도록 다시 교체됩니다. 그런 다음 pin-spacer가 래퍼로 다시 교체됩니다.

     

    transform만 사용하여 "position: fixed"를 회피하면 어떨까요? 많은 브라우저가 이 기술을 사용하여 일관되게 렌더링 하지 않습니다. 최근 브라우저에서는 스크롤 repaints가 다른 스레드에서 처리되기 때문에 시각적 결함이 있습니다. 놀랍게도, "position: fixed"는 전반적으로 성능이 뛰어난 것처럼 보였습니다. 스크롤을 위해서는 성능이 매우 중요합니다.

     

     

    duration은 scrub : true에서 어떻게 작동합니까?

    ScrollTrigger의 "scrub: true"가 있고 해당 ScrollTrigger에 타임라인 또는 트윈 애니메이션이 연결되어있는 경우, 해당 애니메이션 내 트윈의 duration은 트윈이 재생되는 총 거리에 대한 비율입니다. 애니메이션 사이의 거리 비율은 애니메이션의 총 지속 시간과 관련이 있습니다. 다음의 예를 사용하면, 가장 알기 쉬워집니다.

     

    타임라인이 세 개 있다고 가정해 보겠습니다. 1초 간격, 3초 간격, 그리고 1초 간격입니다. 그리고 여기에 적용된 Scroll Trigger는 전체 뷰포트 높이의 거리에 대해 애니메이션됩니다. (트리거는 start: "center bottom"과 end: "center top" 값을 사용합니다).

     

    scrub: true (또는 숫자)가 적용된 경우 첫 번째 트윈은 트리거 요소의 중심이 뷰 포트의 100% 지점(위부터, 뷰포트 하단)과 80% 지점(뷰포트의 상단)에서, 두 번째 트윈은 요소의 중심이 80% 지점과 20% 지점 사이에 있을 때 실행됩니다. 세 번째 트윈은 요소의 중심이 20% 지점과 0% 지점 사이에 있을 때 실행됩니다. 타임 라인의 총 지속 시간이 5초이기 때문입니다. 따라서 ⅕은 20%이고 ⅗는 60%입니다.

    const tl = gsap.timeline({
      scrollTrigger: {
        trigger: ".trigger",
        start: "center bottom",
        end: "center top",
        scrub: true,
        markers: true
      }
    });
    tl.to(".box", {yPercent: 350, duration: 1})
    tl.to(".box", {rotation: 360, duration: 3})
    tl.to(".box", {xPercent: 350, duration: 1})

     

    예를 들어, 모든 트윈의 duration을 동일한 숫자로 변경하면 100% -> 66%, 66% -> 33%, 33% -> 0%로 모두 백분율이 동일합니다. 이는 총 지속시간이 3이므로 β는 33%이기 때문입니다.



    즉, duration 값은 타임라인의 총 시간과 비교해서 각 트윈 duration의 비율만큼 중요하지 않습니다.



    애니메이션을 완료하기 위해 스크롤 거리를 길게 하는 경우 시작에서 종료까지의 거리에 영향을 미칩니다. 예를 들어 end: "+=4000"으로 설정하여 완료하는 데 많은 양의 스크롤이 필요하도록 할 수 있습니다.

     

     

    Demo

    각각 비디오 미리보기가 있는 일반적인 효과에 대한 ScrollTrigger 데모 목록을 만들었습니다. 키워드를 사용하여 관련 데모를 검색 할 수도 있습니다.

     

    ScrollTrigger 데모 이해

     

    콘텐츠 탐색

     

    시차 효과

     

    기본 스크롤 기술과 페어링

     

    기타 효과

     

    더 많은 것을 원하십니까? 사용자가 만든 ScrollTrigger 펜 컬렉션 또는 CodePen에서 ScrollTrigger 펜 모음을 확인하십시오.

     

     

    반응형

    댓글

Luster Sun