스크롤 기반 애니메이션으로 스크롤 시 요소에 애니메이션 적용

스크롤 타임라인과 뷰 타임라인을 사용하여 선언적 방식으로 스크롤 기반 애니메이션을 만드는 방법을 알아봅니다.

스크롤 기반 애니메이션

브라우저 지원

  • Chrome: 115 <ph type="x-smartling-placeholder">
  • Edge: 115 <ph type="x-smartling-placeholder">
  • Firefox: 깃발 뒤쪽에 있습니다.
  • Safari: 지원되지 않음 <ph type="x-smartling-placeholder">

소스

스크롤 기반 애니메이션은 웹의 일반적인 UX 패턴입니다. 스크롤 기반 애니메이션은 스크롤 컨테이너의 스크롤 위치와 연결됩니다. 즉, 위 또는 아래로 스크롤하면 연결된 애니메이션이 직접 반응으로 앞뒤로 스크러빙됩니다. 스크롤할 때 움직이는 시차 배경 이미지 또는 읽기 표시기와 같은 효과가 여기에 해당합니다.

<ph type="x-smartling-placeholder">
</ph>
스크롤으로 구동되는 문서 상단의 읽기 표시기

유사한 유형의 스크롤 기반 애니메이션은 스크롤 컨테이너 내 요소의 위치에 연결된 애니메이션입니다. 예를 들어 이 기능을 사용하면 요소가 시야에 들어올 때 페이드인될 수 있습니다.

<ph type="x-smartling-placeholder">
</ph>
이 페이지의 이미지는 시야에 들어올 때 페이드인됩니다.

이러한 종류의 효과를 얻는 기본적인 방법은 기본 스레드의 스크롤 이벤트에 응답하는 것이며, 이로 인해 다음과 같은 두 가지 주요 문제가 발생합니다.

  • 최신 브라우저는 별도의 프로세스에서 스크롤을 실행하므로 스크롤 이벤트를 비동기식으로 전달합니다.
  • 기본 스레드 애니메이션에 버벅거림이 발생할 수 있습니다.

이로 인해 스크롤과 동기화된 고성능 스크롤 기반 애니메이션을 만드는 것이 불가능하거나 매우 어렵습니다.

Chrome 버전 115부터 선언적 스크롤 기반 애니메이션을 사용 설정하는 데 사용할 수 있는 새로운 API 및 개념 모음인 스크롤 타임라인과 뷰 타임라인이 추가되었습니다.

이러한 새로운 개념은 기존 Web Animations API (WAAPI)CSS Animations API와 통합되어 기존 API의 이점을 상속할 수 있습니다. 여기에는 스크롤 기반 애니메이션이 기본 스레드 밖에서 실행되도록 하는 기능이 포함됩니다. 올바르게 읽어 보세요. 이제 몇 줄의 추가 코드만으로 기본 스레드를 벗어나 스크롤로 구동되는 매끄러운 애니메이션을 만들 수 있습니다. 마음에 들지 않는 점이 뭐지?!

웹 애니메이션 요약

CSS를 사용한 웹 애니메이션

CSS에서 애니메이션을 만들려면 @keyframes at 규칙을 사용하여 키프레임 세트를 정의합니다. animation-name 속성을 사용하여 요소에 연결하는 동시에 animation-duration를 설정하여 애니메이션 재생 시간을 결정합니다. animation-*의 긴 속성(animation-easing-function, animation-fill-mode 등)이 더 많이 있으며 모두 animation 약어로 결합할 수 있습니다.

예를 들어 다음은 X축에서 요소의 크기를 확대하는 동시에 배경 색상도 변경하는 애니메이션입니다.

@keyframes scale-up {
  from {
    background-color: red;
    transform: scaleX(0);
  }
  to {
    background-color: darkred;
    transform: scaleX(1);
  }
}

#progressbar {
  animation: 2.5s linear forwards scale-up;
}

JavaScript를 사용한 웹 애니메이션

