Angular runtime for the ExodeUI motion engine. Use <exodeui-canvas> to play interactive, physics-driven UI animation designed in ExodeUI inside standalone Angular components — with @Input/@Output bindings and a service for imperative control.
ExodeUI is an AI-native motion development environment (MDE): vector design, timeline animation, Rapier physics and state-machine logic on a single canvas, exported as portable .exode artboards. This package renders those artboards with the same Canvas 2D engine used by every ExodeUI framework runtime.
- Angular 17+ standalone component. Drop it into any feature module or standalone app,
OnPushby default. - Zone-safe performance. The render loop runs outside
NgZone, so 60/120fps animation never triggers change detection; outputs re-enter the zone only when they fire. - Typed inputs and outputs. Every sensor, layout and callback is an
@Input/@Output. - Service for imperative control. Inject
ExodeUIService, register the engine once, and drive inputs from anywhere. - Behaviour parity. Matches the React, Vue, Svelte, Solid and vanilla runtimes.
npm install exodeui-angular
# or
pnpm add exodeui-angularRequires @angular/core and @angular/common >= 17.
<div style="width: 800px; height: 600px;">
<exodeui-canvas
[artboard]="artboard"
fit="Contain"
alignment="Center"
(ready)="exoService.register($event)"
(trigger)="onTrigger($event)"
(navigation)="onNavigation($event)"
></exodeui-canvas>
</div>import { Component, inject } from '@angular/core';
import { ExodeUICanvasComponent, ExodeUIService } from 'exodeui-angular';
@Component({
selector: 'app-root',
standalone: true,
imports: [ExodeUICanvasComponent],
templateUrl: './app.component.html',
})
export class AppComponent {
exoService = inject(ExodeUIService);
artboard = /* parsed .exode JSON */;
onTrigger({ name, anim }: { name: string; anim: string }) {
console.log('trigger', name, anim);
}
onNavigation({ type, value }: { type: string; value: string }) {
if (type === 'url') window.location.href = value;
}
}selectTab(index: number) {
this.exoService.updateInput('activeTab', index);
this.exoService.fireTrigger('TabChange');
}<exodeui-canvas [artboard]="artboard" [autoPlay]="false" [currentTime]="1.25" />| Capability | Included |
|---|---|
| Canvas 2D renderer with DPR-aware scaling | ✅ |
| State machine + logic nodes (AND / OR / XOR / NOT) | ✅ |
| Boolean, number, text, trigger, array, random inputs | ✅ |
| 2D physics (Rapier): dynamic, static, kinematic bodies | ✅ |
| Spring, drag, joystick, pointer and keyboard sensors | ✅ |
| Responsive layouts, breakpoints and spatial constraints | ✅ |
| Line graphs, bar charts and pie charts with live data | ✅ |
| Text inputs, toggles, dropdowns, sliders and list views | ✅ |
| Scroll-linked and viewport-driven animation | ✅ |
.exode JSON and compressed .bexode loading |
✅ |
| Glow, light trails, pattern grids, masks | ✅ |
| Input | Type | Default | Description |
|---|---|---|---|
artboard |
Artboard |
— | Parsed artboard JSON |
src |
string |
— | .exode / .bexode URL or JSON string |
buffer |
ArrayBuffer | Uint8Array |
— | Pre-read .bexode buffer |
revision |
number |
0 |
Bump to force a reload |
fit |
Fit |
'Contain' |
Fit mode |
alignment |
Alignment |
'Center' |
Alignment |
layoutScaleFactor |
number |
— | Extra scale for Fit: 'Layout' |
autoPlay |
boolean |
true |
Auto-start the loop |
interactive |
boolean |
true |
Enable input handling |
preventScroll |
boolean |
true |
Block page scroll on wheel/touch |
highRefreshRate |
boolean |
true |
Sub-frame pacing on 120Hz displays |
currentTime |
number |
— | Render a fixed time when autoPlay is false |
scrollX/Y, viewportScrollX/Y |
number |
— | External scroll sensors |
mouseX/Y, isMouseDown |
number | boolean |
— | External pointer sensors |
inputs |
Record<string, any> |
— | Inputs applied on load |
callbacks |
Record<string, Function> |
— | Named listeners from the editor |
(ready), (trigger), (inputUpdate), (componentChange), (toggle), (inputChange), (inputFocus), (inputBlur), (navigation), (buttonClick), (graphPointClick), (log), (logicUpdate), (fpsUpdate)
getEngine(), play(), pause(), seek(time), resize(), setLayout(fit, alignment?, scale?), setOptions(options), setInputBool/Number/Text, fireTrigger, updateInput, updateGraphData, getInputValue
register(engine), updateInput, setInputBool, setInputNumber, setInputText, fireTrigger, updateObjectOptions, updateConstraint, updateGraphData, updateObjectProperty, setDropdownOptions, getInputValue
Does it break zone stability? No — animation and pointer handling run outside NgZone; only emitted events re-enter it.
Does it work with Angular Universal / SSR? Yes, the canvas initialises after ngAfterViewInit.
Is ExodeUI a Rive or Lottie alternative? It targets interactive UI, not linear playback — see the Rive comparison.
How do I update chart data? Call updateGraphData, updateBarChartData or updatePieChartData on the service or component.
What is a .exode file? The portable artboard exported by the ExodeUI editor — plain JSON, or compressed .bexode.
- exodeui — React runtime and Vite plugin
- exodeui-vanilla — framework-free runtime
- exodeui-vue — Vue 3 runtime
- exodeui-svelte — Svelte 5 runtime
- exodeui-solid — SolidJS runtime
MIT © ExodeUI