mcpField
G
gsap-frameworks

gsap-frameworks

github.com/calesthioデザイン・UI73.0k1.1k 回インストール1 日前に更新
リポジトリ

gsap-frameworks について

Vue、SvelteなどのコンポーネントフレームワークでGSAPアニメーションを作成・レビューするためのスキルです。ライフサイクルに沿った初期化、セレクターのスコープ、クリーンアップを扱い、Reactには別のgsap-reactスキルを案内します。

主な機能

  1. 01ライフサイクルに沿ったアニメーション作成
  2. 02gsap.context()によるセレクターのスコープ設定
  3. 03ctx.revert()によるアニメーションのクリーンアップ
  4. 04ScrollTriggerのライフサイクル指針
  5. 05VueとSvelteの例

活用シーン

  1. 01VueコンポーネントへのGSAPアニメーション追加
  2. 02Svelteコンポーネント内のアニメーション管理
  3. 03他のコンポーネントへのセレクター干渉防止
  4. 04コンポーネント破棄時のScrollTriggerクリーンアップ

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/calesthio/openmontage --skill gsap-frameworks

インストール後、Claude Code で/gsap-frameworksを入力して読み込まれたか確認します。

詳細

Vue、Svelte、その他のフレームワークで GSAP を使う

このスキルを使う場面

Vue(または Nuxt)、Svelte(または SvelteKit)、その他のライフサイクル(マウント/アンマウント)を使用するコンポーネントフレームワークで GSAP コードを作成またはレビューする場合に適用します。React では、gsap-react(useGSAP フック、gsap.context())を使用してください。

関連スキル: トゥイーンとタイムラインには gsap-core と gsap-timeline、スクロールベースのアニメーションには gsap-scrolltrigger、React には gsap-react を使用してください。

原則(すべてのフレームワーク)

  • トゥイーンと ScrollTrigger は、コンポーネントの DOM が利用可能になってから(例:onMounted、onMount)作成します。
  • デタッチされたノード上で処理が実行されたり、メモリーリークが発生したりしないよう、アンマウント(または同等の処理)のクリーンアップでトゥイーンと ScrollTrigger を停止または元に戻します。
  • セレクターの範囲をコンポーネントのルートに限定し、.box などがページ内のほかの場所ではなく、そのコンポーネント内の要素だけに一致するようにします。

Vue 3(Composition API)

onMounted を使って、コンポーネントが DOM に追加された後に GSAP を実行します。クリーンアップには onUnmounted を使います。

import { onMounted, onUnmounted, ref } from "vue";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger); // once per app, e.g. in main.js

export default {
  setup() {
    const container = ref(null);
    let ctx;

    onMounted(() => {
      if (!container.value) return;
      ctx = gsap.context(() => {
        gsap.to(".box", { x: 100, duration: 0.6 });
        gsap.from(".item", { autoAlpha: 0, y: 20, stagger: 0.1 });
      }, container.value);
    });

    onUnmounted(() => {
      ctx?.revert();
    });

    return { container };
  }
};
  • ✅ gsap.context(scope) — コンテナの ref(例:container.value)を第 2 引数として渡すと、.item などのセレクターの範囲がそのルートに限定されます。コールバック内で作成されたすべてのアニメーションと ScrollTrigger は追跡され、ctx.revert() の呼び出し時に元に戻されます。
  • ✅ onUnmounted — ctx.revert() を必ず呼び出し、トゥイーンと ScrollTrigger を停止して、インラインスタイルを元に戻します。

Vue 3(script setup)

<script setup> と ref を使う場合も、考え方は同じです。

<script setup>
import { onMounted, onUnmounted, ref } from "vue";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";

const container = ref(null);
let ctx;

onMounted(() => {
  if (!container.value) return;
  ctx = gsap.context(() => {
    gsap.to(".box", { x: 100 });
    gsap.from(".item", { autoAlpha: 0, stagger: 0.1 });
  }, container.value);
});

onUnmounted(() => {
  ctx?.revert();
});
</script>

<template>
  <div ref="container">
    <div class="box">Box</div>
    <div class="item">Item</div>
  </div>
</template>

