agentsclimarketplace

Gsap canvas

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

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.From its SKILL.md

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.

SKILL.md

4.8 KB, ~1.2k tokens by cl100k_base, 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)

What ships with it: 1 file

14.6 KB alongside SKILL.md

references/

Keep looking

Skills are one crate of 325,949. 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.