taste-gsap について
taste-gsapは、GSAPアニメーションを実装するコーディングエージェント向けのスキルです。アクセシブルなモーション、スクロール演出、性能、クリーンアップの指針を示します。
主な機能
- 01gsap.contextによるアニメーション範囲の限定
- 02matchMediaによるモーション制御
- 03ピン留め区間の制限と構成
- 04変形と透明度を優先したアニメーション
- 05静的表示とモーション低減時の代替
活用シーン
- 01GSAPのスクロール連動区間の設計
- 02モーション低減設定への対応
- 03ピン留めとスクラブ動作の確認
- 04アニメーションのレイアウト性能維持
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ madebymustafa/ design-taste --skill taste-gsapインストール後、Claude Code で/taste-gsapを入力して読み込まれたか確認します。
詳細
taste-gsap
GSAP はメスであり、ラメをまき散らす銃ではありません。きちんとピン留めしたセクションが1つあれば、パララックスレイヤーを9つ重ねるより効果的ですし、コードレビューにも耐えられます。
1. アーキテクチャ(譲れない基本構造)
- 各ページのアニメーションはすべて、単一の
gsap.context(() => { ... }, rootElement)で囲みます。セレクターのスコープを限定でき、すぐにクリーンアップできます。 - すべてを
gsap.matchMedia()で制御します。(prefers-reduced-motion: no-preference)— すべてのアニメーションはここに配置します。視差効果を抑える設定のユーザーには、静的で完全なページを表示します。(min-width: 768px)— 重いエフェクト(ピン留め、スクラブ、文字単位の分割)はデスクトップ専用にし、小さい画面ではフェードかアニメーションなしにします。
- matchMedia のコールバックはクリーンアップ関数を返します。SPA では、アンマウント時に
ctx.revert()を呼び出します。 - セクションごとにタイムラインを1つ作成し、セクション名を付けます。40個のトゥイーンを持つ巨大なグローバルタイムラインは作りません。
- Lenis(ScrollSmoother ではなく無料版):
new Lenis({ duration: ~1.1, anchors: true })を使い、lenis.on("scroll", ScrollTrigger.update)+gsap.ticker.add(t => lenis.raf(t * 1000))+gsap.ticker.lagSmoothing(0)で ScrollTrigger に接続します。プリローダー表示中はlenis.stop()を呼び、表示後にlenis.start()を呼びます。視差効果を抑える設定では、スムーススクロールを有効にしません。
2. ピン留めとスクラブの衛生管理(エージェントが最も派手に失敗するところ)
- 1ページあたり、ピン留めするセクションは最大2つです。 ピン留めするたびにスクロールスレッドに負荷がかかります。上限は2つですが、通常は1つです。
- ピン留めには
pin: true, pinSpacing: true(デフォルト。変更しない)、start: "top top"、end: "+=200%"から"+=300%"を指定します。終了位置が遠いほどスクラブが遅くなり、モバイルでカクつきやすくなります。 - 横スクロールギャラリー(Awwwards の定番手法):セクションをピン留めし、トラックを移動させます(
xのみを使い、leftは使いません)。end: () => "+=" + (track.scrollWidth - innerWidth)として、リサイズ時に距離を再計算します。scrub: 1を設定し、デスクトップ専用にします。JS 無効時や視差効果を抑える設定時のフォールバックとして、ネイティブのoverflow-x+ scroll-snap を必ず残します。 - ドラッグ式カルーセル(Magma-school):
Draggable.create(track, { type: "x", inertia: true, bounds: () => ({ minX: -(track.scrollWidth - wrap.offsetWidth), maxX: 0 }) })を使います。リサイズ時に再調整できるよう、bounds は関数にします。edgeResistanceは約0.9に設定し、JS 無効時のフォールバックとしてネイティブのoverflow-x+ snap を使います。また、ストリップをドラッグできることを示すカーソルや UI のヒントを付けます。 - 重いセクションでは
scrub: 0.6~1を使います。scrub: trueは単純なトゥイーンに限ります。スムージングのないスクラブ付きトゥイーンはスクロールと競合します。 - ピン留めの中に別のピン留めを配置しません。最初のピン留めのスペーサーが終わる前に、2つ目のピン留めを開始しません。フォントや画像の読み込み後(
window.load+document.fonts.ready)にScrollTrigger.refresh()を呼び出します。呼び出さないと、すべての位置がずれます。 - リリース前に幅768pxでピン留めをテストします。モバイルユーザーのスクロールを妨げるピン留めセクションは、機能ではなくバグです(そのため、ピン留めは
(min-width: 768px)の条件内に配置します)。 - レイアウトの再計算で位置がずれないよう、再計算に依存するトリガーには
invalidateOnRefresh: trueを設定します。
3. アニメーションの対象(transform と opacity のみ)
x、y、scale、rotation、opacityをアニメーションさせます。top/left/width/height/margin/filterは使いません(レイアウトの再計算はカクつきの原因です)。- テキストの表示には、デフォルトで行単位の分割を使います(
overflow: hiddenのラッパー +yPercent: 110→ 0)。文字単位の分割はヒーローの見出しに限り、デスクトップ条件内でのみ使います。 will-changeをむやみに使いません。アニメーション中は対象要素のラッパーに設定し、終了後に削除します(または GSAP に管理させます)。will-changeを設定するたびに、メモリを消費します。- 60fps を守ります。1フレーム内で200要素をスタッガーさせたり、40個の DOM プロパティをスクラブしたりしません。
gsap.utils.toArrayとスタッガーを使ってまとめます。1つのトゥイーンで多数の対象を処理すれば、負荷を抑えられます。
4. リビールのパターン(プロが標準とする設定)
- 表示状態はCSSではなくコードで維持します: 要素はCSSで表示された状態にしておきます。
gsap.from(...)をmatchMediaゲート内でimmediateRender: trueとともに使うと、JSとモーションが有効な場合に限り要素が非表示になります。GSAPが読み込まれなくてもページは完成した状態です。これが安全性の契約です。 - 標準的なリビール:
opacity: 0, y: 40, duration: 0.9, ease: "power3.out"、トリガーはtop 82%、コンテンツセクションではonce: trueにします。 - ヒーローのイントロ:読み込み時に
gsap.timeline()を使い、要素間に80~120msのスタガーを設定します。ease: "expo.out"またはpower4.outを使い、合計時間は1.4秒未満にします。ページはスライドショーではなく、冒頭の一文から始まる物語です。 - カウントアップ:プロキシオブジェクトをトゥイーンし(
gsap.to(obj, { v: target }))、onUpdateでel.textContentを書き換えます。snapは任意です。トリガーにはonce: trueを設定します。
5. 禁忌の総覧(どれも失格です)
- スムーズスクロールレイヤー(Lenis)なしでホイール操作をスクロールジャックし、そのうえテストもしないこと。ネイティブスクロールは機能です。
- コンテンツが存在する前にトリガーされるアニメーション(
ScrollTrigger.refresh()の呼び出し漏れ)。 - 視差を抑える設定のときに停止しない無限マーキー。JSだけでなく、
@media (prefers-reduced-motion: reduce)のCSSでも停止してください。 - 自動再生されるものすべて:ヒーロー動画、アコーディオン、入力なしで動くカルーセル。Awwwardsで評価されるのは、瞬間と瞬間の間の静けさです。
- 「すごさ」がアニメーション頼みのページ。静止画のスクリーンショットが退屈なら、そのアニメーションはデザインではなく化粧です。
6. チェックリスト(次の場合はアニメーションを不合格にする…)
-
gsap.contextとmatchMediaによる制御がない(視差を抑える設定のユーザーにもアニメーションが表示される)。 - ピン留めされたセクションが3つ以上ある、または768px未満でピン留めしている。
- アニメーション対象のレイアウトプロパティ(
top/left/width/height)がある。 - フォントや画像の読み込み後に
ScrollTrigger.refresh()を呼び出していない。 - 文字単位の分割がデスクトップ用ゲートの外にある。
- マーキーや自動再生に、視差を抑える設定で停止する仕組みがない。
- 静止フレーム(JSなし)で、ページが完成していて美しくない。
- アニメーションに存在意義がない。すべての動きが物語に役立つか、さもなければ削除してください。
コメント
Markdown 対応