GSAP入門(第2回) - タイムライン

はてなブックマークへ投稿
33
Xへポスト
75
URLをコピー
共有

JavaScriptライブラリの「GSAPジーサップ」(ジーサップ)は、ウェブサイトのモーション制作に役立ちます。第1回では、GSAPの基本的な使い方を解説しました。

第2回となる本記事では、タイムラインによる演出を紹介します。

タイムライン

タイムラインはGSAPで高度な演出をつくるうえで必ず利用する重要な機能です。

複雑なモーションを時系列で作成できるので、多くのトゥイーンを作成したり、管理するのに便利です。

▼公式サイトのチュートリアル動画。たった5行のコードで出現アニメーションを構築。

使い方として、gsap.timeline()で作成したインスタンスに対して、add()メソッドでタイムラインにgsap.to()のトゥイーンを追加します。

const tl = gsap.timeline({ repeat: -1, repeatDelay: 0.5 }); // はじめに初期化
// 続けて動かしたい要素を追加
tl.add(gsap.to(".rect", { x: 100, duration: 1 })); // 水平方向に移動
tl.add(gsap.to(".rect", { y: 100, duration: 1 })); // 垂直方向に移動
tl.add(gsap.to(".rect", { rotation: 360, duration: 1 })); // 回転
tl.add(gsap.to(".rect", { x: 0, duration: 1 })); // 水平方向に移動
tl.add(gsap.to(".rect", { y: 0, duration: 1 })); // 垂直方向に移動

タイムラインのto()メソッドはadd(gsap.to())のショートカットであるため、以下の記述でも利用できます。

const tl = gsap.timeline({ repeat: -1, repeatDelay: 0.5 }); // はじめに初期化
// 続けて動かしたい要素を追加
tl.to(".rect", { x: 100, duration: 1 }); // 水平方向に移動
tl.to(".rect", { y: 100, duration: 1 }); // 垂直方向に移動
tl.to(".rect", { rotation: 360, duration: 1 }); // 回転
tl.to(".rect", { x: 0, duration: 1 }); // 水平方向に移動
tl.to(".rect", { y: 0, duration: 1 }); // 垂直方向に移動

チェーンメソッドとして記述してもいいでしょう。いずれの記述も書き方が異なるだけで、実行結果に違いはありません。

gsap
  .timeline({ repeat: -1, repeatDelay: 0.5 }) // はじめに初期化
  // 続けて動かしたい要素を追加
  .to(".rect", { x: 100, duration: 1 }) // 水平方向に移動
  .to(".rect", { y: 100, duration: 1 }) // 垂直方向に移動
  .to(".rect", { rotation: 360, duration: 1 }) // 回転
  .to(".rect", { x: 0, duration: 1 }) // 水平方向に移動
  .to(".rect", { y: 0, duration: 1 }); // 垂直方向に移動

メソッド

タイムラインの作成で主に利用にするのは以下のメソッドです。

関数名 説明
add() トゥイーン、タイムライン、コールバック、ラベルをタイムラインに追加します。
to() gsap.to()トゥイーンをタイムラインの最後に追加します。
from() gsap.from() トゥイーンをタイムラインの最後に追加します。
fromTo() gsap.fromTo() トゥイーンをタイムラインの最後に追加します。
set() タイミングで値をセットします。
call() タイミングで関数を呼び出します。

時間指定

モーションは直列でつないでいくと台本的な動きになりがちです。滑らかに演出を見せるためには、モーションを重ねることが多いです。次の作例では、前半は台本的な動きとし、後半は重ねつつモーションさせています。

gsap
  .timeline({ repeat: -1, repeatDelay: 0.5 })
  // 🌟段取り的なうごき
  .set("h1", { textContent: "show" })
  .from(".rect1", { y: -32, opacity: 0, duration: 0.5 })
  .from(".rect2", { y: 32, opacity: 0, duration: 0.5 })
  .from(".rect3", { y: -32, opacity: 0, duration: 0.5 })
  .from(".rect4", { y: 32, opacity: 0, duration: 0.5 })
  .from(".rect5", { y: -32, opacity: 0, duration: 0.5 })
  .from(".rect6", { y: 32, opacity: 0, duration: 0.5 })
  // 🌟ここから重ねつつ動かしている
  .set("h1", { textContent: "hide" }, "+=1") // 1秒待機
  .to(".rect1", { y: -32, opacity: 0, duration: 0.5 }, "+=0.5") // 0.5秒待機
  .to(".rect2", { y: 32, opacity: 0, duration: 0.5 }, "-=0.4") // 0.4秒開始を早める
  .to(".rect3", { y: -32, opacity: 0, duration: 0.5 }, "-=0.4")
  .to(".rect4", { y: 32, opacity: 0, duration: 0.5 }, "-=0.4")
  .to(".rect5", { y: -32, opacity: 0, duration: 0.5 }, "-=0.4")
  .to(".rect6", { y: 32, opacity: 0, duration: 0.5 }, "-=0.4");

タイムラインのタイミングはto()from()メソッドの第3引数positionで指定可能です。

数値を指定すると、タイムラインの先頭からの絶対時間になります。"+=2"はタイムライン末尾の2秒後、"-=2"はタイムライン末尾の2秒前に配置します。

+=-=の直後にパーセンテージを指定すると、挿入するアニメーションの総時間が基準になります。たとえば"-=50%"は、挿入するアニメーションの総時間の50%だけタイムライン末尾に重ねます。直前に追加したアニメーションの50%の位置に配置する場合は、"<50%"と指定します。

