@clayzo/canvaskit-player
The full-fidelity Clayzo player. CanvasKit — Skia compiled to WASM, the same build the video export runs — so it draws everything the engine can express.
npm i @clayzo/canvaskit-player
import { createPlayer } from '@clayzo/canvaskit-player';
const player = await createPlayer({ canvas, document });
player.play();
Same call as @clayzo/webgl-player, so swapping is one word in an import.
React and Next clients can use the optional client entrypoint:
import { ClayzoPlayer } from '@clayzo/canvaskit-player/react';
export function Hero() {
return <ClayzoPlayer document={document} poster="/hero.poster.webp" posterTick={240} label="A cube folding into the logo" />;
}
It takes the same poster, posterTick, autoplay, reducedMotion, label, decorative and fallback props as @clayzo/webgl-player/react, and loads the player only as it comes near the viewport.
~2,535 KB brotli, most of it Skia. If that is affordable, this is the renderer to reach for: it is correct by construction, and what a viewer sees cannot drift from what an export produces, because they are the same code.
Where Skia comes from
Unlike the light renderer, an 8 MB binary cannot be baked into the bundle — base64 would be 10 MB of JavaScript to parse before the first frame. It is fetched instead, from a version-pinned CDN by default:
https://unpkg.com/[email protected]/bin/full
Pinned to an exact version deliberately. This renderer is written against that build's behaviour, and a CDN quietly serving a newer Skia is a fidelity change nobody asked for.
To self-host — behind a firewall, under a strict CSP, or simply not wanting a third-party dependency in your critical path:
npm i -D [email protected]
cp node_modules/canvaskit-wasm/bin/full/canvaskit.{js,wasm} public/canvaskit/
await createPlayer({ canvas, document, canvasKitUrl: '/canvaskit' });
Both files are required, and the full build specifically: Skottie ships only there, and documents with Lottie nodes need it.
Fonts
await createPlayer({
canvas,
document,
onPrewarm: (result) => {
if (result.unresolvedFamilies.length > 0) {
console.warn('no font for:', result.unresolvedFamilies.join(', '));
}
},
});
Worth wiring up. A font no loader could supply does not throw and does not
substitute — the text runs relying on it draw nothing at all. onPrewarm is
the difference between catching that in development and shipping a blank
headline.
Choosing between the two renderers
See @clayzo/animation's docs/renderers.md. Use this one when you
cannot enumerate the documents in advance — a design tool, an editor preview, a
gallery of user-authored work — or when @clayzo/webgl-player's checkCoverage says
a document needs it.