JavaScript에서 Web Animations API를 사용하여 정확히 동일한 작업을 수행할 수 있습니다. 이렇게 하려면 새 AnimationKeyFrameEffect 인스턴스를 만들거나 훨씬 더 짧은 Element animate() 메서드를 사용하면 됩니다.

document.querySelector('#progressbar').animate(
  {
    backgroundColor: ['red', 'darkred'],
    transform: ['scaleX(0)', 'scaleX(1)'],
  },
  {
    duration: 2500,
    fill: 'forwards',
    easing: 'linear',
   }
);

위 자바스크립트 스니펫의 시각적 결과는 이전 CSS 버전과 동일합니다.

애니메이션 타임라인

기본적으로 요소에 연결된 애니메이션은 문서 타임라인에서 실행됩니다. 시작 시간은 페이지가 로드될 때 0에서 시작해서 시계 시간이 진행됨에 따라 순식간에 시작됩니다. 이것이 기본 애니메이션 타임라인이며 지금까지 액세스할 수 있었던 유일한 애니메이션 타임라인이었습니다.

스크롤 기반 애니메이션 사양은 사용할 수 있는 두 가지 새로운 유형의 타임라인을 정의합니다.

  • 스크롤 진행률 타임라인: 특정 축을 따라 스크롤 컨테이너의 스크롤 위치에 연결된 타임라인입니다.
  • 뷰 진행률 타임라인: 스크롤 컨테이너 내 특정 요소의 상대 위치에 연결된 타임라인

스크롤 진행률 타임라인

스크롤 진행률 타임라인은 특정 축을 따라 스크롤 컨테이너의 스크롤 위치(scrollport 또는 scroller라고도 함)에서 진행률에 연결된 애니메이션 타임라인입니다. 스크롤 범위의 위치를 진행률로 변환합니다.

시작 스크롤 위치는 0% 진행률로 나타내고 종료 스크롤 위치는 100% 진행률로 나타냅니다. 다음 시각화에서 스크롤러를 위에서 아래로 스크롤하면 진행률이 0% 에서 100% 까지 증가합니다.

<ph type="x-smartling-placeholder">
</ph>
스크롤 진행률 타임라인 시각화 스크롤러 하단으로 스크롤하면 진행률 값이 0% 에서 100%까지 증가합니다.

✨ 직접 사용해 보기 를 탭합니다.

스크롤 진행률 타임라인은 간단히 '스크롤 타임라인'으로 축약되는 경우가 많습니다.

뷰 진행률 타임라인

이 유형의 타임라인은 스크롤 컨테이너 내 특정 요소의 상대적인 진행률에 링크됩니다. 스크롤 진행률 타임라인과 마찬가지로 스크롤러의 스크롤 오프셋이 추적됩니다. 스크롤 진행률 타임라인과 달리 진행률을 결정하는 것은 해당 스크롤러 내에서 대상의 상대 위치입니다.

이는 요소가 스크롤러에 표시되는 정도를 추적할 수 있는 IntersectionObserver의 작동 방식과 다소 비슷합니다. 스크롤러에 요소가 보이지 않으면 교차하지 않습니다. 가장 작은 부분이라도 스크롤러 내부에 보이면 교차합니다.

뷰 진행률 타임라인은 대상이 스크롤러와 교차하기 시작하는 순간부터 시작되어 대상이 스크롤러와 교차하는 것을 멈출 때 끝납니다. 다음 시각화에서 진행률은 대상이 스크롤 컨테이너에 들어갈 때 0% 부터 시작하여 대상이 스크롤 컨테이너를 떠난 즉시 100% 에 도달하는 것을 볼 수 있습니다.

<ph type="x-smartling-placeholder">
</ph>
뷰 진행률 타임라인의 시각화. 대상 (녹색 상자)이 스크롤러를 넘어가면 진행률이 0% 에서 100% 까지 올라갑니다.

