🦸
GSAPの基本的な記述をまとめる
はじめに
JavaScriptのアニメーションライブラリ「GSAP」の基本的な記述や、よく使う機能をまとめたいと思います。
GSAPはとても高機能で基本の部分となる記述を抑えるだけでも、工夫次第でいろんな表現ができます。当記事では触れませんがSVGやcanvasなどと組み合わせるとアニメーションの幅が一気に広がります。また、scrollTriggerやMotionPathPluginなどプラグインもとても充実しています。
基本的な動きを組み合わせたイントロアニメーション
ループやリピート制御を組み合わせたエフェクト
連続的な処理
応用:canvasと組み合わせたイントロアニメーション
GSAPのインストール
npm install gsap
// for cdn
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.0/gsap.min.js"></script>
import {gsap} from "gsap";
基本のメソッド4つ
-
set
– アニメーション対象要素の初期値を指定 -
to
– アニメーション完了時の状態を指定 -
from
– アニメーション開始時の状態を指定 -
fromTo
– アニメーション開始時と終了時の状態を指定
基本的なメソッド
// set アニメーション対象要素の初期値を指定
const firstPosition = {
x: 100,
y: 100,
}
gsap.set('.box', {
x: firstPosition.x, //x軸を100px移動
y: firstPosition.y, //y軸を100px移動
})
// to アニメーション終了時の状態を指定
gsap.to('.box', 1, {
// // x, y 100px移動した状態で終了
x: 100,
y: 100,
})
// from アニメーション開始時の状態を指定
gsap.from('.box', 1, {
// x, y 100px移動した状態で開始
x: 100,
y: 100,
})
// fromTo アニメーション開始時と終了時の状態を指定
gsap.fromTo('.box', 1,
// x, y -100px移動した状態で開始
{
x: -100,
y: -100,
},
// x, y 100px移動した状態で終了
{
x: 100,
y: 100,
}
)
アニメーションでよく使うプロパティ
CSSアニメーションでもよく使うtransform類が指定できます。
- 移動 –
translate
- 伸縮 –
scale
- 回転 –
rotate
- 歪み –
skew
transform類
gsap.to('.box', 1,
{
// translate
x: 100, // transform: translateX(100px)
y: 100, // transform: translateY(10px)
xPercent: -50, // transform: translateX(-50%)
yPercent: -50,// transform: translateY(-50%)
// scale
scale: 1.5, // transform: scale(1.5, 1.5)
scaleX: 1.5, // transform: scaleX(1.5)
scaleY: 1.5, // transform: scaleY(1.5)
// rotate
rotation: 180, // transform: rotate(180deg)
rotationX: 180, // transform: rotateX(180deg)
rotationY: 180, // transform: rotateY(180deg)
// skew
skewX: 20, // transform: skew(20deg, 0)
skewY: 20, // transform: skew(0, 20deg)
}
)
duration delay(時間制御)
-
duration
– アニメーションの秒数を指定 -
delay
– アニメーションの開始時間を指定
// duration
// 第二引数に指定
gsap.to('.box', 1, { // 1秒かけてアニメーション
x: '100px',
})
//or
// オブジェクトのキーに指定
gsap.to('.box', {
x: '100px',
duration: 1, // 1秒かけてアニメーション
})
// delay
gsap.to('.box', {
x: '100px',
delay: 1, // 1秒後にアニメーション
})
opacity autoAlpha(透過制御)
フェードエフェクトなどでopacityで透過処理をする際、同時にvisibility: hidden;
をつけたい場合に、autoAlpha
を使用することで、opacityとvisibilityを指定することができます。
gsap.fromTo('.box',
{
autoAlpha: 0, // opacity: 0;とvisibility: hidden;を指定
},
{
autoAlpha: 1, // opacity: 1;とvisibility:visible;を指定
}
);
また、display: none;
を指定したい場合は、onComplete
の関数内で直接指定する必要があります。
const box = document.querySelector('.box')
gsap.fromTo(box ,
{
opacity: 0,
onComplete: () => {
box.style.display = 'none'
}
},
{
opacity: 1,
onComplete: () => {
box.style.display = 'block'
}
}
);
アニメーションの繰り返し
-
repeat
– 繰り返しの回数 -
repeatDelay
– 繰り返しするまでの遅延 -
yoyo
– 繰り返し時に反転する -
yoyoEase
– 反転の際のイージング
gsap.to('.box', 1, {
repeat: -1, // -1で無限に繰り返す
repeatDelay: .5, // 0.5秒後に繰り返す
yoyo: true, // 繰り返し時に反転する
yoyoEase: 'power1.out', // 反転の際のイージング
})
複数要素をずらしてアニメーション
stragger
– 複数要素を遅延させる際に使用
-
each
– 遅延させる時間 -
from
– 開始位置の指定 -
start
– 始めの要素から -
end
– 最後の要素から -
center
– 真ん中の要素から -
edges
– 始めと終わりの要素から同時に -
ramdom
– ランダムに
gsap.set('.list__item', {
y: 30,
opacity: 0
})
gsap.to('.list__item', 1, {
y: 0,
opacity: 1,
ease: 'expo.out',
stagger: {
each: .1, // 遅延させる時間
from: 'start' // 開始位置の指定 start, end, center, edges, random
}
})
straggerのデモ
キーフレーム(Keyframes)
CSSアニメーションでよく使うkeyframesもgsapで記述できます。
二次元配列や、css同様でパーセントの指定ができます。
// keyframes
// 書き方1
gsap.to('.box', 4, {
keyframes: {
x: [0, 100, 100, 0, 0],
y: [0, 0, 100, 100, 0],
ease: 'power4.out',// 全体のイージング
easeEach: 'power4.out'// 個々のイージング
}
})
// 書き方2
gsap.to('.box', 3, {
keyframes: [
{
x: 100,
y: 100,
},
{
x: 0,
y: 0
},
{
rotation: 180
}
],
ease: 'expo.out',// 全体のイージング
easeEach: 'power4.out'// 個々のイージング
})
// 書き方3
gsap.to('.box', 3, {
keyframes: {
'0%': {
x: 100,
},
'50%': {
y: 100,
},
'100%': {
x: 0,
y: 0
}
},
ease: 'expo.out',// 全体のイージング
easeEach: 'power4.out'// 個々のイージング
})
制御用のメソッド
-
play()
– アニメーションの開始 -
pause()
– 一時停止 -
resume()
– 一時停止から再開 -
restart()
– リスタート -
reverse()
– 逆再生 -
seek(num)
– 引数の値の秒数地点での表示を確認できる(デバッグ時に有効) -
timeScale(num)
– 引数の値の倍速で再生(速度調整) -
duration(num)
– 引数の値のdurationを設定
// 制御用メソッド
const animation = gsap.to('.box', 3, {
x: 200,
paused: true, // 停止状態に
})
// クリックイベントの指定
function clickFunction(id, method) {
document.getElementById(id).addEventListener('click', () => {
method()
})
}
// アニメーション制御時によく使うメソッド
clickFunction('play', () => animation.play()) // アニメーションの開始
clickFunction('pause', () => animation.pause()) // 一時停止
clickFunction('resume', () => animation.resume()) // 一時停止から再開
clickFunction('restart', () => animation.restart()) // リスタート
clickFunction('reverse', () => animation.reverse()) // 逆再生
// デバッグ時によく使うメソッド
clickFunction('seek', () => animation.seek(2))// 引数に入れられた数値の秒数地点での表示を確認できる(デバッグ時に有効)
clickFunction('timeScale', () => animation.timeScale(1))// 引数の値の倍速で再生(速度調整)
clickFunction('duration', () => animation.duration(1))// 引数の値のdurationを設定
タイムライン(timeline)
初期化した後にメソッドチェーンでつなげることで、連続的な処理を行うことができます。
// 要素を指定してメソッドチェーンで記述
const tl = gsap.timeline()
tl.to('.box', 1, {
x: 200
})
.to('.box', 1, {
y: 200,
rotation: 90
})
.to('.box', 1, {
x: 0,
rotation: 360
})
.to('.box', 1, {
y: 0,
rotation: 0
})
timelineでのアニメーションの開始時間の制御
アニメーションの開始時間などを、to()などのメソッドの第3または第4引数に指定することができます。
-
数値
– 指定時間後にアニメーションを開始、※timelineではtimeline全体の時間を基準に考える -
+=1
– そのアニメーション自身を基準に1秒後に発火、delay: 1と同じ -
-=2
– そのアニメーション自身を基準に2秒前に発火、delay: -2と同じ -
<
– 直前のアニメーションの開始時に発火 -
>3
– 直前のアニメーションが終わってから、3秒後に発火 -
<4
– 直前のアニメーションが始まってから、3秒後に発火
const tl = gsap.timeline()
tl.to('.box', 1, {
x: 100,
backgroundColor: 'red'
})
.to('.box', 1, {
y: 100,
backgroundColor: 'blue'
})
.to('.box', 1, {
x: 0,
backgroundColor: 'orange'
}, '<') // < 直前のアニメーション開始時に発火
.to('.box', 1, {
y: 0,
backgroundColor: 'green'
})
timelineの連結、ネスト
timelineの連結
タイムライン1の後にタイムライン2を発火させたいといった場合には.add()
を使用することで2つのタイムラインを連結させることができます。
const tl = gsap.timeline()
tl
.to('.box1', 1, {
y: 30,
})
.to('.box1', 1, {
opacity: 0
})
const tl2 = gsap.timeline()
tl2
.to('.box2', 1, {
y: 30,
})
.to('.box2', 1, {
opacity: 0
})
tl.add(tl2)// timeline連結(tl終了後にtl2が発火)
timelineのネスト
timelineを返した関数をgsap.timeline.add()
にコールバックとして渡すことで連結することができます。
// scene1を作成
function scene1(target) {
const tl = gsap.timeline()
tl
.to(target, 1, { y: 100 })
.to(target, 1, { x: 100 })
return tl // タイムラインを返す
}
// scene2を作成
function scene2(target) {
const tl2 = gsap.timeline()
tl2
.to(target, 1, { y: 0, })
.to(target, 1, { x: 0 })
return tl2 // タイムラインを返す
}
// scene3を作成
function scene3(target) {
const tl3 = gsap.timeline()
tl3
.to(target, 1, { y: -100 })
.to(target, 1, { x: -100 })
return tl3 // タイムラインを返す
}
// 親のタイムラインを作成
// scene1の後にscene2とscene3が同時に発火
const master = gsap.timeline()
.add(scene1('.box1'))
.add(scene2('.box2'))
.add(scene3('.box3'), '<') //scene2開始時に発火
コールバック
-
onStart
– アニメーション開始時の処理 -
onComplete
– アニメーション終了時の処理 -
onUpdate
– アニメーション開始から終了までの間、処理され続ける -
onRepeat
– リピートされたアニメーションの開始時の処理 -
onReverseComplete
– リバースされたアニメーションの終了時の処理
const tween = gsap.to('.box', 3, {
x: 300,
delay: 1,
onStart: () => {
// アニメーション開始時の処理
},
onComplete: () => {
// アニメーション終了時の処理
},
onUpdate: () => {
// アニメーション開始から終了までの間、処理され続ける
// progress()を使用してアニメーションの進捗状況を取得できる
// 進捗バーやローディングなどで使える
const progress = Math.floor(tween.progress() * 100)
document.getElementById('progress').textContent = `${progress}%`
},
onRepeat: () => {
// リピートされたアニメーションの開始時の処理
},
onReverseComplete: () => {
// リバースされたアニメーションの終了時の処理
}
})
Effects(アニメーションの登録)
よく使うアニメーションを登録して、呼び出すことができます。
gsap.registerEffect({
// 名前
name: 'fadeOut',
// デフォルト値
defaults: {
duration: 1,
delay: 1,
position: 30
},
// アニメーションの内容
effect: (targets, config) => {
return gsap.to(targets, {
opacity: 0,
ease: 'power2.out',
// デフォルトのオプションを使いつつ、変更可能のオプションを指定
y: config.position,
duration: config.duration,
delay: config.delay,
})
},
// timeline内で使う場合は以下を指定
extendTimeline: true
})
// エフェクトを呼び出す(timelineなし)
gsap.effects.fadeOut('.box')
// エフェクトを呼び出す(timelineあり)
const tl = gsap.timeline()
tl.to('.box', 1, {
y: -30
})
.fadeOut('.box', {
delay: 0
})
参考
Discussion