連続した同じ要素を一度にアニメーションさせるのではなく、GSAPのStaggerというプロパティで時間差を作り、0.2秒ごとなど順番にアニメーションさせる方法を解説していきます。
GSAPを使ったことがないという人は、まず以下の記事を参照下さい。
GSAPとは?基本的な使い方とアニメーションのサンプル付きで解説
続きを見る
重要なコード以外は省略している箇所が多いので、全部見たい人はCodePen左上のHTML・CSS・JSをクリックして下さい。
(有料になっていたらすいません🙇♂️)
GSAPのStaggerで時間差を作り順番にアニメーションさせる方法
まずはStaggerを使わずに同じ要素を並べた状態でアニメーションさせてみます。
HTMLはこちら。
<div class="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
同じclass名の要素を5つにしています。
JavaScriptはこちら。
gsap.to(".box", {
y: 100, // 下に100px移動
backgroundColor: "#ffb6c1", // 背景色
borderRadius: "50%", // 正円
rotate: 360, // 360°回転
duration: 2, // 2秒間アニメーション
repeat: -1, // リピート無限
yoyo: true, // リピートで順方向と逆方向を繰り返す
ease: "none", // イージングなし(等速)
});
色々書いていますが、とりあえず気にしなくてOKです。
サンプルはこちら。
See the Pen
GSAP(Staggerなし) by junpei (@junpei-sugiyama)
on CodePen.
全て同じタイミングで動いていますね。
これをStaggerを使って動くタイミングをズラしたいと思います。
Staggerの基本的な書き方
Staggerの書き方は非常に簡単で、最後の一行を追記するだけです。
gsap.to(".box", {
y: 100, // 下に100px移動
backgroundColor: "#ffb6c1", // 背景色
borderRadius: "50%", // 正円
rotate: 360, // 360°回転
duration: 2, // 2秒間アニメーション
repeat: -1, // リピート無限
yoyo: true, // リピートで順方向と逆方向を繰り返す
ease: "none", // イージングなし(等速)
stagger: 0.5, // 0.5秒遅れて順番に再生
});
そしてサンプルがこちらです。
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
1つずつ順番にアニメーションしています。
ちなみにHTMLとCSSは変わっていません。
Staggerオブジェクトの書き方
先ほどは時間だけを指定するシンプルな書き方でしたが、オブジェクトを使うと細かい設定が可能です。
例えば以下のようなコードがあったとします。
gsap.to(".box", {
y: 100, // 下に100px移動
stagger: 0.5, // 0.5秒遅れて順番に再生
});
これをオブジェクトを使うとこのような書き方になります。
gsap.to(".box", {
y: 100, // 下に100px移動
stagger: {
each: 0.5, // 0.5秒遅れて順番に再生
},
});
こうすることでStaggerだけのプロパティ(オプション)を設定することが出来ます。
Staggerオブジェクトで使えるプロパティ(オプション)
Staggerオブジェクトで使えるプロパティはこちらです。
プロパティ名 | 意味 | 単位 |
each | アニメーション開始時間の間隔 | 秒 |
amount | アニメーション開始時間の間隔の合計時間 | 秒 |
from | アニメーション開始位置を指定 | "start" "end" "center" "edges" "random" または数値 |
grid | fromで指定した位置から広がるように アニメーション | "auto" または[数値, 数値] |
axis | grid有効時に使用可能で、 アニメーションの方向軸を指定 | "x" "y" |
1つずつサンプルを見ていきます。
each:アニメーション開始時間の間隔
これはオブジェクトの書き方で書いた通り、通常のstagger: 数値,
と同じです。
gsap.to(".box", {
y: 100, // 下に100px移動
stagger: 0.5, // 0.5秒遅れて順番に再生
});
// ↓同じ結果↓
gsap.to(".box", {
y: 100, // 下に100px移動
stagger: {
each: 0.5, // 0.5秒遅れて順番に再生
},
});
通常の書き方と全く同じですが、一応こちらがオブジェクトで書いたサンプルです。
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
amount:アニメーション開始時間の間隔の合計時間
each
はアニメーション開始時間の間隔でしたが、amount
はアニメーション開始時間の間隔の合計時間になります。
例えばこれまでの例では要素が5つで4分割されているので、each: 0.5,
とamount: 2,
は同じ結果になります。
gsap.to(".box", {
y: 100, // 下に100px移動
stagger: {
each: 0.5, // 0.5秒遅れて順番に再生
},
});
// ↓同じ結果↓
gsap.to(".box", {
y: 100, // 下に100px移動
stagger: {
amount: 2, // アニメーション間隔の合計時間
},
});
これはamount: 2,
を4で割ったら0.5になるからですね。
これが要素の数が5つでamount: 4,
なら、要素間の時間間隔は以下のように1秒になります。
See the Pen
GSAP(Stagger・amount) by junpei (@junpei-sugiyama)
on CodePen.
例えば要素の数が違うグループでも、アニメーションの開始と終了を同じタイミングにしたい場合に使えます。
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
from:アニメーション開始位置を指定
fromはアニメーションの開始位置を指定します。
fromの種類
- start:最初の要素から開始
- end:最後の要素から開始
- center:中央の要素から開始
- edges:端の要素から開始
- random:ランダム
- 数値:何番目の要素から開始するか指定
書き方はこちらです。
gsap.to(".box", {
y: 100, // 下に100px移動
stagger: {
each: 0.5, // 0.5秒遅れて順番に再生
from: "start", // 最初の要素から開始
},
});
それでは1つずつサンプルをご紹介しますが、無限リピートすると分かりにくいのでリピートは無効にしています。
なので最初から再生させたい場合は右下の『Rerun』をクリックして下さい。
from:startのサンプル
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
from:endのサンプル
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
from:centerのサンプル
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
from:edgesのサンプル
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
from:randomのサンプル
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
これは何度もRerunをクリックすると毎回アニメーションを開始する要素が違うのが分かります。
from:数値のサンプル
数値は0だと1番目の要素から開始、1だと2番目の要素から開始という感じになります。
- from: 0 → 1番目の要素からアニメーション開始
- from: 1 → 2番目の要素からアニメーション開始
- from: 2 → 3番目の要素からアニメーション開始
- from: 3 → 4番目の要素からアニメーション開始
- from: 4 → 5番目の要素からアニメーション開始
例えばfrom: 1
だと2番目の要素からアニメーションが開始します。
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
grid:fromで指定した位置から広がるようにアニメーション
これは要素がグリッド状に表示されている場合に、from
で指定した位置から広がるようにアニメーションするプロパティです。
放射線状とも言えますね。
グリッド状で無くても効きますが、効果的には使えないかと思います。
書き方はこちらになります(stagger以外は省略)
gsap.to(".box", {
stagger: {
each: 0.1, // 0.1秒遅れて順番に再生
from: "center", // 中央の要素から開始
grid: "auto", // 放射線状にアニメーション
},
});
数値でも指定できますが、数値にすると放射線状にはなりません。
今回は放射線状になるgrid: "auto"
のサンプルを見てみます。
from
の値によって広がり方が違うので、1つずつ見てみます(display: grid;
ではなくdisplay: flex;
を使っています)
from: "start"のサンプル
これは設定しなくても同じです。
See the Pen
GSAP(Stagger・grid) by junpei (@junpei-sugiyama)
on CodePen.
from: "end"のサンプル
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
from: "center"のサンプル
See the Pen
GSAP(Stagger・grid・center) by junpei (@junpei-sugiyama)
on CodePen.
ちなみにgrid: "auto"
がないとこうなります。
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
中央から開始していますが、放射線状ではなく1つずつアニメーションしています。
from: "edges"のサンプル
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
from: "random"のサンプル
See the Pen
GSAP(Stagger・grid・random) by junpei (@junpei-sugiyama)
on CodePen.
ランダムはgrid: "auto"
が無くても変わらないように思えますが、無いとこうなります。
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
先ほどのcenter
を見ても分かりますが、grid
を使うと複数の要素が同時にアニメーションを開始していきます。
axis:grid有効時にアニメーションの方向軸を指定
これはgridが有効時に使えるプロパティですが、これを設定しないとX軸とY軸両方に向かってアニメーションが広がります。
つまり放射線状に広がりますが、axis: "x"にするとX軸方向のみ、axis: "y"にするとY軸方向のみアニメーションします。
from: "center"
で見てみたいと思います。
axis未設定
axisを設定しないと中心から放射線状に広がります。
See the Pen
GSAP(Stagger・grid・center) by junpei (@junpei-sugiyama)
on CodePen.
axis: "x"
これはX軸、つまり横方向にアニメーションします。
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
axis: "y"
これはY軸、つまり縦方向にアニメーションします。
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
Staggerオブジェクト(括弧)の外と中に書く違い
Staggerではイージングを指定できるease
とリピートを指定できるrepeat
を指定できますが、Staggerオブジェクトの外に書くか中に書くかで動きが変わります。
これは実際に見た方が分かると思うので、サンプルをご覧下さい。
ease(イージング)の場合
まずはStaggerオブジェクトの外に書いた場合がこちら。
gsap.to(".box", {
ease: "back.out(5)", // イージング
stagger: {
each: 0.5, // 0.5秒遅れて順番に再生
},
});
これは少し先までアニメーションして少し戻るイージングです。
サンプルはこちらです。
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
これは要素ごとにイージングが適用されていて、予想通りかと思います。
次はStaggerオブジェクトの中に書いた場合がこちら。
gsap.to(".box", {
stagger: {
each: 0.5, // 0.5秒遅れて順番に再生
ease: "back.out(5)", // イージング
},
});
サンプルはこちらです。
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
今度はイージングが効いていない上にバラバラになってしまいました。
Staggerオブジェクトの中に書いた場合は要素ごとではなく全体にイージングがかかると解説している記事もありますが、色々試してみた結果『イージングは効かない上に変な動きになる』かと思います。
他には時計の秒針のように動くease: "steps(12)"
だとこうなります。
まずはStaggerオブジェクトの外に書いた場合。
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
これはちゃんとイージングが効いていますね。
次は問題のStaggerオブジェクトの中に書いた場合がこちら。
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
どう見てもイージングは効いていませんね。
なのでease
を書く場合はStaggerオブジェクトの外に書きましょう。
repeatの場合
repeat
はease
と違い、ちゃんと効きます。
まずはStaggerオブジェクトの外に書いた場合がこちら。
gsap.to(".box", {
repeat: -1, // リピート無限
yoyo: true, // リピートで順方向と逆方向を繰り返す
stagger: {
each: 0.5, // 0.5秒遅れて順番に再生
},
});
これまでのリピートはずっとこの書き方をしています。
そしてサンプルはこちらです。
See the Pen
GSAP(Stagger・ease・repeat・外) by junpei (@junpei-sugiyama)
on CodePen.
全ての要素のアニメーションが終わってからリピートを開始しています。
次はStaggerオブジェクトの中に書いた場合がこちら。
gsap.to(".box", {
stagger: {
each: 0.5, // 0.5秒遅れて順番に再生
repeat: -1, // リピート無限
yoyo: true, // リピートで順方向と逆方向を繰り返すå
},
});
yoyoも中に書いていますが、これを外に書くと変な動きをするので、yoyoも中に書きます。
サンプルはこちらです。
See the Pen
Untitled by junpei (@junpei-sugiyama)
on CodePen.
今度は全ての要素のアニメーションが終わるのを待たずにリピートを開始しています。
違いは以下になります。
- 外に書いた場合:全ての要素のアニメーションが終わってからリピート
- 中に書いた場合:要素単位でアニメーションが終わったら即リピート(ノンストップ)
このような違いがあるので、用途に応じて使い分けるといいと思います。
まとめ
今回はGSAPのプロパティ『Stagger』を使って時間差で順番にアニメーションさせる方法について解説しました。
時間差で順番にアニメーションと言ってもかなり色々な調整ができるのが分かったと思います。
ぜひご自身でも色々試してみて下さい。
以上になります。