時間指定で数値以外に指定できるもの

具体値 説明 頻出度
数値 1 タイムラインの先頭からの時間(秒)で開始
+=数値 +=1 タイムライン末尾の何秒後か
-=数値 -=1 タイムライン末尾の何秒前か
< < 直前に追加したアニメーションの開始時
<数値 <1 直前に追加したアニメーションの開始から何秒後か
> > 直前に追加したアニメーションの終了時
>数値 >1 直前に追加したアニメーションの終了から何秒後か

筆者としては「★」の習得をオススメします(それ以外は個人的にあまり使わないです)。

他にもさまざまな指定方法があるので、公式解説の『Timeline Tip: Understanding the Position Parameter - Learning Center - GreenSock』を参照ください。

ネスト

タイムラインはネスト(入れ子)も可能です。GSAPのタイムラインを作るとコードが長くなってしまいがちです。ネストを上手に使ってコードを整理するといいでしょう。

タイムラインをgsap.timeline.add()メソッドで、別のタイムラインインスタンスを追加します。

// タイムラインを作成する関数
function createChildTimeline(target) {
  const tl = gsap.timeline();
  tl.to(target, { x: 100, duration: 1 });
  return tl; // タイムラインを戻り値にする
}

// ルートのタイムラインを作成
const rootTl = gsap
  .timeline()
  .add(createChildTimeline(".a")) // 子どもを追加
  .add(createChildTimeline(".b")); // 子どもを追加

ここまでで、タイムラインの重要な機能はひととおり紹介しました。

高度な制御

ここからは中・上級者向けのタイムラインの機能を紹介します。必ず利用するものではないので、初級者はスキップして構いません。

seek()

GSAPのタイムラインはtimeline.seek()メソッドでシークできます。一般的な用語として「シーク」とは、再生中の動画の好きな場所に再生位置を動かす操作のことです。

次のサンプルでは、シークバーをinputタグで用意しています。シークバーを動かして、GSAPのタイムラインの時間を自由に行き来できることを確認ください。再生速度も変更できます。

※デモはVue.jsを使ってインタラクティブに作成しています。

時間に関するタイムラインのメソッドを紹介します。time()duration()progress()はいずれもゲッター(取得)・セッター(設定)の役割として用意されています。

関数名 説明
time() 再生ヘッドのローカル位置(基本的には現在時刻)を取得または設定します(リピートやrepeatDelayは含まれません)。
duration() タイムラインの時間(秒)を取得します。セッターとして使用された場合、指定されたデュレーション内に収まるようにタイムラインのtimeScaleを調整します。
progress() タイムラインの進行状況を取得・設定します。0から1までの値で、仮想再生ヘッドの位置を表します(0が最初、0.5が半分、1が完了)。
seek() 特定の時間にジャンプします。

tweenTo()

タイムラインの時間軸に対してトゥイーンを適用できます。tweenTo()メソッドを利用します。複数のオブジェクトを制御するようなタイムラインにおいて、演出の工夫として使ってもいいでしょう。

// 格子状に適用
const tl = gsap
  .timeline()
  .from(".rect", {
    scale: 0,
    rotation: -360,
    duration: 0.5,
    stagger: {
      each: 0.1,
      grid: "auto", // 格子状に開始
    },
  })
  .addLabel("complete"); // ラベルを追加

// 時間軸に対してトゥイーン
tl.tweenTo("complete", {
  duration: 4,
  // 時間軸に対してイージングを指定
  ease: "slow(0.4, 0.9, false)",
  // 注意:slow は EasePack プラグインの導入が必要
});
関数名 説明
addLabel() タイムラインにラベルを追加。重要な位置/時間を簡単にマークできます。
tweenTo() 再生ヘッドを特定の時間までスクラブし、その後停止するリニアトゥイーンを作成します。

timeScale()

タイムラインのtimeScale()メソッドを使うとタイムラインの再生時間を伸縮できます。タイムラインの伸縮を使えば、タイムラインの一部分だけスローモーションにできます。この演出の呼び方はいろいろあるのですが、私は「タイムリマップ」と呼んでいます。

タイムリマップ演出は当サイトの記事『GSAPを使ったタイムリマップ表現』で詳しく解説しています。

先ほど紹介したtweenTo()メソッドと演出が少し似ていますが、制御のアプローチが異なります。コードの書き方や演出のフレーバーが異なるので、好みで使い分けていいでしょう。

まとめ

タイムラインは複雑な演出を作るのに欠かせない機能です。

次の第3回では、ScrollTriggerを使ったスクロール演出を紹介します。複雑なスクロール演出では、複数のモーションをまとめるタイムラインが必要になります。

※この記事が公開されたのは3年前ですが、今月8月に内容をメンテナンスしています。

Google検索でICS MEDIAの記事を見つけやすくしよう

優先するソースに追加すると、GoogleのトップニュースやAI検索でICS MEDIAの記事が表示されやすくなります。

Googleで優先するソースとして追加
SNSでシェアしよう
シェアいただくと、サイト運営の励みになります!
はてなブックマークへ投稿
Xへポスト
URLをコピー
共有
池田 泰延

ICS代表。筑波大学 非常勤講師。ICS MEDIA編集長。個人実験サイト「ClockMaker Labs」のようなビジュアルプログラミングとUIデザインが得意分野です。

この担当の記事一覧