Svelte

onMount を使って、DOM の準備ができてから GSAP を実行します。onMount から返すクリーンアップ関数を使うか、context を追跡してリアクティブブロックまたはコンポーネントの破棄時にクリーンアップし、元に戻します。Svelte 5 ではライフサイクルが異なりますが、原則は同じです。「マウント」時に作成し、「破棄」時に元に戻します。

<script>
  import { onMount } from "svelte";
  import { gsap } from "gsap";
  import { ScrollTrigger } from "gsap/ScrollTrigger";

  let container;

  onMount(() => {
    if (!container) return;
    const ctx = gsap.context(() => {
      gsap.to(".box", { x: 100 });
      gsap.from(".item", { autoAlpha: 0, stagger: 0.1 });
    }, container);
    return () => ctx.revert();
  });
</script>

<div bind:this={container}>
  <div class="box">Box</div>
  <div class="item">Item</div>
</div>
  • ✅ bind:this={container} — ルート要素への参照を取得し、gsap.context(scope) に渡せるようにします。
  • ✅ return () => ctx.revert() — Svelte の onMount はクリーンアップ関数を返せます。そこで ctx.revert() を呼び出すと、コンポーネントの破棄時にクリーンアップが実行されます。

セレクターのスコープ設定

現在のコンポーネントの外側にある要素にも一致するグローバルセレクターは使用しないでください。コールバック内で実行されるセレクターの範囲をそのサブツリーに限定するため、gsap.context(callback, scope) の第 2 引数には必ず scope(コンテナ要素または ref)を渡します。

  • ✅ gsap.context(() => { gsap.to(".box", ...) }, containerRef) — .box は containerRef 内だけを検索します。
  • ❌ コンポーネント内で context のスコープを指定せずに gsap.to(".box", ...) を実行すると、ほかのインスタンスやページ内のほかの要素に影響する可能性があります。

ScrollTrigger のクリーンアップ

トゥイーンまたはタイムラインの scrollTrigger 設定や ScrollTrigger.create() を使うと、ScrollTrigger インスタンスが作成されます。これらは gsap.context() に含まれており、ctx.revert() を呼び出すと元に戻されます。そのため、以下のようにします。

  • トゥイーンに使うものと同じ gsap.context() コールバック内で ScrollTrigger を作成します。
  • トリガー位置に影響するレイアウト変更(例:データ読み込み後)があった場合は、ScrollTrigger.refresh() を呼び出します。Vue/Svelte では、DOM の更新後(例:Vue の nextTick、Svelte の tick、または非同期コンテンツの読み込み後)に呼び出すことがよくあります。

作成と停止のタイミング

ライフサイクル操作
マウントgsap.context(scope) 内でトゥイーンと ScrollTrigger を作成します。
アンマウント/破棄ctx.revert() を呼び出し、その context 内のすべてのアニメーションと ScrollTrigger を停止して、インラインスタイルを元に戻します。

ルート要素が存在する前に実行されるコンポーネントのセットアップや同期的なトップレベルスクリプト内では、GSAP アニメーションを作成しないでください。コンテナの ref が DOM に追加されるよう、onMounted/onMount(または同等の処理)を待ってください。

避けること

  • ❌ コンポーネントがマウントされる前にトゥイーンや ScrollTrigger を作成しないでください(例:onMounted を使わずに setup で作成するなど)。DOM ノードがまだ存在しない可能性があります。
  • ❌ スコープなしでセレクター文字列を使用しないでください(gsap.context() の第 2 引数としてコンテナを渡してください)。これにより、セレクターがコンポーネント外の要素に一致するのを防げます。
  • ❌ クリーンアップを省略しないでください。コンポーネントの破棄時にアニメーションと ScrollTrigger が停止されるよう、onUnmounted / onMount の return で必ず ctx.revert() を呼び出してください。
  • ❌ レンダリングのたびに実行されるコンポーネント本体内でプラグインを登録しないでください(問題は起きませんが、無駄です)。アプリレベルで一度だけ登録してください。
詳細はこちら
  • React 固有のパターン(useGSAP、contextSafe)については、gsap-react スキルを参照してください。

コメント