agentsclimarketplace

Gsap canvas

Skill iotron/gsap-cookbook/skills/gsap-canvas

Production recipes for premium GSAP animations — scroll, text, SVG, cursor, canvas, and visual effects. Claude Code plugin.

Install
npx -y skills add iotron/gsap-cookbook --skill gsap-canvas

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Production recipes for GSAP animations rendered to HTML5 Canvas. Companion to official gsap-core and gsap-timeline skills (API reference). Triggers: canvas animation, GSAP canvas, particle system, canvas particles, canvas rendering, onUpdate canvas, draw loop, sprite animation, canvas timeline, canvas GSAP, canvas morph, MorphSVG canvas, shape morphing canvas. Non-triggers: Not for DOM-based animation (use gsap-animate), not for SVG DOM morphing (use gsap-svg), not for WebGL/Three.js. Outcome: Produces canvas-based animations using GSAP timelines with custom onUpdate rendering pipelines, particle systems, and resize handling.

SKILL.md

4.8 KB, as published. Nobody here has run it

GSAP Canvas — Rendering Patterns

Flow: gsap-setup → gsap-canvas → gsap-optimise → gsap-test

Companion: For GSAP core API reference, invoke gsap-core. For timeline sequencing, invoke gsap-timeline. This skill covers canvas rendering recipes only. Requires: greensock/gsap-skills


1. The Pattern

Canvas animation with GSAP is fundamentally different from DOM animation. GSAP never touches a DOM element directly. Instead:

  1. Create plain JS objects with numeric properties (x, y, scale, rotation, alpha).
  2. Animate those objects with a GSAP timeline or tween — GSAP interpolates the numbers.
  3. Attach an onUpdate callback to the timeline that reads the current object values and draws them to canvas using the Canvas 2D API.
Plain objects  →  GSAP tweens numbers  →  onUpdate draws to canvas
     ↑                                          ↓
  { x, y, scale }                      ctx.drawImage(img, x, y, w*scale, h*scale)

This means GSAP handles easing, stagger, repeat, yoyo, and timeline sequencing — while you own the rendering pipeline entirely.

// 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. Particle System Recipe

Animate an array of particles with sprite images orbiting inward. GSAP handles all motion; onUpdate redraws every frame.

Setup particle array

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`,
  }),
}))

Build the timeline

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

The draw function

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. Controls & Resize

Play/pause toggle via timeScale

canvas.addEventListener('pointerup', () => {
  gsap.to(tl, {
    timeScale: tl.isActive() ? 0 : 1, // smooth ease to pause/play
  })
})

Resize handler with 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() forces GSAP to re-evaluate function-based values (the trig calculations) using updated dimensions.


4. Performance Tips

TipWhy
Use gsap.ticker.add(fn) for render loopsSyncs with GSAP's internal rAF — one frame budget, no double-paints
Minimize state changesBatch translate/rotate calls; call resetTransform() once per particle
Sort sparinglyparticles.sort() every frame is O(n log n) — skip if z-order is fixed
Use will-change: transform on the <canvas>Promotes to GPU layer, reduces compositing cost
Prefer ctx.resetTransform() over save/restoreFaster — avoids stack push/pop overhead
Pre-render to offscreen canvasFor static sprites, draw once to OffscreenCanvas, then drawImage from it

References

  • references/canvas-patterns.md — Full implementations: particle orbit system, canvas morphs (MorphSVG rendered to canvas)

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.