GSAPでひとつの要素を移動、回転、フェードさせる基本単位がTween(トゥイーン)です。
最初に覚えるメソッドは、次の4つです。
| メソッド | 指定する値 | 向いている場面 |
|---|---|---|
gsap.to() |
終了値 | 現在の状態から目的の状態へ動かす |
gsap.from() |
開始値 | 指定した状態から現在の見た目へ登場させる |
gsap.fromTo() |
開始値と終了値 | 開始・終了の両方を明示して再現性を高める |
gsap.set() |
即時反映する値 | アニメーション前の初期状態を作る |
たとえば、要素を右へ100px移動するだけなら次のコードです。
gsap.to(".box", {
x: 100,
duration: 1,
});
この記事では、4つのメソッドの違いから、pause()・restart()・reverse()などの再生制御、ボタン連打時の競合対策、ReactやVueでも必要になる後片付けまで順番に解説します。
GSAPのTweenとは
Tweenは、対象となる要素のプロパティを「ある値から別の値へ、指定した時間をかけて変化させる」アニメーションです。
const tween = gsap.to(".box", {
x: 100,
rotation: 45,
opacity: 0.5,
duration: 1,
});
このコードでは、.boxを1秒かけて次の状態へ変化させます。
- X方向へ100px移動する
- 45度回転する
- 不透明度を0.5にする
gsap.to()、gsap.from()、gsap.fromTo()は、いずれもTweenインスタンスを返します。変数へ入れておくと、あとから停止、再開、逆再生などを操作できます。
複数のTweenを順番に並べる場合はTimelineを使います。ひとつの動きを理解してから、GSAP Timelineの使い方へ進むと理解しやすくなります。
GSAPを読み込む
Tweenの基本機能はGSAP本体に含まれています。ScrollTriggerのような追加プラグインは必要ありません。
npmでインストールする
npm install gsap
import { gsap } from "gsap";
gsap.to(".box", {
x: 100,
duration: 1,
});
scriptタグで読み込む
簡単なHTMLで試す場合は、GSAP本体を読み込んだあとに自分のJavaScriptを実行します。
<script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js"></script>
<script src="main.js"></script>
本番では、動作確認したバージョンを固定し、更新時に表示を再確認してください。古い記事にあるGSAP 3.6.1固定のCDN例をそのままコピーする必要はありません。
動作確認用のHTMLとCSS
以降のコードは、次のHTMLを基準にしています。
<div class="demo">
<div class="box">BOX</div>
<button class="play-button" type="button">再生</button>
</div>
.box {
display: grid;
width: 100px;
aspect-ratio: 1;
place-items: center;
color: #fff;
background: #222;
}
gsap.to()で現在値から終了値へ動かす
gsap.to()は最もよく使うメソッドです。現在の見た目を開始値として取得し、指定した終了値へ変化させます。
gsap.to(".box", {
x: 120,
y: 40,
rotation: 45,
backgroundColor: "#2563eb",
duration: 1,
ease: "power2.out",
});
第1引数は対象、第2引数は終了値と動作設定をまとめたオブジェクトです。
対象には次の形式を指定できます。
- CSSセレクタ:
".box"、"#hero" - DOM要素:
document.querySelector(".box") - 複数のDOM要素や配列
- 数値プロパティを持つ通常のJavaScriptオブジェクト
xとyはtransformによる移動
GSAPのxとyは、CSSのleft・topではなくtransformによる移動です。通常の移動アニメーションでは、レイアウトを再計算しやすいleftよりxを優先します。
gsap.to(".box", {
x: 100,
yPercent: 50,
scale: 1.2,
rotation: 15,
});
gsap.from()で指定した状態から登場させる
gsap.from()は、指定した値を開始状態として、CSSなどで決まっている現在の状態へ変化させます。
gsap.from(".box", {
autoAlpha: 0,
y: 30,
duration: 0.8,
ease: "power2.out",
});
この例では、不透明で30px下にある状態から、元の位置・表示状態へ移動します。
autoAlphaはopacityとvisibilityをまとめて扱うGSAPの機能です。0にすると透明になるだけでなく、visibilityもhiddenになるため、見えない要素がクリックやフォーカスの邪魔をする問題を減らせます。
from()は作成時に開始状態を反映する
from()とfromTo()は、既定では作成時に開始状態をすぐ反映します。これをimmediateRenderと呼びます。
同じ要素へ複数のfrom()を重ねたり、Timeline上で作成順を誤ったりすると、開始値が想定外になることがあります。必要な場合はimmediateRender: falseを検討しますが、まずTweenを重複作成していないか確認してください。
読み込み時の一瞬の表示を防ぐ
JavaScriptが実行される前に要素が一瞬見える場合は、CSSで非表示にし、fromTo()で表示状態まで明示します。
.hero-copy {
visibility: hidden;
}
gsap.fromTo(
".hero-copy",
{ autoAlpha: 0, y: 24 },
{
autoAlpha: 1,
y: 0,
duration: 0.8,
ease: "power2.out",
}
);
JavaScriptが無効でも本文を読める必要があるサイトでは、no-jsクラスなどを使い、常時非表示にならないフォールバックも用意してください。
gsap.fromTo()で開始値と終了値を指定する
gsap.fromTo()は、第2引数に開始値、第3引数に終了値を指定します。
gsap.fromTo(
".box",
{
x: -80,
autoAlpha: 0,
},
{
x: 0,
autoAlpha: 1,
duration: 1,
ease: "power2.out",
}
);
duration、ease、コールバックなどの動作設定は、終了値を指定する第3引数へ書きます。
to・from・fromToの使い分け
| 状況 | 選ぶメソッド |
|---|---|
| 現在位置から右へ移動したい | to() |
| 下からふわっと現在位置へ出したい | from() |
| 毎回同じ開始・終了状態を保証したい | fromTo() |
| 値を瞬時に初期化したい | set() |
クリックするたび同じアニメーションを再生する
クリックイベント内で毎回新しいTweenを作ると、連打したときに複数のTweenが同じプロパティを取り合います。
開始時にTweenを1回だけ作り、restart()で再利用すると挙動を安定させやすくなります。
const revealTween = gsap.fromTo(
".box",
{ autoAlpha: 0, scale: 0.7, rotation: -20 },
{
autoAlpha: 1,
scale: 1,
rotation: 0,
duration: 0.7,
ease: "back.out(1.5)",
paused: true,
}
);
document.querySelector(".play-button").addEventListener("click", () => {
revealTween.restart();
});
fromTo()を使うだけで連打問題がすべて解決するわけではありません。新しいTweenを何度も生成せず、既存Tweenを再利用することが重要です。
新しい目的値へ動かす場合はoverwriteを使う
イベントのたびに目的値が変わり、新しいTweenを作る必要がある場合は、競合するプロパティを置き換えるoverwrite: "auto"を使えます。
document.addEventListener("pointermove", (event) => {
gsap.to(".cursor", {
x: event.clientX,
y: event.clientY,
duration: 0.25,
overwrite: "auto",
});
});
マウス移動のように高頻度で同じ数値プロパティを更新する場合は、後述するquickTo()のほうが適しています。
gsap.set()で値をすぐ反映する
gsap.set()は、アニメーションせず値を即時反映します。実質的にはdurationが0のTweenです。
gsap.set(".box", {
x: 40,
autoAlpha: 0,
transformOrigin: "50% 50%",
});
次のような用途に向いています。
- アニメーション開始前の位置や表示状態を作る
- 複数要素のtransform値をまとめて設定する
- GSAPが管理しているtransformへ安全に値を加える
DOMのstyleを直接書き換える方法でも値は設定できますが、アニメーション前後をGSAPで統一すると、transformの各成分を扱いやすくなります。
quickSetter()で高頻度の即時更新を軽くする
pointermoveなどで同じプロパティへset()を大量に実行する場合は、対象とプロパティを先に固定するquickSetter()を使えます。
const setX = gsap.quickSetter(".cursor", "x", "px");
document.addEventListener("pointermove", (event) => {
setX(event.clientX);
});
通常のUIではgsap.set()で十分です。処理回数が多く、実測で問題がある場合にquickSetter()へ切り替えます。
quickTo()で新しい値へ滑らかに追従する
値を即時反映するのではなく、現在値から新しい値へ短時間で追従させたい場合はquickTo()を使います。
const xTo = gsap.quickTo(".cursor", "x", {
duration: 0.3,
ease: "power3.out",
});
document.addEventListener("pointermove", (event) => {
xTo(event.clientX);
});
新しい数値を渡すたび、同じTweenが目的値を更新して再開されます。
duration・ease・delayなどの基本設定
Tweenの第2引数またはfromTo()の第3引数には、変化させる値と動作設定を書きます。
| 設定 | 意味 | 例 |
|---|---|---|
duration |
1回の再生時間(秒) | duration: 0.8 |
ease |
速度変化 | ease: "power2.out" |
delay |
開始までの待ち時間 | delay: 0.3 |
repeat |
初回後の繰り返し回数 | repeat: 2 |
repeatDelay |
繰り返し間の待ち時間 | repeatDelay: 0.2 |
yoyo |
繰り返すたび往復する | yoyo: true |
stagger |
複数要素の開始をずらす | stagger: 0.08 |
paused |
停止状態で作成する | paused: true |
overwrite |
競合Tweenの処理方法 | overwrite: "auto" |
イージングの種類と選び方は、GSAPのeaseとアニメーションプロパティで詳しく解説しています。
複数要素を順番に表示する場合は、GSAP staggerの使い方も参考にしてください。
Tweenを変数へ入れて再生制御する
あとから操作する場合は、Tweenインスタンスを変数へ入れます。
const tween = gsap.to(".box", {
x: 240,
rotation: 360,
duration: 2,
paused: true,
});
document.querySelector(".play").addEventListener("click", () => tween.play());
document.querySelector(".pause").addEventListener("click", () => tween.pause());
document.querySelector(".restart").addEventListener("click", () => tween.restart());
document.querySelector(".reverse").addEventListener("click", () => tween.reverse());
| メソッド | 動作 |
|---|---|
play() |
現在位置から順方向へ再生する |
pause() |
現在位置で一時停止する |
resume() |
方向を変えずに再開する |
restart() |
先頭へ戻って順方向へ再生する |
reverse() |
現在位置から逆方向へ再生する |
seek(秒) |
指定時間へ再生位置を移す |
progress(0〜1) |
進捗率で再生位置を取得・変更する |
timeScale() |
再生速度を変更する |
kill() |
Tweenを停止して親から削除する |
revert() |
追加したインラインスタイルを戻してTweenを破棄する |
seek()とprogress()の違い
seek(1.5)は1.5秒の位置へ移動します。progress(0.5)はdurationに関係なく50%の位置へ移動します。
tween.seek(1.5);
tween.progress(0.5);
tween.play();
どちらも、Tweenが停止中か再生中かという状態や再生方向は、それだけでは変更しません。
kill()とrevert()の違い
kill()はTweenを停止・破棄しますが、実行時点のインラインスタイルが残る場合があります。
revert()はTweenを破棄し、GSAPが追加したインラインスタイルをアニメーション前の状態へ戻します。画面を破棄するときや、メディアクエリ変更時に元のCSSへ戻したい場合に向いています。
コールバックで開始・更新・完了を検知する
Tweenには、再生状況に応じて関数を実行するコールバックを指定できます。
gsap.to(".box", {
x: 200,
duration: 1,
onStart: () => console.log("開始"),
onUpdate: () => console.log("更新中"),
onComplete: () => console.log("完了"),
});
onUpdateは再生中に何度も呼ばれるため、重いDOM処理を毎回行わないよう注意してください。コールバックの種類と引数は、GSAPのコールバックと実行タイミングで詳しく解説しています。
複数のTweenはTimelineでまとめる
delayを増やして順番を作ると、途中の時間を変更するたびに後続のdelayも直す必要があります。複数のTweenを連続・重複させる場合はTimelineを使います。
const timeline = gsap.timeline();
timeline
.from(".title", { autoAlpha: 0, y: 20, duration: 0.6 })
.from(".description", { autoAlpha: 0, y: 16, duration: 0.5 }, "-=0.2")
.from(".button", { autoAlpha: 0, scale: 0.9, duration: 0.4 }, "-=0.15");
"-=0.2"は、直前のTweenが終わる0.2秒前から開始する指定です。複数段階の値をひとつのTweenでつなぐ場合は、GSAP keyframesの使い方も選択肢になります。
ReactやVue、SPAでは後片付けを行う
画面遷移やコンポーネントの再マウントがある環境では、古いTweenやイベントリスナーを残さないことが重要です。
通常のJavaScriptでも、gsap.context()を使うと、関数内で作成したTweenやScrollTriggerをまとめて戻せます。
const section = document.querySelector(".animation-section");
const context = gsap.context(() => {
gsap.from(".box", {
autoAlpha: 0,
y: 24,
duration: 0.8,
});
}, section);
// 画面やコンポーネントを破棄するとき
context.revert();
第2引数のsectionを指定すると、context内のセレクタをその要素の子孫へ限定できます。ReactではGSAP公式のuseGSAP()も利用できます。
動かない・意図どおりにならないときの確認項目
対象要素が取得できていない
JavaScriptをHTMLより先に実行すると、対象要素がまだ存在しないことがあります。scriptをbody末尾で読み込むか、deferを使います。
<script src="main.js" defer></script>
display: noneをそのままフェードしようとしている
display: noneの要素はレイアウト上に存在しません。単純なフェードでは、autoAlphaでopacityとvisibilityを扱うか、表示前にdisplayを戻します。
同じプロパティを複数のTweenが操作している
ボタン連打やpointermoveでTweenを大量作成すると、xやopacityが競合します。次の順で見直します。
- ひとつのTweenを
restart()して再利用できないか overwrite: "auto"で競合プロパティだけ置き換えられないか- 高頻度更新なら
quickSetter()またはquickTo()へ変えられないか
from()の開始状態が想定と違う
同じ要素へ複数のfrom Tweenを作っていないか、作成時点ですでにインラインスタイルが付いていないかを確認します。開始・終了値を確定したい場合はfromTo()を使います。
ScrollTriggerだけ動かない
Tweenの基本機能と異なり、ScrollTriggerは別途読み込みとプラグイン登録が必要です。スクロール固定はScrollTriggerのpinの使い方で解説しています。
動きを減らす設定に配慮する
大きな移動、回転、繰り返しは、利用者によって負担になることがあります。prefers-reduced-motionを確認し、動きを減らす設定ではアニメーションを省略します。
const reduceMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)"
).matches;
if (reduceMotion) {
gsap.set(".box", { x: 0, autoAlpha: 1 });
} else {
gsap.from(".box", {
x: -40,
autoAlpha: 0,
duration: 0.7,
});
}
装飾アニメーションを省略しても、情報や操作が失われないHTMLを先に作ることが大切です。
よくある質問
TweenとTimelineの違いは何ですか?
Tweenは対象のプロパティを変化させる1つのアニメーションです。Timelineは複数のTweenやTimelineを時間軸上へ配置し、まとめて制御するコンテナです。
gsap.to()とCSS transitionはどう使い分けますか?
hoverなどの単純な状態変化はCSS transitionが簡潔です。複数段階の再生制御、途中位置への移動、逆再生、コールバック、ScrollTriggerとの連携が必要ならGSAPが向いています。
repeat: 1は何回再生されますか?
初回に加えて1回繰り返すため、合計2回再生されます。無限ループはrepeat: -1ですが、読みやすさと負荷に配慮してください。
アニメーション後のstyle属性を消すには?
Tweenを破棄し、GSAPが追加したインラインスタイルを元へ戻す場合はrevert()を使います。単に停止・破棄するkill()とは役割が異なります。
まとめ
GSAPの基本は、4つのメソッドを目的に合わせて選ぶことです。
to():現在値から終了値へ動かすfrom():指定した開始値から現在の状態へ動かすfromTo():開始値と終了値を両方指定するset():値をアニメーションせず即時反映する
クリックで繰り返す場合は、Tweenを毎回作るのではなくrestart()で再利用します。目的値が変わる場合はoverwrite: "auto"、高頻度の即時更新はquickSetter()、滑らかな追従はquickTo()を検討します。
まずto()で1要素を動かし、変数に入れたTweenをpause()・restart()・reverse()で操作してみると理解しやすくなります。
関連記事
- GSAPのeaseとアニメーションプロパティ
- GSAP staggerの使い方
- GSAP keyframesの使い方
- GSAP Timelineの使い方
- GSAPのコールバックと実行タイミング
- GSAP ScrollTriggerのpinの使い方