2026年版 Webの「動き」と「表現」を理解するためのリンク集

公開日 · 更新日 · 17 MIN READ · 理解の記録

RECORD / 2026

Webの動きを作るとき、最初に決めるのはライブラリ名ではありません。

何をきっかけに、どの状態を、どんな進み方で、どこへ描くのか。

ここが決まると、Native CSSで足りるのか、JavaScriptが必要なのか、GSAPやThree.jsを使うべきなのかを判断できます。

僕が知りたいのも、ライブラリの一覧ではありません。

  • ブラウザの中で何が起きているのか
  • その仕組みを最小コードでどう実装するのか
  • 表現が大きくなったとき、何へ切り替えるのか
  • その技術を選ぶ理由を自分で説明できるか

この記事は、Webの動きを仕組み → 実装手段 → 選択条件の順で整理した地図です。

Webの動きは6つの工程でできている

どのアニメーションも、まず次の6つへ分けます。

図1:Webの動きに共通する6工程
  1. 1. 入力クリック、スクロール、時間
  2. 2. 状態閉じる、開く、選ぶ
  3. 3. 進行度開始0から終了1まで
  4. 4. 補間途中の値を作る
  5. 5. 描画DOM、Canvas、3Dへ反映
  6. 6. 確認負荷、操作、動きの軽減

根本は、入力を0〜1の進行度へ変え、その途中の値を描画することです。ライブラリが変わっても、この流れは変わりません。

たとえば、カードが500msで右へ200px動く場合はこうなります。

click
→ closed から open へ
→ 0〜1を500msで進める
→ ease-outで途中の値を作る
→ translateへ反映する

スクロールに合わせて3Dカメラが進む場合も、構造は同じです。

scroll
→ セクションの開始位置と終了位置を決める
→ 現在位置を0〜1へ直す
→ 必要なら補間する
→ Three.jsのcamera.positionへ反映する

入力から時間、DOM、Canvas、3D、GPU描画へ進むWebアニメーションの流れ

GSAPもThree.jsも、この6工程を消してくれるわけではありません。複雑になった工程を、書きやすく管理しやすくしてくれます。

実装手段は「進行度を誰が作るか」で選ぶ

動きの実装で迷ったら、時間を誰に進めてもらうかを考えます。

図2:進行度の作り方から実装手段を選ぶ
  1. 状態が変わるCSS Transition
  2. 決まった順番で進むKeyframes / WAAPI
  3. スクロールで進むScroll-driven / GSAP
  4. 指やマウスで進むPointer Events + rAF

二つの状態ならCSS。再生位置を操作するならJavaScript。スクロールやポインターが時間の代わりになる場合は、その入力を0〜1へ直します。

状態が変わるだけならCSS Transition

ホバー、開閉、選択、表示切り替えのように、開始と終了が2つの状態で表せるならCSSから始めます。

.card {
  translate: 0 0;
  transition: translate 240ms ease-out;
}

.card:hover {
  translate: 0 -8px;
}

ここではブラウザが進行度を作ります。JavaScriptは不要です。

判断基準は簡単です。

  • 状態が2つで表せる
  • 途中を細かく制御しない
  • 再生位置を外から操作しない

この3つなら、まずTransitionで十分です。

決まった順番を再生するならKeyframesかWeb Animations API

0%・40%・100%のように途中の状態が必要なら@keyframesを使います。

再生、停止、逆再生、現在位置の変更をJavaScriptから行いたいならWeb Animations APIへ進みます。

const animation = element.animate(
  [
    { opacity: 0, translate: "0 16px" },
    { opacity: 1, translate: "0 0" }
  ],
  { duration: 400, easing: "ease-out", fill: "both" }
);

animation.pause();
animation.currentTime = 200;

見た目はCSSでも、操作権はJavaScriptに置けます。

スクロールは「入った瞬間」と「進み続ける」を分ける

要素が画面へ入ったときに一度だけ表示するならIntersectionObserverです。

スクロール量に合わせて0〜1を連続して使うなら、Scroll-driven Animationsか、スクロール位置を正規化する処理が必要です。

const start = section.offsetTop;
const end = start + section.offsetHeight - innerHeight;
const progress = Math.min(1, Math.max(0, (scrollY - start) / (end - start)));

大切なのはscrollYをそのまま使わないことです。表現が必要としている区間を0〜1へ直してから、座標や透明度へ渡します。

指やマウスへ追従させるならPointer EventsとrequestAnimationFrame

ドラッグ、視差、追従カーソルのように入力が毎回変わる表現はJavaScriptで進行度を作ります。

let targetX = 0;
let currentX = 0;

addEventListener("pointermove", (event) => {
  targetX = event.clientX;
});

function frame() {
  currentX += (targetX - currentX) * 0.12;
  cursor.style.translate = `${currentX}px 0`;
  requestAnimationFrame(frame);
}

