# Canvas Generative

Algorithmic and generative art with Canvas 2D - particles, flow fields, noise...

- Repository: https://github.com/AThevon/genjutsu (721 stars)
- Category: Engineering
- License: see repository
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add AThevon/genjutsu --skill canvas-generative -g -a claude-code -y`
Codex: `npx skills add AThevon/genjutsu --skill canvas-generative -g -a codex -y`
Cursor: `npx skills add AThevon/genjutsu --skill canvas-generative -g -a cursor -y`
Gemini CLI: `npx skills add AThevon/genjutsu --skill canvas-generative -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add AThevon/genjutsu`

## Description

Algorithmic and generative art with Canvas 2D - particles, flow fields, noise, fractals, L-systems.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

> **Version-sensitive.** Every API name, SDK gate and browser-support claim below was
> verified on **2026-09-08** against primary sources. What against, and when, is in
> `_jutsu/VERSIONS.md`. If that date is old, re-verify before acting on a version number.

# Canvas Generative

> Algorithmic and generative art with Canvas 2D.
> Concise rules here. Deep-dive and reference implementations in `references/`.

---

## Canvas 2D Setup

### DPR-Aware Sizing

Every canvas must be sharp on Retina/HiDPI displays. Set the buffer size to the physical pixel size, scale down with CSS.

```js
function setupCanvas(canvas, width, height) {
  const dpr = window.devicePixelRatio || 1;
  canvas.width = width * dpr;
  canvas.height = height * dpr;
  canvas.style.width = `${width}px`;
  canvas.style.height = `${height}px`;
  const ctx = canvas.getContext('2d');
  ctx.scale(dpr, dpr);
  return ctx;
}
```

### Resize Handler

```js
function handleResize(canvas, ctx, draw) {
  const ro = new ResizeObserver(([entry]) => {
    const { width, height } = entry.contentRect;
    const dpr = window.devicePixelRatio || 1;
    canvas.width = width * dpr;
    canvas.height = height * dpr;
    ctx.scale(dpr, dpr);
    draw(); // re-render after resize
  });
  ro.observe(canvas.parentElement);
  return () => ro.disconnect();
}
```

### Animation Loop (RAF)

```js
let animId;
let prevTime = 0;

function loop(time) {
  const dt = Math.min((time - prevTime) / 1000, 0.1); // cap delta to avoid spiral of death
  prevTime = time;

  update(dt);
  render(ctx);

  animId = requestAnimationFrame(loop);
}

// Start
animId = requestAnimationFrame(loop);
// Stop
cancelAnimationFrame(animId);
```

---

## Noise

The rest: https://github.com/AThevon/genjutsu/blob/HEAD/skills/_jutsu/canvas-generative/SKILL.md
