gsap-frameworks について
Vue、SvelteなどのコンポーネントフレームワークでGSAPアニメーションを作成・レビューするためのスキルです。ライフサイクルに沿った初期化、セレクターのスコープ、クリーンアップを扱い、Reactには別のgsap-reactスキルを案内します。
主な機能
- 01ライフサイクルに沿ったアニメーション作成
- 02gsap.context()によるセレクターのスコープ設定
- 03ctx.revert()によるアニメーションのクリーンアップ
- 04ScrollTriggerのライフサイクル指針
- 05VueとSvelteの例
活用シーン
- 01VueコンポーネントへのGSAPアニメーション追加
- 02Svelteコンポーネント内のアニメーション管理
- 03他のコンポーネントへのセレクター干渉防止
- 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 スキルを参照してください。