requestAnimationFrame(frame);

入力値と表示値を分け、毎フレーム少しずつ近づける。この考え方がlerpやspringの入口です。

DOM・SVG・Canvas・3Dは描きたい量で選ぶ

時間の進め方が決まったら、次は描画先です。

描画先 向いている表現 切り替える目安
DOM + CSS ボタン、カード、メニュー、記事UI 意味のある要素が中心なら最初に選ぶ
SVG ロゴ、線、図解、チャート、モーションパス 形をDOMとして選択・操作したい
Canvas 2D 粒子、波、描画ツール、大量の2D要素 DOM要素を増やすより1枚へ描く方が自然
WebGL / Three.js カメラ、奥行き、光、立体、シェーダー 3D空間そのものが体験の意味になる
WebGPU 大量計算、独自レンダリング、GPU計算 既存の描画手段では計算量や設計が足りない

DOMは意味とアクセシビリティを持ちやすい反面、大量の要素を毎フレーム動かす用途には向きません。

Canvasは大量描画に向きますが、描いた丸や文字はDOM要素ではありません。クリック判定や読み上げは別に設計します。

Three.jsは、scene、camera、geometry、material、light、rendererを使って3D空間を組み立てます。単に回転するカードを作るために導入するものではありません。

同じ女性がThree.jsとWebGPUを使い、立体の形状や光、粒子表現を組み立てている

WebGPUはThree.jsの上位版ではありません。GPUへ描画や計算の命令を組み立てる、より低い層のAPIです。最初から選ぶのではなく、何を計算したいかが明確になってから検討します。

ライブラリは「難しい工程をどこへ任せるか」で選ぶ

僕はNative CSSとJavaScriptを基準にします。Nativeが偉いからではありません。仕組みとコードの距離が近く、問題が起きた場所を追いやすいからです。

そのうえで、複雑さが増えた工程だけをライブラリへ渡します。

図3:複雑になった場所だけライブラリへ任せる
  1. 時間の組み立てが複雑GSAP
  2. UI状態と動きを近づけたいMotion
  3. 大量の2D描画PixiJS
  4. カメラ・光・立体が必要Three.js
  5. スクロールの感触を変えたいLenis
  6. 独自のGPU計算が必要WebGPU

最初から全部を入れません。Nativeで作り、管理できなくなった工程だけ置き換えます。

同じ女性がCSS、GSAP、Motionのタイムラインとイージングを操作している

GSAPを選ぶ条件

GSAPは、複数要素の開始位置、重なり、待ち時間、逆再生を1本のタイムラインとして管理したいときに使います。

const timeline = gsap.timeline();

timeline
  .to(".title", { opacity: 1, y: 0 })
  .to(".image", { scale: 1 }, "<0.15")
  .to(".caption", { opacity: 1 }, "-=0.2");

CSSのdelayが増え、前の時間を直すたびに後ろも修正しているなら、GSAPへ移る理由があります。

ScrollTriggerは、スクロール区間、固定、進行度、複数シーンの同期をまとめたいときに使います。表示開始だけならIntersectionObserver、単純なスクロール進行ならNative CSSも候補です。

Motionを選ぶ条件

Motionは、UIの状態とアニメーションを近い場所で宣言したいときに向いています。

特にReactなどで、要素の追加・削除、レイアウト変更、gesture、springをコンポーネント単位で扱うときに選びやすいです。

複雑な映像的タイムラインを作るならGSAP。UIの状態変化を宣言的に扱うならMotion。この違いで考えます。

Three.jsを選ぶ条件

Three.jsは、カメラ、立体、光、素材が表現の中心にあるときに選びます。

DOM要素を3D風に傾けたいだけならCSSで足ります。3Dモデルの中を移動する、光で質感を変える、粒子を空間へ配置するならThree.jsが候補です。

PixiJSを選ぶ条件

大量のスプライト、2Dゲーム、画像フィルターのように、CanvasやGPUで2Dをまとめて描きたいときに使います。

DOMのカード一覧を速くするために選ぶものではありません。描画対象をCanvasの中へ移す設計が必要です。

Lenisを選ぶ条件

Lenisは、アニメーションライブラリではなく、スクロールの入力と表示位置の間へ滑らかさを加える道具です。

僕は標準スクロールを基本にします。サイト全体の体験として慣性が必要で、アンカー移動、キーボード、モーダル、prefers-reduced-motionまで確認できる場合だけ導入します。

「なんとなく高級に見える」だけでは採用理由にしません。

作りたい表現から実装を選ぶ

