🗂

GSAP基本的な書き方集

2022/06/29に公開約6,900字

✖︎ こう書けばGSAPでリッチアニメーションが書けます!集
○ GSAPを動かす上で基本の部分となる記述集(これを読んで突然アニメーションがバリバリ書けるようにはならない)

偏差値でいえば45くらいの記事ですが、基本の部分なので割と大事かもしれません

/* アニメーション対象要素の初期値を設定 開始 */
gsap.set(".moveItem", { scale: 0 });
//初期状態としてtransform:scale(0);が適用される
//※「transform:」scale(0);の「transform:」が省略できる訳ではないので、GSAPが用意している変形プロパティのみ省略記述可能
 
/* アニメーション対象要素の初期値を設定 終了 */
 
/* アニメーション内容を記述 開始 */
gsap.to(".moveItem", {
  //同一トリガーで複数要素をアニメーションさせる場合は gsap.to(".moveItem1",".moveItem2" {
 
  /* アニメーション完了後の状態を記述 開始 */
  //cssに用意されている「プロパティ:値,」を記述してもOK(全てのプロパティはサポートしていない)
  x: 100, //x軸を100px移動
  y: -100, //y軸を-100px移動
  scale: 1, //transform:scale(1)
  duration: 2, //何秒かけてアニメーションを100%まで進めるか設定可能
  delay: 2, //何秒後にアニメーションを発火するか設定可能
  ease: "power1.out", // 用意されているイージング詳細は公式:https://greensock.com/docs/v3/Eases
 
  /* アニメーション完了後の状態を記述 終了 */
  scrollTrigger: {
    trigger: ".moveTrigger",
    //この要素が画面に入ったらgsap.toで記述した要素がアニメーションを開始する(トリガー設定)
    //pin:true,の場合はこの要素がendの数値スクロール分固定される
    start: "top top",
    //トリガー要素のどの部分が画面に入ったらアニメーションを発火するか設定
    //top top の場合はトリガー要素が画面に入ったら
    //top center の場合はトリガー要素が画面の中心に入ったら発火
    end: "+=900",
    //アニメーション終了位置を設定。この数値のスクロール量でアニメーションが 0% -> 100% に到達
    pin: true,
    //トリガー要素を固定する場合はtrue
    scrub: true,
    //スクロールとアニメーションを連動させる場合はtrue。数字をセットすることで◯秒遅れでスクロールと連動させる(慣性スクロール)
    markers: true,
    //デバッグ用マーカーを表示する場合はtrue(triggerの位置、アニメーション開始・終了位置を表示可能)
    once:true,
    //一度だけ実行したい場合に記述
  },
});
 
/* アニメーション内容を記述 終了 */
 
/* 1つのトリガーで複数の要素をアニメーションさせるがタイミングはずらす 開始 */
gsap.to(".moveItems", { //アニメーションさせたい複数の要素に付与されているclass名
  x: 100,
  scrollTrigger: {
    trigger: ".moveTrigger",
    start: "top top",
  },
  stagger: {
    from: "start", //start = 要素順にアニメーション。 start、center、edges、random、endで指定可能
    amount: 0.4, //0.4秒ずらしてアニメーション
  },
});
/* 1つのトリガーで複数の要素をアニメーションさせるがタイミングはずらす 終了 */
 
/* トリガーとアニメーションの対象要素が同一の場合 開始 */
ScrollTrigger.batch(".moveItems", {
  // トリガーを通過した場合
  onEnter: function (elem) {
    gsap.to(elem, { opacity: 1, y: 0 });
  },
  // トリガーを完全に通過した場合
  onLeave: function (elem) {
    gsap.to(elem, { opacity: 0, y: 0 });
  },
  // トリガーを完全に通過した後、通過した方向から再度トリガーを通過した場合
  onEnterBack: function (elem) {
    gsap.to(elem, { opacity: 1, y: 0 });
  },
  // トリガーを完全に通過した後、トリガーより上に戻って再度トリガーを通過した場合
  onLeaveBack: function (elem) {
    gsap.to(elem, { opacity: 0, y: 0 });
  },
  start: "top 50%",
});
/* トリガーとアニメーションの対象要素が同一の場合 終了 */
 
/* トリガー通過で対象要素にclassを追加 開始 */
ScrollTrigger.create({
  trigger: ".moveTrigger", //class付与のトリガーとなる要素
  start: "top center",
  end: "bottom center",
  toggleClass: { targets: ".moveItem1, .moveItem2", className: "is-show" },
  /*
  targets: classを付与したい要素を記述(複数可)
  className: 付与したいclassを記述
  */
  once: true, // 着脱を繰り返したくない場合(一度だけclass付与)
});
/* トリガー通過で対象要素にclassを追加 終了 */
 
/* アニメーションタイムラインを作成する 開始 */
const customAnimation = gsap.timeline({
  scrollTrigger: {
    trigger: ".moveTrigger",
    start: "top center",
  },
});
 
// トリガー到達時にアニメーションする1つ目の要素
customAnimation.to(
  ".moveItem1", //アニメーションする要素
  {
    keyframes: [
      { duration: 0.5, x: 100, y: 200 }, //このアニメーション完了後、下のアニメーションが発火
      { duration: 1, x: 0, y: 0 },
    ],
  }
);
 