✨ 직접 사용해 보기 를 탭합니다.

뷰 진행률 타임라인은 간단히 '뷰 타임라인'으로 줄인 경우가 많습니다. 피사체의 크기에 따라 뷰 타임라인의 특정 부분을 타겟팅할 수 있지만 이에 대해서는 나중에 자세히 설명합니다.

스크롤 진행률 타임라인 실습하기

CSS에서 익명의 스크롤 진행률 타임라인 만들기

CSS에서 스크롤 타임라인을 만드는 가장 쉬운 방법은 scroll() 함수를 사용하는 것입니다. 이렇게 하면 새 animation-timeline 속성 값으로 설정할 수 있는 익명의 스크롤 타임라인이 생성됩니다.

예:

@keyframes animate-it { … }

.subject {
  animation: animate-it linear;
  animation-timeline: scroll(root block);
}

scroll() 함수는 <scroller><axis> 인수를 허용합니다.

<scroller> 인수에 허용되는 값은 다음과 같습니다.

  • nearest: 가장 가까운 상위 스크롤 컨테이너(기본값)를 사용합니다.
  • root: 문서 표시 영역을 스크롤 컨테이너로 사용합니다.
  • self: 요소 자체를 스크롤 컨테이너로 사용합니다.

<axis> 인수에 허용되는 값은 다음과 같습니다.

  • block: 스크롤 컨테이너의 블록 축을 따라 진행률 측정을 사용합니다(기본값).
  • inline: 스크롤 컨테이너의 인라인 축을 따라 진행률 측정을 사용합니다.
  • y: 스크롤 컨테이너의 Y축을 따라 진행률 측정을 사용합니다.
  • x: 스크롤 컨테이너의 x축을 따라 진행률 측정을 사용합니다.

예를 들어 애니메이션을 블록 축의 루트 스크롤러에 바인딩하려면 scroll()에 전달할 값은 rootblock입니다. 합하면 값은 scroll(root block)입니다.

데모: 읽기 진행률 표시기

이 데모에는 읽기 진행률 표시기가 표시 영역 상단에 고정되어 있습니다. 페이지를 아래로 스크롤하면 진행률 표시줄이 커지면서 문서의 끝에 도달하면 전체 표시 영역 너비를 차지하게 됩니다. 익명의 스크롤 진행률 타임라인은 애니메이션을 구동하는 데 사용됩니다.

<ph type="x-smartling-placeholder">
</ph>
데모: 읽기 진행률 표시기

✨ 직접 사용해 보기 를 탭합니다.

읽기 진행률 표시기는 페이지 상단에 고정되어 있습니다. 합성된 애니메이션을 활용하기 위해 width가 애니메이션되지만 요소는 transform를 사용하여 x축에서 축소됩니다.

<body>
  <div id="progress"></div>
  …
</body>
@keyframes grow-progress {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

#progress {
  position: fixed;
  left: 0; top: 0;
  width: 100%; height: 1em;
  background: red;

  transform-origin: 0 50%;
  animation: grow-progress auto linear;
  animation-timeline: scroll();
}

#progress 요소의 grow-progress 애니메이션 타임라인은 scroll()를 사용하여 만든 익명 타임라인으로 설정됩니다. scroll()에 인수가 제공되지 않으므로 기본값으로 대체됩니다.

추적할 기본 스크롤러는 nearest이며 기본 축은 block입니다. 이렇게 하면 루트 스크롤러가 #progress 요소의 가장 가까운 스크롤러이므로 블록 방향을 추적하는 동시에 루트 스크롤러를 효과적으로 타겟팅할 수 있습니다.

CSS에서 이름이 지정된 스크롤 진행률 타임라인 만들기