作りたいもの 最初に使うもの 切り替え条件
ボタンやカードの反応 CSS Transition 途中状態や再生制御が必要ならWAAPI / Motion
順番に現れるHero CSS Keyframes 要素数と時間調整が増えたらGSAP
スクロールで一度表示 IntersectionObserver 進行度と同期するならScroll-driven / GSAP
スクロール連動の長い演出 Scroll-driven Animations 固定・複数シーン・細かな同期が増えたらGSAP
追従カーソルやドラッグ Pointer Events + requestAnimationFrame springやgesture管理が増えたらMotion
大量の2D粒子 Canvas 2D スプライト・フィルター管理が増えたらPixiJS
カメラで進む3D空間 Three.js 独自GPU計算が主役ならWebGPUも検討

選ぶ前に、次の7問へ答えます。

  1. 入力は時間、クリック、スクロール、ポインターのどれか
  2. 状態はいくつあるか
  3. 0〜1の進行度を誰が作るか
  4. 描画先はDOM、SVG、Canvas、3Dのどれか
  5. 同時に動く対象はいくつか
  6. 途中で停止、逆再生、同期が必要か
  7. 動きを減らしても内容と操作が成立するか

答えられない項目があるなら、まだライブラリを決める段階ではありません。

4つの動きを触って理解する

説明だけでは、動きの仕組みはつかみにくいものです。下の4例は、入力が進行度になり、見た目へ変わるところを実際に試せます。すべてNative CSSとJavaScriptだけで動きます。

触る → 変化を見る → コードを確かめる

保存したサンプルは、ブラウザで開くだけで動きます。

1. 状態を切り替える

使う:メニュー、カード、モーダル
次:再生制御や状態が増えたらMotion

閉じた状態
コードを見る
button.addEventListener("click", () => {
  card.classList.toggle("is-open");
});

.box { transition: transform 360ms; }
.is-open .box { transform: translateY(0); }

2. 順番に動かす

使う:ヒーロー、導入、順番のある説明
次:重なりや逆再生が増えたらGSAP Timeline

コードを見る
dots.forEach((dot, index) => {
  dot.animate(keyframes, {
    duration: 700,
    delay: index * 140
  });
});

3. 進行度で動かす

使う:スクロール進捗、場面転換、カメラ移動
次:実スクロールと同期するならScroll-driven Animations / ScrollTrigger

コードを見る
const progress = range.value / 100;
stage.style.setProperty(
  "--progress", progress
);
// スクロール量も同じ0〜1へ変換できる

4. 少し遅れて追いかける

使う:カーソル追従、視差、ドラッグの手応え
次:springやgesture管理が増えたらMotion

ここでポインターを動かす
コードを見る
current += (target - current) * 0.14;
follower.style.left = current + "px";
requestAnimationFrame(update);
// 差を少しずつ埋める = 補間

最初に作る3つで仕組みがつながる

学習はAPIの順番ではなく、同じ仕組みを少しずつ大きくします。

1. ホバーで持ち上がるカード

CSS Transitionで、状態、時間、easing、transformを理解します。

2. スクロール量で進むバー

スクロール区間を0〜1へ直し、入力と進行度を分けます。

3. マウスを少し遅れて追う円

Pointer Events、requestAnimationFrame、補間、描画をつなぎます。

この3つをNativeで作れれば、GSAPやMotionのコードを見たときも、何を任せているのかが分かります。

その次に、同じ進行度をSVGの線、Canvasの粒子、Three.jsのカメラへ渡します。描画先が変わっても、仕組みは変わりません。

技術名から選ばない。入力、進行度、描画先、規模から選ぶ。

これが、Webの動きを仕組みから実装へつなげる判断軸です。

読むならこの順番

全部を読む必要はありません。今作っている表現に必要な場所だけ開きます。

仕組みを理解するために読む

  1. W3C — Web Animations:時間、進行度、再生状態の共通モデルを確認する
  2. W3C — CSS Transitions:状態の変化からアニメーションが生まれる仕組みを確認する
  3. W3C — Scroll-driven Animations:時間の代わりにスクロール位置を使う考え方を確認する
  4. W3C — Pointer Events:マウス、指、ペンを同じ入力として扱う仕組みを確認する

仕様書は最初から最後まで読まず、記事で分からなかった言葉の定義を確かめる辞書として使います。

実装するときに読む

読む順番も技術名ではなく、今困っている工程から決めます。

3件のコメント

  1. Nativeから始める方針は仕組みを理解しやすい一方、実案件では対応ブラウザ、保守する人、既存構成も判断材料になります。複雑さだけでなく、運用条件も含めて選ぶ必要があります。

  2. CSS、JavaScript、GSAP、Motion、Three.jsを同じ判断軸で比べている点がこの記事の特徴です。図で仕組みをつかみ、操作例で結果を見てからコードへ進めます。

  3. この記事では、技術名から選ばず、入力・状態・進行度・補間・描画・確認の順で考えられるように整理しました。まず4つの動きを触り、必要な工程だけ持ち帰ってください。

コメントを残す