@zeroweight/renderer
v0.2.44
Published
Universal avatar rendering engine — use via CDN <script> tag or ES module import.
Maintainers
Readme
@zeroweight/renderer
Universal avatar rendering engine. Framework-agnostic — use via CDN <script> tag or ES module import.
Installation
CDN (Script Tag)
<script src="https://unpkg.com/@zeroweight/renderer/dist/zeroweight-renderer.umd.js"></script>Or via jsDelivr:
<script src="https://cdn.jsdelivr.net/npm/@zeroweight/renderer/dist/zeroweight-renderer.umd.js"></script>npm / yarn
npm install @zeroweight/rendererQuick Start
Via <script> tag
<canvas id="avatar" width="640" height="480"></canvas>
<script src="https://unpkg.com/@zeroweight/renderer/dist/zeroweight-renderer.umd.js"></script>
<script>
const { ZeroWeightRenderer, ActionQueue, VoiceActivityDetector } = window.ZeroWeightRenderer;
const renderer = new ZeroWeightRenderer();
const canvas = document.getElementById('avatar');
// Init with your avatar bundle payload
await renderer.init(canvas, { payload: bundleData });
// Play actions
renderer.play('speaking');
renderer.play('wave_hand', 'listening'); // oneshot with fallback
// Clean up
renderer.destroy();
</script>Via ES module
import {
ZeroWeightRenderer,
ActionQueue,
VoiceActivityDetector,
} from "@zeroweight/renderer";
const renderer = new ZeroWeightRenderer();
await renderer.init(canvas, { payload: bundleData });API
ZeroWeightRenderer
The core rendering engine. Handles WASM initialization, canvas setup, render loop, and action management.
const renderer = new ZeroWeightRenderer();init(canvas, config)
Initialize with a canvas element and bundle config.
await renderer.init(canvas, {
payload: bundleData, // required — avatar bundle from API
fullWidth: false, // optional — see Full-Width Mode below
scale: 1, // optional — override scale factor
forceMobile: false, // optional — override mobile detection
});Full-Width Mode — set fullWidth: true to scale the avatar so it covers the full canvas width, top-aligned. The bottom may be clipped on ratio mismatch (like CSS object-fit: cover with object-position: top). Default: false.
| Method | Description |
| --------------------------- | --------------------------------------------------------------------- |
| play(actionId, fallback?) | Play an action (e.g. "speaking", "wave_hand") |
| interrupt() | Interrupt the current action |
| onOneshotComplete(cb) | Subscribe to oneshot completion events; returns an unsubscribe fn |
| destroy() | Clean up all resources |
| Property | Description |
| ------------ | ---------------------------------------------------------------- |
| state | Current state: "idle" | "loading" | "ready" | "error" |
| isReady | true when engine is ready |
| dimensions | Avatar intrinsic { width, height } |
Events: ready, actionLoaded, allActionsLoaded, dimensions, oneshotComplete, error, stateChanged
renderer.on("ready", () => console.log("Engine ready!"));
renderer.on("dimensions", (w, h) => console.log(`Avatar: ${w}x${h}`));
const unsubscribe = renderer.onOneshotComplete((actionId) => {
console.log(`Oneshot finished: ${actionId}`);
});ActionQueue
Centralized action dispatch with turn-based queuing for speech synchronization.
const queue = new ActionQueue((actionId, fallback) => {
renderer.play(actionId, fallback);
});
queue.dispatch("wave_hand"); // Execute or queue
queue.setTurnActive(true); // Start speaking turn
queue.setSpeechState("speaking"); // Update speech state
queue.startVoiceActivityDetection(mediaStreamTrack); // Drive speech state from audio
queue.stopVoiceActivityDetection(); // Stop VAD + reset to listening
queue.forceListening(); // Reset to listeningVoiceActivityDetector
Amplitude-based VAD using Web Audio API with hysteresis for lipsync.
const vad = new VoiceActivityDetector({
threshold: 0.008,
speechStartFrames: 1,
speechPauseFrames: 30,
turnEndFrames: 50,
});
queue.attachVoiceActivityDetector(vad);
vad.start(mediaStreamTrack);Usage Tiers
| Tier | What you get | Use case |
| ------------------ | ---------------------------------------------------------------------- | ------------------------ |
| Tier 1 (Raw) | ZeroWeightRenderer only | Custom engine control |
| Tier 2 (Queue) | + ActionQueue + VoiceActivityDetector | Speech-synced avatars |
| Tier 3 (React) | @zeroweight/react | Drop-in React components |
Build from Source
git clone <repo-url>
cd zeroweight-renderer
npm install
npm run buildOutput in dist/:
zeroweight-renderer.umd.js— UMD bundle (script tag)zeroweight-renderer.es.js— ES moduleindex.d.ts— TypeScript declarations
Deploy
npm publish --access publicLicense
MIT