스크롤 진행률 타임라인을 정의하는 다른 방법은 이름이 지정된 스크롤 진행률 타임라인을 사용하는 것입니다. 좀 더 장황하지만 상위 스크롤러 또는 루트 스크롤러를 타겟팅하지 않거나 페이지에서 여러 타임라인을 사용하거나 자동 조회가 작동하지 않는 경우 유용할 수 있습니다. 이렇게 하면 이름을 지정하여 스크롤 진행률 타임라인을 식별할 수 있습니다.

요소에 대해 이름이 지정된 스크롤 진행률 타임라인을 만들려면 스크롤 컨테이너의 scroll-timeline-name CSS 속성을 원하는 식별자로 설정합니다. 값은 --(으)로 시작해야 합니다.

추적할 축을 조정하려면 scroll-timeline-axis 속성도 선언합니다. 허용되는 값은 scroll()<axis> 인수와 동일합니다.

마지막으로 애니메이션을 스크롤 진행률 타임라인에 링크하려면 애니메이션을 적용해야 하는 요소의 animation-timeline 속성을 scroll-timeline-name에 사용된 식별자와 동일한 값으로 설정합니다.

코드 예:

@keyframes animate-it { … }

.scroller {
  scroll-timeline-name: --my-scroller;
  scroll-timeline-axis: inline;
}

.scroller .subject {
  animation: animate-it linear;
  animation-timeline: --my-scroller;
}

원하는 경우 scroll-timeline 약식에서 scroll-timeline-namescroll-timeline-axis를 결합할 수 있습니다. 예를 들면 다음과 같습니다.

scroll-timeline: --my-scroller inline;

이 데모에는 각 이미지 캐러셀 위에 걸음 수 표시기가 있습니다. 캐러셀에 세 개의 이미지가 포함된 경우 표시기의 너비는 33% 로 시작해서 세 개의 이미지 중 하나를 보고 있음을 나타냅니다. 마지막 이미지가 시야에 들어오면(스크롤러가 끝까지 스크롤한 후에 결정) 표시기가 스크롤러의 전체 너비를 차지합니다. 이름이 지정된 스크롤 진행률 타임라인은 애니메이션을 구동하는 데 사용됩니다.

<ph type="x-smartling-placeholder">
</ph>
데모: 가로형 캐러셀 단계 표시기

✨ 직접 사용해 보기 를 탭합니다.

갤러리의 기본 마크업은 다음과 같습니다.

<div class="gallery" style="--num-images: 2;">
  <div class="gallery__scrollcontainer">
    <div class="gallery__progress"></div>
    <div class="gallery__entry">…</div>
    <div class="gallery__entry">…</div>
  </div>
</div>

.gallery__progress 요소는 .gallery 래퍼 요소 내에 절대적으로 배치됩니다. 초기 크기는 --num-images 커스텀 속성에 따라 결정됩니다.

.gallery {
  position: relative;
}


.gallery__progress {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 1em;
  transform: scaleX(calc(1 / var(--num-images)));
}

.gallery__scrollcontainer는 포함된 .gallery__entry 요소를 가로로 배치하며 스크롤되는 요소입니다. 스크롤 위치를 추적하면 .gallery__progress에 애니메이션이 적용됩니다. 이 작업은 이름이 지정된 스크롤 진행률 타임라인 --gallery__scrollcontainer를 참조하여 실행됩니다.

@keyframes grow-progress {
  to { transform: scaleX(1); }
}

.gallery__scrollcontainer {
  overflow-x: scroll;
  scroll-timeline: --gallery__scrollcontainer inline;
}
.gallery__progress {
  animation: auto grow-progress linear forwards;
  animation-timeline: --gallery__scrollcontainer;
}

JavaScript로 스크롤 진행률 타임라인 만들기

JavaScript로 스크롤 타임라인을 만들려면 ScrollTimeline 클래스의 새 인스턴스를 만듭니다. 추적하려는 sourceaxis가 포함된 속성 가방을 전달합니다.

  • source: 스크롤러를 추적하려는 요소에 관한 참조입니다. document.documentElement를 사용하여 루트 스크롤러를 타겟팅합니다.
  • axis: 추적할 축을 결정합니다. CSS 변형과 마찬가지로 허용되는 값은 block, inline, x, y입니다.