// トリガー到達時にアニメーションする2つ目の要素
customAnimation.to(
  ".moveItem2", //アニメーションする要素
  {
    keyframes: [
      { duration: 0.5, x: -100, y: -200 }, //このアニメーション完了後、下のアニメーションが発火
      { duration: 1, x: 0, y: 0 },
    ],
  },
  "<"
  /*
    "<"   直前の要素と同じタイミングでアニメーション
    "2"   2秒後にアニメーション
    "+=1" 要素自身を基準に1秒後にアニメーション
    "-=3" 要素自身を基準に3秒前にアニメーション
    "<4"  直前の要素を基準に4秒後にアニメーション
    ">2"  直後の要素を基準に2秒後にアニメーション
  */
);
 
/* アニメーションタイムラインを作成する 終了 */
 
/* アニメーションタイムラインを作成する 開始 */
const customAnimation = gsap.timeline({
  repeat: -1, // アニメーションを繰り返す回数。-1で無限回
  repeatDelay: 0.6, // アニメーションループの間隔を設定
  // repeatとtoggleActionsは共存しない
 
  scrollTrigger: {
    trigger: ".moveTrigger",
    start: "top center",
    toggleActions: "play pause resume reset", // アニメーション開始位置、終了位置通過後の処理
    /*
    
    □ 指定可能なオプション
    play … アニメーションをスタートさせる
    pause … 一時停止
    resume … アニメーションを再開させる
    reset … アニメーション開始直前の状態に戻す
    restart … 始めに戻ってアニメーションを開始
    complete … アニメーション直後の状態にする
    reverse … アニメーションを逆再生する
    none … 何も指定しない
  
    □ 指定順
    onEnter onLeave onEnterBack onLeaveBack
  
    */
  },
});
 
// トリガー到達時にアニメーションする1つ目の要素
customAnimation.to(
  ".moveItem1", //アニメーションする要素
  {
    keyframes: [
      { duration: 0.5, x: 100, y: 200 }, //このアニメーション完了後、下のアニメーションが発火
      { duration: 1, x: 0, y: 0 },
    ],
  }
);
 
// トリガー到達時にアニメーションする2つ目の要素
customAnimation.to(
  ".moveItem2", //アニメーションする要素
  {
    keyframes: [
      { duration: 0.5, x: -100, y: -200 }, //このアニメーション完了後、下のアニメーションが発火
      { duration: 1, x: 0, y: 0 },
    ],
  },
  "<"
  /*
    "<"   直前の要素と同じタイミングでアニメーション
    "2"   2秒後にアニメーション
    "+=1" 要素自身を基準に1秒後にアニメーション
    "-=3" 要素自身を基準に3秒前にアニメーション
    "<4"  直前の要素を基準に4秒後にアニメーション
    ">2"  直後の要素を基準に2秒後にアニメーション
  */
);
 
/* アニメーションタイムラインを作成する 終了 */
 
/* イベントトリガーでアニメーションを発火させる 開始 */
// tweenを作成
const createTween = gsap.to(".moveItem2", {
  y: -100, //y軸を-100px移動
  paused: true, // アニメーションを停止状態に
});
 
// トリガーを設定
const trigger = document.querySelector(".moveItem1");
trigger.addEventListener("click", function () {
  // 作成した tweenを発火
  createTween.play();
  /*
  pause()...	  停止
  play()...	    再生(pause時はその場所から続きを再生)
  restart()...	最初から再生
  resume()...	  続きから再生
  reverse()...	逆再生
  */
});
 
/* イベントトリガーでアニメーションを発火させる 終了 */
 
 
/* 画面幅によってアニメーションを出し分ける 開始 */
ScrollTrigger.matchMedia({
  // 960px以上
  "(min-width: 960px)": function () {
    gsap.to(".moveItem", {
      autoAlpha: 1,
      x: 1000,
      scrollTrigger: {
        trigger: ".moveTrigger",
        start: "top center",
      },
    });
  },
 
  // 600px以上959px以下
  "(min-width: 600px) and (max-width: 959px)": function () {
    gsap.to(".moveItem", {
      autoAlpha: 1,
      x: 800,
      scrollTrigger: {
        trigger: ".moveTrigger",
        start: "top center",
      },
    });
  },
 
  // 599px以下
  "(max-width: 599px)": function () {
    gsap.to(".moveItem", {
      autoAlpha: 1,
      x: 300,
      scrollTrigger: {
        trigger: ".moveTrigger",
        start: "top center",
      },
    });
  },
 
  // メディアのサイズに関係なく、すべてに適用する
  all: function () {
    gsap.set(".moveItem", { autoAlpha: 0 });
  },
});
 
/* 画面幅によってアニメーションを出し分ける 終了 */
 
/* スクロール量をページ読み込み完了時に再計算 開始 */
window.addEventListener("load", function () {
  ScrollTrigger.refresh();
});
 
/* スクロール量をページ読み込み完了時に再計算 終了 */

/* タイムリマップ 開始 */
// タイムラインを作成
const tl = gsap.timeline({ repeat: -1 }); // 繰り返し回数を設定 -1で無限
// タイムラインにアニメーション内容を追加
tl.add(gsap.to(".remap", 2.0, { x: 800, rotate: 360 }));
// タイムラインの0.25秒の地点まで到達したら
tl.call(
  function () {
    // .timeScale()でアニメーション速度を、本来のスピードを1として乗算指定可能
    tl.timeScale(0.1);
  },
  null, // 引数なしの場合はnull
  0.25 // 指定したい秒数を記述
);
// タイムラインの0.50秒の地点まで到達したら
tl.call(
  function () {
    // .timeScale()でアニメーション速度を、本来のスピードを1として乗算指定可能
    tl.timeScale(1.0);
  },
  null, // 引数なしの場合はnull
  0.5 // 指定したい秒数を記述
);
/* タイムリマップ 終了 */

Discussion

ログインするとコメントできます