Web の仕様を眺めるシリーズ Scroll Timeline for Web Animations | Offers Tech Blog
Offers を運営している株式会社 overflow の あほむ でございます。
本記事は Chrome Platform Status からなんとなく Proposed なステータスのフィーチャーを取り上げて、そのプロポーザルを眺めてみるシリーズです。前回は Control UI Customization でした。
Scroll Timeline for Web Animations
今回は Scroll Timeline for Web Animations を眺めてみます。本当に眺めるだけで深入りしないので概要のみのライトな記事とご認識ください。W3C の Editor's Draft に倣うと Scroll-driven Animations です。
パララックス表現のネイティブサポート
もの凄く端的に言うと、スクロールに連動して何らかアニメーションするパララックス表現がネイティブサポートされるような仕様です。
従来 Web Animatinos は経過時間に依存したタイムラインで実行されるのに対して、Scroll Timeline は経過時間ではなく特定のコンテナにおけるスクロール位置と連動したタイムラインでアニメーションを実行できるようにします。
Scroll-driven Animations 内には View Progress Timeline (ViewTimeline
) という特定の要素が画面内に表示されている割合に応じたタイムラインについても言及があります。こちらも大体は同じような取り回しになると思われるので今回は ScrollTimeline
を中心に紹介します。
CSS Animation Worklet API の Scroll Timeline
ScrollTimeline is mostly implemented for Animation Worklet, but there are still spec issues to work out and implementation work to be done to integrate it into Web Animations
Chromium の当該チケット によれば、最近話題としては落ち着いた気もする[1] CSS Houdini 的な Animation Worklet API では先行して Scroll Timeline が組み込まれているようです。これを JavaScript と CSS 双方の Web Animations への統合が意図されています。
実験的機能の有効化とデモサイト
本稿執筆時点では少なくとも Chrome Canary (M112) で chrome://flags
から Experimental Web Platform features を Enabled にすることで下記のデモが Polyfill なしで動作することを確認しています。
本稿執筆時点で提案されている API
以下のサンプルコードは ScrollTimeline Examples と scroll-timeline - CSS: Cascading Style Sheets | MDN を元にした引用(一部改変)です。
JavaScript での例
Web Animations API をご存じない/思い出したい方は ミツエーリンクスさんのこちらの記事 を参照すると良さそうです。[2]
下記は Animation クラス等を直接取り扱う例です。ポイントは new Animation(keyframe, scrollTimeline)
で引数に ScrollTimeline
インスタンスを渡しているところでしょう。
const scroller = document.querySelector('div.scroll');
const parallax = document.querySelector('div.parallax');
const scrollRange = scroller.scrollHeight - scroller.clientHeight;
const parallaxRange = scrollRange * 0.2;
const keyframe = new KeyframeEffect(parallax, [{ 'transform': 'translateY(0)' }, { 'transform': 'translateY(' + -parallaxRange + 'px)' }], 1000);
const scrollTimeline = new ScrollTimeline({ source: scroller, orientation: 'block' });
const parallaxAnimation = new Animation(keyframe, scrollTimeline);
const parallaxAnimation.play();
現状は経過時間に従う DocumentTimeline
[3] (→ document.timeline
) しか渡せなかったところに ScrollTimeline
が仲間入りしそう、という形です。Element#animate()
で扱う場合は el.animate(keyframes, {timeline: new ScrollTimeline(...)})
で同様です。
CSS での例
こちらは MDN の記載からの引用です。HTML 構造はこちら。
<div id="container">
<div id="square"></div>
<div id="stretcher"></div>
</div>
スクロールの基準となる要素で scroll-timeline-name
で名前を付けて scroll-timeline-axis
で方向を定義します。scroll-timeline
プロパティもショートハンドとして使えます。定義されたものをアニメーション対象要素で animation-timeline
プロパティを通して呼び出します。
#container {
height: 300px;
overflow-y: scroll;
position: relative;
/* scroll-timeline: squareTimeline block; と同義 */
scroll-timeline-name: squareTimeline;
scroll-timeline-axis: block;
}
#stretcher {
height: 600px;
}
#square {
background-color: deeppink;
width: 100px;
height: 100px;
margin-top: 100px;
animation-name: rotateAnimation;
animation-duration: 3s;
animation-direction: alternate;
animation-timeline: squareTimeline;
position: absolute;
bottom: 0;
}
@keyframes rotateAnimation {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
これは名前をつけるパターンですが scroll()
関数で匿名指定もできます。シンプルな実用においてはこちらのほうが使われそうに見えますね。
#square {
/* 略 */
animation-timeline: scroll(block nearest);
}
CSS における記法は関連ドキュメントを追いかけるとそれなりの変遷を経ている様子が見受けられるので上記の記法が正式に採用されるかは謎です。
まとめ
簡単ですが Scroll Timeline の紹介でした。記事を書いている終盤に見つけた下記の動画が豊富なデモ URL と共に安心と信頼の Google Chrome Developers の発信なので一定の信頼ができる解説かと存じます。🫠
一昔前の悪いパララックス表現が再流行しないことを望みつつも、そもそも一定のパフォーマンス改善効果(≒当時ほど酷い体験にはなりづらい?)は期待できますし、どちらかというとカルーセル UI のアニメーションのほうが捗るかもしれませんね。ではでは 👋
関連記事
副業転職の Offers 開発チームがお送りするテックブログです。【エンジニア積極採用中】カジュアル面談、副業からのトライアル etc 承っております💪 jobs.overflow.co.jp
Discussion