const tl = new ScrollTimeline({
  source: document.documentElement,
});

웹 애니메이션에 연결하려면 timeline 속성으로 전달하고 duration가 있으면 생략합니다.

$el.animate({
  opacity: [0, 1],
}, {
  timeline: tl,
});

데모: 읽기 진행률 표시기, 재검토

동일한 마크업을 사용하면서 JavaScript로 읽기 진행률 표시기를 다시 만들려면 다음 JavaScript 코드를 사용하세요.

const $progressbar = document.querySelector('#progress');

$progressbar.style.transformOrigin = '0% 50%';
$progressbar.animate(
  {
    transform: ['scaleX(0)', 'scaleX(1)'],
  },
  {
    fill: 'forwards',
    timeline: new ScrollTimeline({
      source: document.documentElement,
    }),
  }
);

시각적 결과는 CSS 버전과 동일합니다. 생성된 timeline는 루트 스크롤러를 추적하고 페이지를 스크롤할 때 x축에서 #progress를 0% 에서 100% 까지 확장합니다.

✨ 직접 사용해 보기 를 탭합니다.

뷰 진행률 타임라인으로 연습하기

CSS에서 익명 뷰 진행률 타임라인 만들기

뷰 진행률 타임라인을 만들려면 view() 함수를 사용합니다. 허용되는 인수는 <axis><view-timeline-inset>입니다.

  • <axis>는 스크롤 진행률 타임라인과 동일하며 추적할 축을 정의합니다. 기본값은 block입니다.
  • <view-timeline-inset>를 사용하면 요소가 시야에 있거나 없는 것으로 간주될 때 경계를 조정하도록 오프셋(양수 또는 음수)을 지정할 수 있습니다. 값은 백분율 또는 auto여야 하며 auto은 기본값입니다.

예를 들어 블록 축의 스크롤러와 교차하는 요소에 애니메이션을 바인딩하려면 view(block)를 사용합니다. scroll()와 마찬가지로 이 값을 animation-timeline 속성의 값으로 설정하고 animation-durationauto로 설정하는 것을 잊지 마세요.

다음 코드를 사용하면 스크롤하는 동안 표시 영역을 교차할 때 모든 img가 페이드 인됩니다.

@keyframes reveal {
  from { opacity: 0; }
  to { opacity: 1; }
}

img {
  animation: reveal linear;
  animation-timeline: view();
}

Intermezzo: 타임라인 범위 보기

기본적으로 뷰 타임라인에 연결된 애니메이션은 전체 타임라인 범위에 연결됩니다. 이는 대상이 스크롤 포트에 들어가는 순간부터 시작되어 대상이 스크롤 포트를 완전히 벗어났을 때 끝납니다.

연결해야 하는 범위를 지정하여 뷰 타임라인의 특정 부분에 연결할 수도 있습니다. 예를 들어 대상이 스크롤러에 들어갈 때만 가능합니다. 다음 시각화에서 진행률은 대상이 스크롤 컨테이너에 들어갈 때 0%부터 시작하지만 완전히 교차하는 순간부터 이미 100%에 도달합니다.

<ph type="x-smartling-placeholder">
</ph>
주제의 입력 범위를 추적하도록 설정된 뷰 타임라인. 애니메이션은 대상이 스크롤 포트에 들어가는 동안에만 실행됩니다.

타겟팅할 수 있는 뷰 타임라인 범위는 다음과 같습니다.

  • cover: 뷰 진행률 타임라인의 전체 범위를 나타냅니다.
  • entry: 주 상자가 뷰 진행률 가시성 범위에 들어가는 범위를 나타냅니다.
  • exit: 주 상자가 뷰 진행률 가시성 범위를 벗어나는 범위를 나타냅니다.
  • entry-crossing: 주 상자가 끝 테두리 가장자리를 가로지르는 범위를 나타냅니다.
  • exit-crossing: 주 상자가 시작 테두리 가장자리를 가로지르는 범위를 나타냅니다.
  • contain: 주 상자가 스크롤 포트 내의 뷰 진행률 가시성 범위에 완전히 포함되거나 완전히 포함하는 범위를 나타냅니다. 대상이 스크롤러보다 길거나 짧은지에 따라 달라집니다.

