mcpField
G
gsap-canvas

gsap-canvas

github.com/iotronデザイン・UI938 回インストール31 週間前に更新
リポジトリ

gsap-canvas について

gsap-canvas は、GSAP のアニメーションを Canvas に描画するフロントエンド開発者向けスキルです。通常の JavaScript オブジェクトをアニメーションさせ、Canvas 2D API で描画する方法を、粒子、操作、リサイズ、性能の例とともに説明します。

主な機能

  1. 01GSAP によるオブジェクトアニメーションと描画
  2. 02粒子システムのレシピ
  3. 03再生・一時停止の操作
  4. 04Canvas のリサイズ処理
  5. 05描画性能のヒント

活用シーン

  1. 01Canvas の粒子アニメーション作成
  2. 02GSAP アニメーションの Canvas 描画
  3. 03Canvas シーンへの再生操作の追加
  4. 04フレームごとの描画処理の最適化

インストール

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

$npx skills add https://github.com/iotron/gsap-cookbook --skill gsap-canvas

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

同梱ファイルreferences/canvas-patterns.md

詳細

GSAP Canvas — レンダリングパターン

フロー:gsap-setup → gsap-canvas → gsap-optimise → gsap-test

関連スキル:GSAP コア API のリファレンスについては、gsap-core を呼び出してください。タイムラインのシーケンスについては、gsap-timeline を呼び出してください。このスキルでは、canvas のレンダリングレシピのみを扱います。必要なもの:greensock/gsap-skills


1. パターン

GSAP による canvas アニメーションは、DOM アニメーションとは根本的に異なります。GSAP が DOM 要素に直接触れることはありません。代わりに、次のようにします。

  1. 数値プロパティ(x、y、scale、rotation、alpha)を持つプレーンな JS オブジェクトを作成します。
  2. GSAP のタイムラインまたはトゥイーンでオブジェクトをアニメーションさせ、GSAP に数値を補間させます。
  3. タイムラインに onUpdate コールバックを設定し、現在のオブジェクトの値を読み取って、Canvas 2D API を使用して canvas に描画します。
Plain objects  →  GSAP tweens numbers  →  onUpdate draws to canvas
     ↑                                          ↓
  { x, y, scale }                      ctx.drawImage(img, x, y, w*scale, h*scale)

つまり、イージング、スタガー、リピート、ヨーヨー、タイムラインのシーケンスは GSAP が処理し、レンダリングパイプライン全体は自分で管理します。

// Minimal example: animate a circle across canvas
const dot = { x: 0, y: 250, radius: 20 }

gsap.to(dot, {
  x: 800, duration: 2, ease: 'power2.inOut',
  onUpdate() {
    ctx.clearRect(0, 0, cw, ch)
    ctx.beginPath()
    ctx.arc(dot.x, dot.y, dot.radius, 0, Math.PI * 2)
    ctx.fill()
  },
})

2. パーティクルシステムのレシピ

スプライト画像を使ったパーティクルの配列を、内側に向かって旋回するようにアニメーションさせます。すべての動きを GSAP が処理し、onUpdate で毎フレーム再描画します。

パーティクル配列をセットアップする
const particles = Array.from({ length: 99 }, (_, i) => ({
  x: 0, y: 0, scale: 0, rotate: 0,
  img: Object.assign(new Image(), {
    src: `https://assets.codepen.io/16327/flair-${2 + (i % 21)}.png`,
  }),
}))
タイムラインを構築する
const radius = Math.max(cw, ch)

const tl = gsap.timeline({ onUpdate: draw })
  .fromTo(particles, {
    x: (i) => {
      const angle = (i / particles.length) * Math.PI * 2 - Math.PI / 2
      return Math.cos(angle * 10) * radius
    },
    y: (i) => {
      const angle = (i / particles.length) * Math.PI * 2 - Math.PI / 2
      return Math.sin(angle * 10) * radius
    },
    scale: 1.1,
    rotate: 0,
  }, {
    duration: 5, ease: 'sine',
    x: 0, y: 0, scale: 0, rotate: -3,
    stagger: { each: -0.05, repeat: -1 },
  }, 0)
  .seek(99) // jump ahead so repeating stagger is mid-flow
描画関数
function draw() {
  particles.sort((a, b) => a.scale - b.scale) // z-sort by scale
  ctx.clearRect(0, 0, cw, ch)
  particles.forEach((p) => {
    ctx.translate(cw / 2, ch / 2)
    ctx.rotate(p.rotate)
    ctx.drawImage(p.img, p.x, p.y, p.img.width * p.scale, p.img.height * p.scale)
    ctx.resetTransform()
  })
}

3. コントロールとリサイズ

timeScale による再生/一時停止の切り替え
canvas.addEventListener('pointerup', () => {
  gsap.to(tl, {
    timeScale: tl.isActive() ? 0 : 1, // smooth ease to pause/play
  })
})
invalidate を使ったリサイズハンドラー
window.addEventListener('resize', () => {
  cw = canvas.width = innerWidth
  ch = canvas.height = innerHeight
  radius = Math.max(cw, ch)
  tl.invalidate() // recalculates functional from-values on next render
})

invalidate() は、更新された寸法を使って、関数ベースの値(三角関数の計算)を GSAP に再評価させます。


4. パフォーマンスのヒント

ヒント理由
レンダリングループには gsap.ticker.add(fn) を使うGSAP の内部 rAF と同期するため、フレームの予算を一度だけ使い、二重描画を防げます
状態変更を最小限にするtranslate/rotate の呼び出しをまとめ、パーティクルごとに resetTransform() を一度だけ呼び出します
ソートは控えめにする毎フレームの particles.sort() は O(n log n) です。z 順が固定なら省略します
<canvas> に will-change: transform を指定するGPU レイヤーに昇格させ、合成コストを削減します
save/restore より ctx.resetTransform() を優先するスタックへの push/pop のオーバーヘッドがなく、より高速です
オフスクリーン canvas に事前描画する静的なスプライトの場合は、OffscreenCanvas に一度描画し、その後はそこから drawImage します

参考資料

  • references/canvas-patterns.md — 完全な実装:パーティクルの旋回システム、canvas モーフ(MorphSVG を canvas にレンダリング)

コメント