この章では、GSAPを使ったアニメーションを学びます。
GSAPは、Web制作のアニメーションでよく使われるJavaScriptライブラリです。CSSだけでは管理しづらい複雑な動き、順番に動くファーストビュー演出、スクロール連動アニメーションなどで使われます。
ただし、GSAPは「何でも派手に動かすためのもの」ではありません。情報を読みやすくし、ブランドの印象を高め、ユーザー体験を邪魔しない範囲で使うことが大切です。
GSAPを使う場面
まず、GSAPを使うべき場面を整理しましょう。
| やりたいこと | おすすめ |
|---|---|
| hoverで色を変える | CSS |
| 単純なフェードイン | CSS + Intersection Observer |
| 複数要素を順番に動かす | GSAP |
| ファーストビューで文字や画像を順番に表示する | GSAP Timeline |
| スクロール位置に連動して動かす | GSAP ScrollTrigger |
| 複雑なタイムライン演出 | GSAP |
小さな動きならCSSで十分です。
一方で、複数の要素を細かいタイミングで制御したい場合は、GSAPの方が読みやすく、調整もしやすくなります。
GSAPの導入
npmを使う環境では、GSAPをインストールして読み込みます。
npm install gsapimport { gsap } from "gsap";静的なHTML制作では、CDNで読み込む場合もあります。
<script src="https://cdn.jsdelivr.net/npm/gsap/dist/gsap.min.js"></script>この教材では、コードの考え方を理解するために、gsapが使える状態になっている前提で例を見ていきます。
gsap.to
gsap.toは、現在の状態から指定した状態へアニメーションします。
<div class="box js-box">Box</div>gsap.to(".js-box", {
x: 100,
opacity: 0.5,
duration: 1,
});この例では、.js-boxが現在位置から右に100px動き、透明度が0.5になります。
よく使うプロパティは次の通りです。
| プロパティ | 役割 |
|---|---|
x | 横方向の移動 |
y | 縦方向の移動 |
opacity | 透明度 |
scale | 拡大縮小 |
rotation | 回転 |
duration | アニメーション時間 |
delay | 開始までの待ち時間 |
ease | 動きの緩急 |
gsap.from
gsap.fromは、指定した状態から現在の状態へアニメーションします。
gsap.from(".js-title", {
y: 40,
opacity: 0,
duration: 0.8,
ease: "power2.out",
});この例では、.js-titleが「下に40px、透明」な状態から、CSSで定義された通常の状態へ戻ります。
ファーストビューのテキスト表示、セクション見出しの表示などでよく使います。
gsap.fromTo
gsap.fromToは、開始状態と終了状態の両方を指定します。
gsap.fromTo(
".js-image",
{
clipPath: "inset(0 100% 0 0)",
},
{
clipPath: "inset(0 0% 0 0)",
duration: 1,
ease: "power3.out",
}
);開始状態と終了状態を明確にしたい時に使います。
CSSや直前の状態に依存させたくない演出では便利です。
duration、delay、ease
GSAPでは、時間や緩急をオブジェクトで指定します。
gsap.from(".js-heading", {
y: 32,
opacity: 0,
duration: 0.8,
delay: 0.2,
ease: "power2.out",
});durationは秒単位です。
duration: 0.8なら0.8秒、delay: 0.2なら0.2秒待ってから開始します。
easeは動きの緩急です。
gsap.to(".js-button", {
scale: 1.05,
duration: 0.3,
ease: "power2.out",
});stagger
staggerは、複数要素を少しずつずらして動かす設定です。
<ul class="feature-list">
<li class="js-feature-item">特徴1</li>
<li class="js-feature-item">特徴2</li>
<li class="js-feature-item">特徴3</li>
</ul>gsap.from(".js-feature-item", {
y: 24,
opacity: 0,
duration: 0.6,
stagger: 0.12,
ease: "power2.out",
});stagger: 0.12は、各要素の開始タイミングを0.12秒ずつずらすという意味です。
カード一覧、ナビゲーション、ファーストビューのテキストなどでよく使います。
Timeline
複数のアニメーションを順番に管理したい時は、Timelineを使います。
const timeline = gsap.timeline();
timeline
.from(".js-logo", {
y: 20,
opacity: 0,
duration: 0.5,
})
.from(".js-copy", {
y: 32,
opacity: 0,
duration: 0.7,
})
.from(".js-button", {
y: 24,
opacity: 0,
duration: 0.5,
});Timelineに追加したアニメーションは、基本的に順番に再生されます。
ファーストビューの演出では、とてもよく使います。
Timelineの重なり
アニメーションを少し重ねたい場合は、位置パラメータを使います。
const timeline = gsap.timeline();
timeline
.from(".js-title", {
y: 32,
opacity: 0,
duration: 0.8,
})
.from(
".js-lead",
{
y: 24,
opacity: 0,
duration: 0.6,
},
"-=0.3"
);"-=0.3"は、前のアニメーションが終わる0.3秒前に開始するという意味です。
こうすると、動きがぶつ切りにならず自然につながります。
ScrollTrigger
ScrollTriggerは、スクロールに応じてGSAPアニメーションを実行するプラグインです。
npm環境では、GSAPとScrollTriggerを読み込み、登録します。
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);gsap.registerPlugin(ScrollTrigger)を忘れると、ビルド環境によっては本番で動かないことがあります。
ScrollTriggerの基本形
gsap.from(".js-section-title", {
y: 40,
opacity: 0,
duration: 0.8,
ease: "power2.out",
scrollTrigger: {
trigger: ".js-section-title",
start: "top 80%",
},
});triggerは、どの要素をきっかけにするかです。
start: "top 80%"は、トリガー要素の上端が画面の80%の位置に来たら開始する、という意味です。
markers
開発中は、markers: trueを使うと開始位置や終了位置を確認できます。
gsap.from(".js-section-title", {
y: 40,
opacity: 0,
scrollTrigger: {
trigger: ".js-section-title",
start: "top 80%",
markers: true,
},
});本番公開前には、markersを消します。
scrub
scrubを使うと、スクロール量に合わせてアニメーションが進みます。
gsap.to(".js-image", {
y: -80,
ease: "none",
scrollTrigger: {
trigger: ".js-image",
start: "top bottom",
end: "bottom top",
scrub: true,
},
});パララックス風の動きなどで使います。
scrubを使う時は、ease: "none"にすることが多いです。スクロール量と動きを素直に対応させるためです。
pin
pinを使うと、スクロール中に要素を固定できます。
gsap.to(".js-pin-content", {
x: -300,
scrollTrigger: {
trigger: ".js-pin-section",
start: "top top",
end: "+=800",
scrub: true,
pin: true,
},
});横スクロール風演出や、セクション固定演出で使います。
ただし、pinはレイアウトへの影響が大きいので、実務では慎重に使います。
レスポンシブ対応
PCだけGSAP演出を入れ、スマホでは軽くしたいことがあります。
その場合は、matchMediaを使って条件分岐します。
const mediaQuery = window.matchMedia("(min-width: 769px)");
if (mediaQuery.matches) {
gsap.from(".js-hero-image", {
scale: 1.1,
opacity: 0,
duration: 1,
ease: "power2.out",
});
}ScrollTriggerでも画面幅によって設定を変えることがあります。
実務では、スマホで動かす必要があるか、必ず確認しましょう。
prefers-reduced-motion
GSAPでも、アニメーションを減らしたいユーザーへの配慮が必要です。
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (!prefersReducedMotion) {
gsap.from(".js-title", {
y: 32,
opacity: 0,
duration: 0.8,
});
}大きく動く演出、長い演出、スクロール連動演出では特に意識しましょう。
小さな実装例: ファーストビュー演出
ファーストビューで、ロゴ、見出し、リード文、ボタンを順番に表示する例です。
<section class="hero">
<p class="hero-label js-hero-label">Web Production</p>
<h1 class="hero-title js-hero-title">伝わるWebサイトを作る</h1>
<p class="hero-lead js-hero-lead">設計から実装まで丁寧に支援します。</p>
<a class="hero-button js-hero-button" href="#contact">お問い合わせ</a>
</section>const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (!prefersReducedMotion) {
const timeline = gsap.timeline({
defaults: {
duration: 0.7,
ease: "power2.out",
},
});
timeline
.from(".js-hero-label", {
y: 20,
opacity: 0,
})
.from(
".js-hero-title",
{
y: 32,
opacity: 0,
},
"-=0.35"
)
.from(
".js-hero-lead",
{
y: 24,
opacity: 0,
},
"-=0.25"
)
.from(
".js-hero-button",
{
y: 16,
opacity: 0,
},
"-=0.2"
);
}Timelineのdefaultsを使うと、共通のdurationやeaseをまとめられます。
小さな実装例: セクション見出し
ScrollTriggerで、セクション見出しが画面に入ったら表示します。
<h2 class="section-title js-section-title">サービス</h2>gsap.utils.toArray(".js-section-title").forEach((title) => {
gsap.from(title, {
y: 32,
opacity: 0,
duration: 0.8,
ease: "power2.out",
scrollTrigger: {
trigger: title,
start: "top 80%",
},
});
});gsap.utils.toArrayを使うと、複数要素を配列として扱いやすくなります。
GSAP使用時の注意点
GSAPを使う時は、次の点に注意します。
- アニメーションを長くしすぎない
widthやheightより、できるだけtransformとopacityを使う- スマホで重くならないか確認する
- ScrollTriggerの
markersを本番に残さない - 画像やWebフォント読み込み後に位置がずれる場合がある
pinを使う演出は、ページ全体のスクロール体験を確認するprefers-reduced-motionを考慮する
アニメーションは、実装した時点では気持ちよく見えても、何度も使うユーザーにとっては負担になることがあります。
動きの量、時間、頻度を調整しましょう。
よくある失敗
GSAPでよくある失敗を整理しておきます。
- CSSで初期状態を隠し、JavaScriptが失敗した時にずっと見えない
- ScrollTriggerを読み込んだが
registerPluginしていない markers: trueを本番に残す- 同じ要素に複数のScrollTriggerを重ねて、動きが競合する
- スマホでもPCと同じ重い演出を入れてしまう
pinの影響でアンカーリンクや後続セクションがずれる- アニメーションが情報を読む邪魔になっている
実務では、見た目だけでなく「壊れにくさ」と「読みやすさ」も品質です。
この章のまとめ
この章では、GSAPの基本を学びました。
- GSAPは、複雑なタイミング制御やスクロール連動演出に向いている
- 単純なhoverやフェードならCSSで十分な場面も多い
gsap.toは現在から指定状態へ、gsap.fromは指定状態から現在へ動くstaggerで複数要素を順番に動かせる- Timelineを使うと、複数の演出を順番に管理しやすい
- ScrollTriggerでは、
trigger、start、end、scrub、pinを理解する - 実務では、パフォーマンス、スマホ表示、reduced motion、本番前の確認が重要
次の章では、Web制作で頻出するスライダーをSplideで実装します。