범위를 정의하려면 범위-시작 및 범위-끝을 설정해야 합니다. 각각은 범위 이름(위 목록 참조)과 범위 이름 내 위치를 결정하는 범위 오프셋으로 구성됩니다. 범위 오프셋은 일반적으로 0%에서 100% 사이의 백분율이지만 20em와 같이 고정된 길이를 지정할 수도 있습니다.

예를 들어 대상이 진입하는 순간부터 애니메이션을 실행하려면 entry 0%을 범위 시작으로 선택합니다. 대상이 입력될 때까지 작업을 마치려면 범위 끝 값으로 entry 100%를 선택합니다.

CSS에서는 animation-range 속성을 사용하여 이를 설정합니다. 예:

animation-range: entry 0% entry 100%;

JavaScript에서는 rangeStartrangeEnd 속성을 사용합니다.

$el.animate(
  keyframes,
  {
    timeline: tl,
    rangeStart: 'entry 0%',
    rangeEnd: 'entry 100%',
  }
);

아래에 포함된 도구를 사용하여 각 범위 이름이 나타내는 항목과 백분율이 시작 및 종료 위치에 미치는 영향을 확인하세요. 범위 시작을 entry 0%로, 범위 끝을 cover 50%로 설정한 다음 스크롤바를 드래그하여 애니메이션 결과를 확인해 보세요.

