JavaScript Library
The Lotio JavaScript library provides a WebAssembly-based interface for rendering Lottie animations in the browser.
Installation
npm
npm install lotio
The package is published to the public npm registry and does not require any special configuration or authentication.
Note: Lotio is a pure ES Module (ESM). It does not support CommonJS (CJS) or AMD. Use ES6 import syntax in your code.
Quick Start
import Lotio, { State, TextMeasurementMode } from 'lotio';
// Load font
const fontResponse = await fetch('./fonts/OpenSans-Bold.ttf');
const fontData = new Uint8Array(await fontResponse.arrayBuffer());
// Load animation
const animationResponse = await fetch('./animation.json');
const animationData = await animationResponse.json();
// Create animation
const animation = new Lotio({
fonts: [{ name: 'OpenSans-Bold', data: fontData }],
fps: 30,
animation: animationData,
wasmPath: './lotio.wasm'
});
// Event handlers
animation
.on('loaded', (anim) => anim.start())
.on('frame', () => {
animation.renderToCanvas(canvas);
});
Interactive Demo
API Reference
Constructor
new Lotio(options)
Options:
- fonts (Array): Font files to load. Each font should have { name: string, data: Uint8Array }
- fps (number): Frames per second (default: 30)
- animation (Object|string): Lottie animation JSON (object or stringified)
- layerOverrides (Object|string, optional): Layer overrides JSON (for text and image overrides)
- Can be a JavaScript object or JSON string
- Supports textLayers and imageLayers sections
- Text layer visibility: Overridden text layers must be visible in the Lottie composition. When tp is omitted in the Lottie JSON, lotio's Skottie build uses a track-matte patch (matte source = nearest prior layer with td !== 0, Bodymovin behavior); comps like sample5 typically render correctly. See CLI docs "Text layer visibility requirements" for full details.
- Image Layers: In browser/WebAssembly context, imageLayers supports:
- Data URIs: "data:image/png;base64,..." (recommended for browser use) - use empty filePath and full path in fileName
- Relative paths: Resolved by your application before passing to Lotio
- URLs are NOT supported: HTTP (http://) and HTTPS (https://) URLs are not supported
- textPadding (number, optional): Text padding factor (0.0-1.0, default: 0.97 = 3% padding)
- textMeasurementMode (string, optional): Text measurement mode: 'fast' | 'accurate' | 'pixel-perfect' (default: 'accurate')
- wasmPath (string): Path to lotio.wasm file (default: './lotio.wasm')
Text Padding
The textPadding option controls how much of the target text box width is used for text sizing. A value of 0.97 means 97% of the target width is used, leaving 3% padding (1.5% per side). Lower values provide more padding, higher values allow text to use more of the available space.
Text Measurement Mode
The textMeasurementMode option controls the accuracy vs performance trade-off for measuring text width:
'fast': Fastest measurement using basic font metrics. Good for most cases but may underestimate width for some fonts.'accurate'(default): Good balance of accuracy and performance. Uses SkTextBlob bounds which accounts for kerning and glyph metrics. Recommended for most use cases.'pixel-perfect': Most accurate measurement by rendering text and scanning actual pixels. Accounts for anti-aliasing and subpixel rendering. Slower but most precise.
Methods
Control Methods
start()- Start animation playbackpause()- Pause animationstop()- Stop animation and reset to beginningseek(frameOrTime)- Seek to frame number or time (seconds)renderToCanvas(canvas, bgColor)- Render current frame to canvas
Setters (Fluent Interface)
setFps(fps)- Set frames per secondsetAnimation(animation)- Set animation datasetLayerOverrides(layerOverrides)- Set layer overridessetFonts(fonts)- Set fonts array
Getters
getTextPadding()- Get current text padding factor-
getTextMeasurementMode()- Get current text measurement mode -
getFps()- Get current FPS getAnimation()- Get animation datagetLayerOverrides()- Get layer overridesgetState()- Get current state ('stopped','paused','loaded','error','playing')getCurrentFrame()- Get current frame datagetAnimationInfo()- Get animation metadata (width, height, duration, fps)
Lifecycle
destroy()- Cleanup resources
Events
All event handlers support fluent interface chaining:
animation
.on('error', (error, animation) => { /* ... */ })
.on('loaded', (animation) => { /* ... */ })
.on('start', (animation) => { /* ... */ })
.on('pause', (animation) => { /* ... */ })
.on('stop', (animation) => { /* ... */ })
.on('end', (animation) => { /* ... */ })
.on('seek', (animation) => { /* ... */ })
.on('frame', (frameNumber, time, animation) => { /* ... */ })
.on('statechange', (newState, oldState, animation) => { /* ... */ });
Events:
- error - Emitted when an error occurs
- loaded - Emitted when animation is loaded
- start - Emitted when animation starts
- pause - Emitted when animation is paused
- stop - Emitted when animation stops
- end - Emitted when animation ends
- seek - Emitted when seeking to a different frame/time
- frame - Emitted on each frame during playback
- statechange - Emitted when state changes
- destroy - Emitted when animation is destroyed
Constants
State.STOPPED- Animation is stoppedState.PAUSED- Animation is pausedState.LOADED- Animation is loadedState.ERROR- Error stateState.PLAYING- Animation is playingTextMeasurementMode.FAST- Fast text measurement modeTextMeasurementMode.ACCURATE- Accurate text measurement mode (default)TextMeasurementMode.PIXEL_PERFECT- Pixel-perfect text measurement mode
Examples
Basic Usage
import Lotio from 'lotio';
const animation = new Lotio({
animation: animationData,
wasmPath: './lotio.wasm'
});
animation.on('loaded', () => {
animation.start();
});
animation.on('frame', () => {
animation.renderToCanvas(canvas);
});
With Fonts and Layer Overrides
// Convert image to data URI (recommended for browser)
async function imageToDataURI(url) {
const response = await fetch(url);
const blob = await response.blob();
return new Promise((resolve) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(blob);
});
}
const fontData = new Uint8Array(await fontResponse.arrayBuffer());
const imageDataURI = await imageToDataURI('./images/logo.png');
const animation = new Lotio({
fonts: [{ name: 'OpenSans-Bold', data: fontData }],
animation: animationData,
layerOverrides: {
textLayers: {
"Patient_Name": {
minSize: 20,
maxSize: 100,
textBoxWidth: 500,
value: "John Doe"
}
},
imageLayers: {
"image_0": {
filePath: "", // Empty for data URI
fileName: imageDataURI // Data URI (recommended for browser)
},
"image_1": {
filePath: "",
fileName: "data:image/png;base64,..." // Direct data URI
}
}
}
});
Note on Image Layers in Browser:
- Data URIs are recommended: Convert images to data URIs before passing to Lotio
- Use empty filePath and put the full data URI in fileName
- Relative paths: Must be resolved by your application (Lotio doesn't resolve file paths in browser context)
- URLs are NOT supported: HTTP/HTTPS URLs are not supported in imageLayers
With Custom Text Padding and Measurement Mode
import Lotio, { TextMeasurementMode } from 'lotio';
const animation = new Lotio({
animation: animationData,
layerOverrides: layerOverridesData,
textPadding: 0.95, // Use 95% of width (5% padding)
textMeasurementMode: TextMeasurementMode.PIXEL_PERFECT, // Most accurate measurement
wasmPath: './lotio.wasm'
});
Control Playback
// Start
animation.start();
// Pause
animation.pause();
// Stop and reset
animation.stop();
// Seek to frame 10
animation.seek(10);
// Seek to time 2.5 seconds
animation.seek(2.5);
// Change FPS
animation.setFps(60);
Get Frame Data
const frame = animation.getCurrentFrame();
console.log(frame.number); // Frame number
console.log(frame.time); // Time in seconds
console.log(frame.width); // Frame width
console.log(frame.height); // Frame height
console.log(frame.data); // RGBA pixel data (Uint8Array)
// Render to canvas
frame.renderToCanvas(canvas, '#ffffff');
Module Format
Lotio is distributed as a pure ES Module (ESM). It does not support:
- CommonJS (CJS) - require() is not supported
- AMD - AMD module format is not supported
- UMD - Universal Module Definition is not supported
Use ES6 import syntax:
import Lotio, { State, TextMeasurementMode } from 'lotio';
For bundlers like Vite, Webpack 5+, or Rollup, no special configuration is needed as they support ESM natively.
Browser Support
- Chrome/Edge 57+
- Firefox 52+
- Safari 11+
- Opera 44+
Requires:
- WebAssembly support
- ES Module support (all modern browsers)
See Also
- Overview - General information about Lotio
- CLI - Command-line usage
- C++ Library - C++ library usage