前回GSAPを使って「途中から横にスクロールするサイトを作る方法」をご紹介しました。
今回はその続きとして、GSAP(GreenSock Animation Platform)の基礎と、実務で使う場面が多い機能を順に取り上げます。タイムライン、ScrollTrigger、Flip の3点を中心に、最小構成のコードから始めて段階的に広げます。
GSAPとは
GSAPは、Web上のさまざまな要素に対してアニメーションを与えるためのJavaScriptライブラリです。CSSプロパティ、SVGの属性、数値や色など“数値化できるもの”を時間軸に沿って滑らかに変化させられます。単発の動きを扱う「Tween」と、複数の動きを連ねて管理する「Timeline」を中核に、必要に応じてプラグインを足して拡張できる構成になっています。
JavaScriptアニメーションはGSAP一択?|GSAPを使うメリット
時間軸の考え方がわかりやすい
複数要素の出入りや重なりを、時間の前後関係としてまとめて扱えます。順序変更や微調整が後からでも崩れにくく、リリース後の修正にも耐えます。
スクロール連動の設計がしやすい
特定セクションの開始・終了、固定表示、進捗との同期、スナップなど、スクロールを基準にした演出を一貫して組み立てられます。章立てのページや横スクロール表現と相性が良いです。
レイアウト遷移を自然に見せられる
要素の並び替えやサイズ変更など、DOM構造が変わる場面でも“前後の差分を補間する”形でつながりを保てます。カード一覧→詳細、フィルタやソート時の並び替えなど、UIの迷子を防ぐのに有効です。
保守対応/サイトのパフォーマンスが下がりにくい
タイムラインやラベルで動きに名前を付けられるため、チーム内の共有や保守がしやすくなります。プラグインは必要な分だけ選んで導入でき、バンドルを肥大化させにくいのも利点です。
【機能①】Timeline(タイムライン)
複数のアニメーション(Tween)を時間軸に並べてまとめて管理します。開始順序・重なり・相対遅延・再生/一時停止/逆再生などをひとつの塊として扱えます。
<script>
// タイムラインを作成。以降のアニメに共通のdurationとeaseを適用
const tl = gsap.timeline({ defaults: { duration: 0.6, ease: "power1.out" } });
// 見出し(.hero-title)を「下から・不透明度0→1」で表示
// from() は「この状態から現在の状態へ」遷移させる指定
tl.from(".hero-title", { y: 24, opacity: 0 })
// リード文(.hero-lead)を見出しの直後に続けて表示
// "<0.1" は直前ステップより0.1秒遅らせて開始(相対タイミング)
.from(".hero-lead", { y: 18, opacity: 0 }, "<0.1")
// CTA(.hero-cta)も同様に短い遅延で続ける
// 3要素を短い間隔で重ねることで、自然な段階表示になる
.from(".hero-cta", { y: 12, opacity: 0 }, "<0.1");
</script>
Timeline(タイムライン)実例
See the Pen gsap – timeline by Julia Shikanova (@jshikanova) on CodePen.
See the Pen GSAP 101 – complex timeline by GSAP (@GreenSock) on CodePen.
【機能②】ScrollTrigger(スクロール連動)
スクロール位置をトリガーにして、開始・終了・固定(pin)・同期(scrub)・スナップなどを制御します。
<script>
// ScrollTriggerプラグインを有効化
gsap.registerPlugin(ScrollTrigger);
// .section-visual をわずかに拡大しながら、スクロール位置と同期させる
gsap.to(".section-visual", {
scale: 1.05, // 対象の拡大率
scrollTrigger: {
// 監視対象(この要素がビューポート内でどこに来たら開始/終了するかを判定)
trigger: ".section-visual",
// 開始/終了の基準:
// "targetのtop が viewportの70%位置に来たら開始"
start: "top 70%",
// "targetのbottom が viewportの30%位置に来たら終了"
end: "bottom 30%",
// スクロール量とアニメ進行を同期
scrub: true,
// セクションを固定(pin)。スクロールしてもその場に留めて演出を見せる
// 余白は自動で確保(pinSpacing: true が既定)。不要なら false を指定
pin: true,
}
});
// 画像やWebフォントの読込完了で高さが変わる場合、
// 開始/終了位置を再計測してズレを防ぐ
window.addEventListener("load", () => ScrollTrigger.refresh());
</script>
ScrollTrigger(スクロール連動)実例
See the Pen Infinite Scrolling Snapping Cards with GSAP and ScrollTrigger (smooth) by GSAP (@GreenSock) on CodePen.
See the Pen scrollTrigger.observe() – swipe gallery by Cassie Evans (@cassie-codes) on CodePen.
【機能③】Flip(レイアウト遷移の補間)
DOMの並べ替え・サイズ変更・位置変更などで生じる「瞬間移動感」を、変更前後の差分を補間して自然に見せます。
<script>
// Flipプラグインを有効化
gsap.registerPlugin(Flip);
// 並べ替え対象のグリッドを取得
const grid = document.getElementById("grid");
// true=昇順 / false=降順 のトグル用フラグ
let asc = true;
// 並べ替えボタンをクリックしたら処理開始
document.querySelector(".js-sort").addEventListener("click", () => {
// 変更前の位置・サイズ・変形などをスナップショット
// この後にDOMを並べ替えてから、記録時点の見た目へ「戻す」ように補間して自然に見せる
const state = Flip.getState(".card");
// 子要素(.card)を配列化し、data-rankでソート
const cards = [...grid.children];
cards.sort((a, b) => {
const va = +a.dataset.rank, vb = +b.dataset.rank;
return asc ? va - vb : vb - va; // フラグに応じて昇順/降順
});
// 並び替え後の順序でDOMを再配置(ここで見た目は一瞬で入れ替わる)
cards.forEach(el => grid.appendChild(el));
// 変更「前」の状態から「今」のDOM配置へ、差分を補間してアニメーション
Flip.from(state, {
duration: 0.6,
ease: "power2.inOut",
stagger: 0.03 // カードを少しずつずらして動かす
});
// 次回クリック時の並び順を反転
asc = !asc;
});
</script>
Flip(レイアウト遷移の補間)実例
See the Pen Chess movement (GSAP Flip) by Peter Norton (@graphilla) on CodePen.
See the Pen Generative Re-arranging Grids with GSAP FLIP 💚 by George Francis (@georgedoescode) on CodePen.
【機能④】ScrollTo(スムーススクロール制御)
アンカーリンクや「上へ戻る」などのスムーススクロールを、高精度&制御しやすく実装します。
<script>
// アンカーリンク(.jump)をすべて取得し、クリック時にスムーススクロールさせる
document.querySelectorAll(".jump").forEach(a => {
a.addEventListener("click", e => {
// ブラウザのデフォルトのページ内ジャンプ(瞬間移動)を無効化
e.preventDefault();
// クリックされたリンクのhref(例:"#section2")を取得
const id = a.getAttribute("href");
// ScrollToPluginを使い、windowを目的の要素まで滑らかにスクロール
// duration: アニメ時間 / ease: 速度カーブ
gsap.to(window, { duration: 0.8, scrollTo: id, ease: "power2.out" });
});
});
</script>
ScrollTo(スムーススクロール制御)実例
See the Pen ScrollTrigger – horizontal scroll with variable width sections and anchor links by GSAP (@GreenSock) on CodePen.
【機能⑤】Draggable(ドラッグ機能付与)
要素をドラッグ/スワイプ可能にし、スナップや慣性も付与できます。スライダーや並べ替えUIで使えますね。
<script>
// 横スライダーのトラック要素を取得
const track = document.getElementById("track");
// 各スライド要素を配列化(幅や枚数の計算に使用)
const slides = gsap.utils.toArray(".slide");
// 1枚あたりの幅(px)。全スライドが同幅前提のシンプル実装
const slideW = slides[0].offsetWidth;
// 左方向への最大移動距離(負方向)。最後のスライド位置まで動かす
const maxX = -(slideW * (slides.length - 1));
// 初期位置を0にセット(GSAPで transform: translateX(0) に相当)
gsap.set(track, { x: 0 });
// トラックをドラッグ可能にする(Draggableプラグイン)
Draggable.create(track, {
type: "x", // 水平方向のみ
bounds: { minX: maxX, maxX: 0 }, // はみ出し防止:左端〜右端の範囲に制限
inertia: true, // 指を離した慣性スクロールを有効化
// 近いスライド位置へ吸着させる(スナップ)
snap: (x) => Math.round(x / slideW) * slideW
});
</script>
Draggable(ドラッグ機能付与)実例
See the Pen GSAP – ScrollSmoother – Drag Demo by Eric Van Holtz (@vanholtzco) on CodePen.
See the Pen [gsap/inertia] ❍ Card Animations Showcase – Challenge #2 / Entry 2 by Filip Zrnzevic (@filipz) on CodePen.
See the Pen GSAP GRID by Shunya Koide (@shunyadezain) on CodePen.
横スクロールの話から一歩広げて、GSAPの輪郭(タイムライン/ScrollTrigger/Flip)をざっと見てきました。動きに“過不足”を出さないための道具として、必要な場面にだけ静かに差し込めるのがGSAPの良さです。皆さんもぜひ触ってみてくださいね。