<ph type="x-smartling-placeholder">
</ph>
뷰 타임라인 범위 비주얼라이저(https://goo.gle/view-timeline-range-tool에서 사용 가능)

녹화 파일 시청하기

타임라인 범위 보기 도구를 사용하는 동안 확인할 수 있듯이, 일부 범위는 두 개의 서로 다른 범위 이름 + 범위 오프셋 조합으로 타겟팅할 수 있습니다. 예를 들어 entry 0%, entry-crossing 0%cover 0%은(는) 모두 동일한 지역을 타겟팅합니다.

범위 시작 및 범위 끝이 동일한 범위 이름을 타겟팅하고 전체 범위를 포괄하는 경우(0% 에서 100%까지) 값을 단순히 범위 이름으로 줄일 수 있습니다. 예를 들어 animation-range: entry 0% entry 100%;를 훨씬 더 짧은 animation-range: entry로 다시 작성할 수 있습니다.

데모: 이미지 표시

이 데모는 스크롤 포트에 들어가면 이미지가 페이드 인됩니다. 이 작업은 익명 뷰 타임라인을 사용하여 수행됩니다. 각 이미지가 스크롤러의 절반을 차지할 때 전체 불투명도가 되도록 애니메이션 범위가 조정되었습니다.

<ph type="x-smartling-placeholder">
</ph>
데모: 이미지 표시

✨ 직접 사용해 보기 를 탭합니다.

확장 효과는 애니메이션으로 표시되는 클립 경로를 사용하여 구현할 수 있습니다. 이 효과에 사용되는 CSS는 다음과 같습니다.

@keyframes reveal {
  from { opacity: 0; clip-path: inset(0% 60% 0% 50%); }
  to { opacity: 1; clip-path: inset(0% 0% 0% 0%); }
}

.revealing-image {
  animation: auto linear reveal both;
  animation-timeline: view();
  animation-range: entry 25% cover 50%;
}

CSS에서 이름이 지정된 뷰 진행률 타임라인 만들기

스크롤 타임라인에 이름이 지정된 버전이 있는 방식과 유사하게 이름이 지정된 뷰 타임라인을 만들 수도 있습니다. scroll-timeline-* 속성 대신 view-timeline- 접두사를 포함하는 변형(view-timeline-nameview-timeline-axis)을 사용합니다.

동일한 유형의 값이 적용되며 이름이 지정된 타임라인 조회에도 동일한 규칙이 적용됩니다.

데모: 이미지 표시, 재검토

이전의 이미지 표시 데모를 다시 작업하면 수정된 코드는 다음과 같습니다.

.revealing-image {
  view-timeline-name: --revealing-image;
  view-timeline-axis: block;

  animation: auto linear reveal both;
  animation-timeline: --revealing-image;
  animation-range: entry 25% cover 50%;
}

view-timeline-name: revealing-image를 사용하면 가장 가까운 스크롤러 내에서 요소가 추적됩니다. 그러면 동일한 값이 animation-timeline 속성 값으로 사용됩니다. 시각적 출력은 이전과 정확히 동일합니다.

✨ 직접 사용해 보기 를 탭합니다.

JavaScript에서 뷰 진행률 타임라인 만들기

JavaScript로 뷰 타임라인을 만들려면 ViewTimeline 클래스의 새 인스턴스를 만듭니다. 추적하려는 subject, axis, inset가 포함된 속성 가방을 전달합니다.

  • subject: 자체 스크롤러 내에서 추적하려는 요소에 관한 참조입니다.
  • axis: 추적할 축입니다. CSS 변형과 마찬가지로 허용되는 값은 block, inline, x, y입니다.
  • inset: 상자가 뷰에 있는지 결정할 때 스크롤 포트의 인셋(양수) 또는 아웃셋(음수) 조정입니다.
const tl = new ViewTimeline({
  subject: document.getElementById('subject'),
});

웹 애니메이션에 연결하려면 timeline 속성으로 전달하고 duration가 있으면 생략합니다. 필요한 경우 rangeStartrangeEnd 속성을 사용하여 범위 정보를 전달합니다.

$el.animate({
  opacity: [0, 1],
}, {
  timeline: tl,
  rangeStart: 'entry 25%',
  rangeEnd: 'cover 50%',
});

✨ 직접 사용해 보기 를 탭합니다.

시도해 볼 만한 다른 작업

하나의 키프레임 세트를 사용하여 여러 뷰 타임라인 범위에 연결하기

목록 항목이 애니메이션으로 표시된 이 연락처 목록 데모를 살펴보겠습니다. 목록 항목이 하단에서 슬라이드 + 페이드 인되고 스크롤 포트에서 나가면 하단에서 스크롤 포트로 들어가면서 페이드 아웃됩니다.

<ph type="x-smartling-placeholder">
</ph>
데모: 연락처 목록

✨ 직접 사용해 보기 를 탭합니다.

이 데모에서는 각 요소가 스크롤 포트를 교차할 때 요소를 추적하는 뷰 타임라인 1개로 장식되지만 스크롤 기반 애니메이션 2개가 연결됩니다. animate-in 애니메이션은 타임라인의 entry 범위에 연결되고 animate-out 애니메이션은 타임라인의 exit 범위에 연결됩니다.

@keyframes animate-in {
  0% { opacity: 0; transform: translateY(100%); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes animate-out {
  0% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-100%); }
}

#list-view li {
  animation: animate-in linear forwards,
             animate-out linear forwards;
  animation-timeline: view();
  animation-range: entry, exit;
}

서로 다른 두 범위에 연결된 두 개의 서로 다른 애니메이션을 실행하는 대신 범위 정보가 이미 포함된 하나의 키프레임 세트를 만들 수도 있습니다.

@keyframes animate-in-and-out {
  entry 0%  {
    opacity: 0; transform: translateY(100%);
  }
  entry 100%  {
    opacity: 1; transform: translateY(0);
  }
  exit 0% {
    opacity: 1; transform: translateY(0);
  }
  exit 100% {
    opacity: 0; transform: translateY(-100%);
  }
}

