@blinn-motion/canvas paints the very same resolved tree to a 2D <canvas> — one immediate-mode draw per frame, with zero DOM nodes for the animation itself. Reach for it when you want a single compositing surface (lots of moving layers, a background effect, a game-like loop).

Install

npm i @blinn-motion/canvas

Create a player

The call mirrors the DOM adapter exactly — same signature, same options, same control surface.
import { create } from "@blinn-motion/canvas";
import doc from "./card.motion.json";

const player = create(canvasHost, doc, { loop: true, autoplay: true });

player.play();
player.seekFraction(0.5);

When to choose Canvas over DOM

Choose Canvas

Many layers, a single surface, no per-node DOM cost, or you’re already drawing to a canvas.

Choose DOM

You need the widest paint fidelity — SVG vector paths, arrowheads, complex masks and shaders.
Both adapters call sample(doc, t) from the same core, so timing is identical. The only difference is the paint backend and which rarer effects each supports — see the fidelity matrix.