JS で自作するトゥイーン
GSAP / anime.js / motion などのライブラリを使う前に、「中で何が起きているか」を理解する。 rAF + 補間 + イージング の 3 点セットだけで、トゥイーン / キーフレーム / タイムライン / スプリングまで組める。
このノートの目的
- JS でアニメーションをライブラリ無しで書ける
- GSAP / anime.js / motion / framer-motion の裏側が分かる
- イージング関数を理解して使い分けられる
- キーフレーム・タイムラインを設計できる
- スプリング(バネ)系の動きを物理ベースで作れる
アニメーションの正体
画面上でなめらかに動いて見えるのは、毎フレーム少しずつ値を変えて描き直しているだけ。 コアは次の 3 つに集約される。
時間 (t)
──────────────────▶
0% ────────────────── 100%
[1] 0〜1 に正規化 (経過時間 / 全体時間)
[2] イージングで歪める (linear / easeOutQuad / etc)
[3] 値を補間 (lerp(start, end, t))
[4] 適用 (element.style.transform = ...)
30 行のミニ実装
ライブラリを使わず、requestAnimationFrame + lerp + イージングで動くトゥイーン:
function tween({ from, to, duration, easing = (t) => t, onUpdate }) {
return new Promise((resolve) => {
const start = performance.now()
function frame(now) {
const t = Math.min((now - start) / duration, 1)
const eased = easing(t)
const value = from + (to - from) * eased
onUpdate(value)
if (t < 1) requestAnimationFrame(frame)
else resolve()
}
requestAnimationFrame(frame)
})
}
// 使い方
const box = document.querySelector("#box")
await tween({
from: 0, to: 300, duration: 800,
easing: (t) => 1 - Math.pow(1 - t, 3), // easeOutCubic
onUpdate: (x) => {
box.style.transform = `translateX(${x}px)`
}
})
これが世のすべてのトゥイーンの最小核。あとはこれを「複数値同時」「複数アニメーション直列」 「逆再生 / ループ / 一時停止」… と拡張していくだけ。
用語の整理
| 用語 | 意味 |
|---|---|
| Tween | 2 値の間(between)を補間して動かす単位 |
| Keyframe | 時間軸上の複数の「節」となる値 |
| Easing | 0〜1 の進行を歪める関数(緩急をつける) |
| Interpolation | 2 値の中間を求める計算(lerp / spline / 球面) |
| Timeline | 複数のトゥイーンを時系列に並べる仕組み |
| Spring | バネと減衰の物理シミュレーション。時間ベースでない |
| Delta time (dt) | 前フレームからの経過時間(秒 / ms) |
| Easing function | 例: easeInOutCubic, easeOutBack |
このセクションの読み方
- requestAnimationFrame — 時間管理の基礎
- 補間 — 線形・カラー・配列・角度
- イージング関数 — 30 種類の実装と使い分け
- Tween クラス自作 — Promise / chaining / 制御
- キーフレーム — 多段・スプライン・パス
- タイムライン — 直列・並列・スクラブ
- スプリング — バネの物理
- 最適化と注意点 — 60fps を守る
ライブラリと自作の使い分け
| 状況 | 選択 |
|---|---|
| とにかく早く・複雑な演出 | GSAP / motion / anime.js |
| React で宣言的 | framer-motion / @react-spring |
| CSS で済む | CSS Transitions / Animations / WAAPI |
| Three.js / Canvas / WebGL の中 | 自作の方が綺麗(ループに統合できる) |
| 軽量さ・依存ゼロ | 自作(数十行で済む) |
| 学習目的 | 自作 |
本ノートで作るもの(最終形)
- 10 行の
lerpと 30 行のtween関数 - 30 種類のイージング関数(easings.net 互換)
- Promise ベース・チェイン可能な Tween クラス
- キーフレーム + スプライン補間
- 並列・直列・ネスト対応のタイムライン
- バネシミュレーション(質量・剛性・減衰)
- スクロール連動・スクラブ可能なシークバー
ブラウザ標準も知っておく
- CSS Transitions: 簡単。状態変化のみ
- CSS Animations / @keyframes: 純 CSS で完結
- Web Animations API (WAAPI):
element.animate(...)。CSS と JS のハイブリッド - View Transition API: ページ遷移補間 (→ View Transition API)
簡単な演出なら CSS / WAAPI で十分。複雑な演出やCanvas / WebGLでは JS で自前ループを回す方が綺麗にまとまる。
最短ルート
まず requestAnimationFrame と 線形補間 を一回手書きする。 そこから先は知識の積み重ねでしかない。