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

Loading WASM module...

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:

Methods

Control Methods

Setters (Fluent Interface)

Getters

Lifecycle

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

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

Requires:
- WebAssembly support
- ES Module support (all modern browsers)

See Also