@vizij/animation-wasm
v0.3.7
Published
WASM bindings for Vizij animation core.
Maintainers
Readme
@vizij/animation-wasm
Vizij’s real-time animation engine for JavaScript and TypeScript.
This package ships the official WebAssembly build of vizij-animation-core together with a TypeScript-friendly wrapper, ABI guards, and sample assets. Use it to load Vizij animation clips, create players/instances, stream outputs, and bake derivative-friendly bundles without compiling Rust.
Table of Contents
Overview
- Compiled directly from Vizij’s animation runtime (
vizij-animation-core) viawasm-bindgen. - Includes a high-level
Engineclass, low-level bindings, TypeScript declarations, and ready-to-use fixtures. - Runs in browsers and Node;
init()chooses the correct loader and validates the ABI (abi_version() === 2). - Designed and maintained by the Vizij team—this npm package is the canonical distribution of the animation engine for JavaScript consumers.
Key Concepts
- StoredAnimation JSON – Normalised animation format with duration, tracks, and cubic-bezier transitions. Recommended for authoring and interchange.
- Engine – High-level API mirroring the Rust engine (load animations, create players, add instances, prebind targets, update values, bake clips).
- Players & Instances – Players track playback state; instances attach animations with weight/time-scale/start-offset controls.
- Outputs & Events –
updateValuesreturns per-targetValueJSONpayloads plus engine events (play/pause, keyframe hits, warnings). - Derivatives – Optional finite-difference derivatives are available at runtime and via
bakeAnimationWithDerivatives. - ABI Guard –
abi_version()ensures the JS glue and.wasmbinary stay in sync. Rebuild when versions diverge.
Installation
npm install @vizij/animation-wasm
# or pnpm add @vizij/animation-wasmFor local development inside the Vizij workspace:
pnpm run build:wasm:animation # regenerate pkg/
cd npm/@vizij/animation-wasm
pnpm install
pnpm run buildLink into vizij-web while iterating:
(cd npm/@vizij/animation-wasm && pnpm link --global)
(cd ../vizij-web && pnpm link @vizij/animation-wasm)Bundler Configuration
@vizij/animation-wasm now mirrors the import strategy used by the orchestrator and node-graph packages: it tries a static ESM import first, then falls back to a runtime URL when necessary. Ensure your bundler is configured to emit the .wasm file. For Webpack/Next.js:
// next.config.js
module.exports = {
webpack: (config) => {
config.experiments = { ...(config.experiments ?? {}), asyncWebAssembly: true };
config.module.rules.push({
test: /\.wasm$/,
type: "asset/resource",
});
return config;
},
};When serving the binary from a custom location, hand init() a string URL:
await init("https://cdn.example.com/vizij/vizij_animation_wasm_bg.wasm");String URLs keep Webpack’s helper from wrapping the value and calling .replace() on a URL object.
API
async function init(input?: InitInput): Promise<void>;
function abi_version(): number;
class Engine {
constructor(config?: Config);
loadAnimation(data: StoredAnimation | AnimationData, opts?: { format?: "stored" | "core" }): AnimId;
createPlayer(name: string): PlayerId;
addInstance(player: PlayerId, anim: AnimId, cfg?: InstanceCfg): InstId;
prebind(resolver: (path: string) => string | number | null | undefined): void;
updateValues(dtSeconds: number, inputs?: Inputs): Outputs;
updateValuesAndDerivatives(dtSeconds: number, inputs?: Inputs): OutputsWithDerivatives;
update(dtSeconds: number, inputs?: Inputs): Outputs; // alias for compatibility
bakeAnimation(anim: AnimId, cfg?: BakingConfig): BakedAnimationData;
bakeAnimationWithDerivatives(anim: AnimId, cfg?: BakingConfig): BakedAnimationBundle;
listPlayers(): PlayerInfo[];
listAnimations(): AnimationInfo[];
// …additional helpers mirroring vizij-animation-core
}
// Raw bindings (rarely needed directly)
class VizijAnimation { /* same surface but string/JSON based */ }All types (StoredAnimation, Inputs, Outputs, etc.) are exported from src/types.
Usage
import { init, Engine } from "@vizij/animation-wasm";
await init();
const engine = new Engine();
const animId = engine.loadAnimation(storedAnimationJson, { format: "stored" });
const player = engine.createPlayer("demo");
engine.addInstance(player, animId);
engine.prebind((path) => path); // map canonical target path to your handle
const outputs = engine.updateValues(1 / 60);
console.log(outputs.changes, outputs.events);
const withDerivatives = engine.updateValuesAndDerivatives(1 / 60);
console.log(withDerivatives.changes.map(({ key, derivative }) => ({ key, derivative })));
const baked = engine.bakeAnimationWithDerivatives(animId, { frame_rate: 60 });
console.log(baked.values.tracks.length, baked.derivatives.tracks.length);Low-level binding usage (when you want direct control over JSON serialisation):
import initWasm, { VizijAnimation } from "@vizij/animation-wasm/pkg";
await initWasm();
const raw = new VizijAnimation();
const animId = raw.load_stored_animation(JSON.stringify(storedAnimationJson));
const player = raw.create_player("demo");
raw.add_instance(player, animId, undefined);
const outputs = JSON.parse(raw.update_values(0.016, undefined));Custom loader options
init(input?: InitInput) accepts anything understood by @vizij/wasm-loader: URL, Response, ArrayBuffer, Uint8Array, or a precompiled WebAssembly.Module.
import { init } from "@vizij/animation-wasm";
import { readFile } from "node:fs/promises";
// CDN or edge deploy
await init(new URL("https://cdn.example.com/vizij/animation_wasm_bg.wasm"));
// Node / Electron / tests
const bytes = await readFile("dist/animation_wasm_bg.wasm");
await init(bytes);Provide your own loader when running inside service workers or sandboxed environments that restrict network access.
Fixtures
The package re-exports helpers from @vizij/test-fixtures:
import { loadAnimationFixture } from "@vizij/animation-wasm";
const stored = await loadAnimationFixture("pose-quat-transform");
engine.loadAnimation(stored, { format: "stored" });Fixtures are useful for smoke testing integrations or demoing the engine without writing your own assets.
Available fixture names (synchronised with vizij-test-fixtures):
| Fixture | Description |
|---------|-------------|
| pose-quat-transform | Transform animation showcasing translation + quaternion tracks. |
| vector-pose-combo | Mixed scalar/vector tracks for blending tests. |
| loop-window | Demonstrates loop windows and playback commands. |
Use listAnimationFixtures() to enumerate available fixtures at runtime.
Bundler Notes
- ESM entry (
dist/index.js) is optimised for modern bundlers; CJS (dist/index.cjs) supports Node-only tooling. - For Vite, add
optimizeDeps.exclude = ["@vizij/animation-wasm"]to avoid pre-bundling the wasm artefact. - Webpack >=5 handles wasm automatically. Enable
experiments.asyncWebAssembly = trueif you are on an older configuration. - The package delegates loading to
@vizij/wasm-loader, which memoises initialisation so multipleinit()calls reuse the same module.
Development & Testing
pnpm run build:wasm:animation # ensure pkg/ is fresh
cd npm/@vizij/animation-wasm
pnpm testThe Vitest suite checks ABI guards, StoredAnimation parsing, and parity with the native engine for common scenarios.
Related Packages
vizij-animation-wasm– Rust source of these bindings.vizij-animation-core– underlying engine logic.@vizij/animation-react– React provider built on this npm package.@vizij/value-json– canonical value helpers used internally.
Need help or spotted an inconsistency? Open an issue—reliable bindings keep animation workflows smooth. 🎥