#list-view li {
  animation: linear animate-in-and-out;
  animation-timeline: view();
}

키프레임에는 범위 정보가 포함되어 있으므로 animation-range를 지정할 필요가 없습니다. 결과는 이전과 정확히 일치합니다.

✨ 직접 사용해 보기 를 탭합니다.

상위가 아닌 스크롤 타임라인에 연결

이름이 지정된 스크롤 타임라인 및 이름이 지정된 뷰 타임라인의 조회 메커니즘은 스크롤 상위 항목으로만 제한됩니다. 그러나 애니메이션으로 표시해야 하는 요소는 추적해야 하는 스크롤러의 하위 요소가 아닌 경우가 매우 많습니다.

이렇게 하려면 timeline-scope 속성을 사용해야 합니다. 이 속성을 사용하여 실제로 타임라인을 만들지 않고 이 이름으로 타임라인을 선언할 수 있습니다. 이렇게 하면 해당 이름의 타임라인이 더 넓어집니다. 실제로는 하위 스크롤러의 타임라인을 여기에 연결할 수 있도록 공유된 상위 요소에서 timeline-scope 속성을 사용합니다.

예를 들면 다음과 같습니다.

.parent {
  timeline-scope: --tl;
}
.parent .scroller {
  scroll-timeline: --tl;
}
.parent .scroller ~ .subject {
  animation: animate linear;
  animation-timeline: --tl;
}

이 스니펫에서는 다음 사항이 적용됩니다.

  • .parent 요소는 이름이 --tl인 타임라인을 선언합니다. 모든 하위 요소는 이 속성을 찾아 animation-timeline 속성의 값으로 사용할 수 있습니다.
  • .scroller 요소는 실제로 이름이 --tl인 스크롤 타임라인을 정의합니다. 기본적으로 하위 요소에만 표시되지만 .parent에서 scroll-timeline-root로 설정되어 있으므로 하위 요소에 연결됩니다.
  • .subject 요소는 --tl 타임라인을 사용합니다. 상위 트리를 위로 이동하고 .parent에서 --tl를 찾습니다. .parent--tl.scroller--tl를 가리키면 .subject는 기본적으로 .scroller의 스크롤 진행률 타임라인을 추적합니다.

달리 말하면, timeline-root를 사용하여 타임라인을 상위 (호이스팅이라고도 함)로 이동하여 상위 요소의 모든 하위 요소에서 액세스할 수 있도록 할 수 있습니다.

timeline-scope 속성은 스크롤 타임라인과 뷰 타임라인 모두에 사용할 수 있습니다.

데모 및 리소스 더보기

스크롤 기반 애니메이션 스타일 미니 사이트에 관한 이 도움말에서 다루는 모든 데모 이 웹사이트에는 스크롤 기반 애니메이션으로 무엇을 할 수 있는지 강조하는 다양한 데모가 있습니다.

추가 데모 중 하나는 이 앨범 표지 목록입니다. 각 표지는 중앙의 스포트라이트를 비추면서 3D로 회전합니다.

<ph type="x-smartling-placeholder">
</ph>
데모: 표지 흐름

✨ 직접 사용해 보기 를 탭합니다.

또는 position: sticky를 활용하는 이 스태킹 카드 데모입니다. 카드가 쌓이면 이미 붙어 있는 카드가 작아져 깊이 있는 효과를 연출할 수 있습니다. 결국 전체 스택이 그룹으로 밀려 사라집니다.

<ph type="x-smartling-placeholder">
</ph>
데모: 카드 쌓기

✨ 직접 사용해 보기 를 탭합니다.

또한 scroll-driven-animations.style에는 이 게시물 앞부분에 포함된 뷰 타임라인 범위 진행률 시각화와 같은 도구 모음이 있습니다.

스크롤 기반 애니메이션은 Google I/O ’23의 웹 애니메이션의 새로운 기능에서도 다룹니다.