exodeui 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # exodeui
1
+ # ExodeUI React SDK
2
2
 
3
- The React Runtime for the ExodeUI Animation Engine. Easily render and interact with ExodeUI animations in your React applications.
3
+ The official React Runtime for the **ExodeUI Animation Engine**. Seamlessly render and interact with high-performance animations, physics simulations, and state machines built with ExodeUI.
4
4
 
5
5
  ## Installation
6
6
 
@@ -17,10 +17,9 @@ import { ExodeUICanvas } from 'exodeui';
17
17
 
18
18
  function App() {
19
19
  return (
20
- <div style={{ width: 500, height: 500 }}>
21
- {/* Option 1: Load from a URL or file path (e.g. in public folder) */}
20
+ <div style={{ width: 800, height: 600 }}>
22
21
  <ExodeUICanvas
23
- src="/my-animation.json"
22
+ src="/animations/my-scene.json"
24
23
  autoPlay={true}
25
24
  fit="Contain"
26
25
  alignment="Center"
@@ -30,83 +29,93 @@ function App() {
30
29
  }
31
30
  ```
32
31
 
33
- ### Loading via Import
32
+ ## Features
34
33
 
35
- Alternatively, you can import the JSON directly if your bundler supports it:
34
+ ### 1. State Machine & Logic
35
+ ExodeUI supports complex interactive logic using a node-based **State Machine**.
36
+ - **Inputs**: Control the flow with Boolean, Number, and Trigger inputs.
37
+ - **Logic Nodes**: Combine inputs using AND, OR, NOT, XOR.
38
+ - **Conditions**: Create transitions based on input values (e.g., `Speed > 10`, `IsHovered == true`).
36
39
 
37
40
  ```tsx
38
- import { ExodeUICanvas } from 'exodeui';
39
- import animationData from './my-animation.json';
41
+ const [engine, setEngine] = useState<ExodeUIEngine | null>(null);
40
42
 
41
- function App() {
42
- return (
43
- <ExodeUICanvas artboard={animationData} />
44
- )
45
- }
43
+ // ... inside your component
44
+ <ExodeUICanvas
45
+ src="/player_controller.json"
46
+ onReady={setEngine}
47
+ />
48
+
49
+ // Button controls
50
+ <button onClick={() => engine?.setInputBool('IsRunning', true)}>Run</button>
51
+ <button onClick={() => engine?.fireTrigger('Jump')}>Jump</button>
46
52
  ```
47
53
 
48
- ## API
54
+ ### 2. Physics Engine
55
+ Built-in 2D physics using **Rapier**.
56
+ - **Dynamic Bodies**: Objects that react to gravity and collisions.
57
+ - **Static Bodies**: Platforms and walls.
58
+ - **Kinematic**: Animated objects that push other bodies.
59
+ - **Properties**: Mass, Friction, Restitution (Bounciness), Density.
49
60
 
50
- ### `<ExodeUICanvas />`
61
+ *Physics is configured directly in the ExodeUI Editor.*
62
+
63
+ ### 3. Data Visualization (Line Graphs)
64
+ Render beautiful, animated line graphs with zero extra code.
65
+ - **Line Graphs**: Supports multiple datasets, smoothing (Catmull-Rom splines), fill areas, and points.
66
+ - **Data Binding**: Bind graph data to runtime inputs or variables.
67
+
68
+ ```tsx
69
+ // Example of injecting data via Inputs (if supported by your graph configuration)
70
+ // engine.setInputNumberArray('StockData', [10, 25, 15, 40, 35, 60]);
71
+ // (Note: array input support depends on your specific version/setup)
72
+ ```
73
+
74
+ ## API Reference
51
75
 
52
- The main component for rendering ExodeUI animations.
76
+ ### `<ExodeUICanvas />`
53
77
 
54
78
  | Prop | Type | Default | Description |
55
79
  |------|------|---------|-------------|
56
- | `artboard` | `object` | `undefined` | The JSON animation data object. |
57
- | `src` | `string` | `undefined` | URL to fetch the animation JSON from. |
58
- | `autoPlay` | `boolean` | `true` | Whether the animation should start playing automatically. |
59
- | `fit` | `'Contain' \| 'Cover' \| 'Fill' \| 'FitWidth' \| 'FitHeight' \| 'None' \| 'ScaleDown'` | `'Contain'` | How the artboard fits within the canvas. |
60
- | `alignment` | `'Center' \| 'TopLeft' \| ...` | `'Center'` | How the content aligns if there is extra space. |
61
- | `onReady` | `(engine: ExodeUIEngine) => void` | `undefined` | Callback fired when the engine is loaded and ready. |
62
- | `style` | `CSSProperties` | `{ width: '100%', height: '100%' }` | CSS styles for the canvas element. |
63
- | `className` | `string` | `undefined` | CSS class name for the canvas element. |
80
+ | `src` | `string` | - | URL to the animation JSON file. |
81
+ | `artboard` | `object` | - | Direct JSON data object (if imported). |
82
+ | `fit` | `'Contain' \| 'Cover' \| 'Fill'` | `'Contain'` | Scaling strategy. |
83
+ | `alignment` | `'Center' \| 'TopLeft' ...` | `'Center'` | Alignment within the canvas. |
84
+ | `autoPlay` | `boolean` | `true` | Auto-start the animation loop. |
85
+ | `onReady` | `(engine: ExodeUIEngine) => void` | - | Callback when engine is initialized. |
86
+ | `onTrigger` | `(name: string, animationName: string) => void` | - | Listener for outgoing triggers (events). |
87
+ | `onInputUpdate` | `(nameOrId: string, value: any) => void` | - | Listener for input value changes. |
64
88
 
65
89
  ### `useExodeUI` Hook
66
90
 
67
- (Coming Soon)
68
-
69
- ## State Machine Inputs
70
-
71
- You can control the animation state machine using the engine instance provided via `onReady`.
91
+ A helper hook for easier engine management.
72
92
 
73
93
  ```tsx
74
- const [engine, setEngine] = useState<ExodeUIEngine | null>(null);
94
+ import { useExodeUI, ExodeUICanvas } from 'exodeui';
75
95
 
76
- // ...
77
-
78
- <ExodeUICanvas
79
- artboard={data}
80
- onReady={(e) => {
81
- setEngine(e);
82
-
83
- // Listen to triggers
84
- e.setTriggerCallback((triggerName, animationName) => {
85
- console.log(`Trigger "${triggerName}" fired! Playing "${animationName}"`);
86
- });
87
- }}
88
- />
96
+ function Game() {
97
+ const { setEngine, setInputBool, fireTrigger } = useExodeUI();
89
98
 
90
- <button onClick={() => engine?.setInputBool('IsWalking', true)}>
91
- Walk
92
- </button>
99
+ return (
100
+ <>
101
+ <ExodeUICanvas src="/game.json" onReady={setEngine} />
102
+ <div className="controls">
103
+ <button onMouseDown={() => setInputBool('Fire', true)}>Shoot</button>
104
+ </div>
105
+ </>
106
+ );
107
+ }
93
108
  ```
94
109
 
95
- ## Listening to Triggers
110
+ ## Advanced
96
111
 
97
- You can listen for interactive triggers (e.g. clicks on shapes) using `setTriggerCallback`:
112
+ ### Logic Nodes
113
+ The engine automatically evaluates logic nodes defined in the editor.
114
+ - **AND / OR / XOR / NOT** gates allow for complex condition evaluation without writing code.
115
+ - Inputs are strictly typed: `Boolean`, `Number`, `Trigger` (momentary boolean), `Text`.
98
116
 
99
- ```tsx
100
- <ExodeUICanvas
101
- artboard={data}
102
- onReady={(engine) => {
103
- engine.setTriggerCallback((triggerName, animationName) => {
104
- // Handle side effects here (e.g. navigation, sound, analytics)
105
- console.log(triggerName, animationName);
106
- });
107
- }}
108
- />
109
- ```
117
+ ### Custom Fonts
118
+ Ensure any custom fonts used in the ExodeUI editor are loaded in your web page (e.g., via Google Fonts or `@font-face`) for correct rendering.
110
119
 
111
120
  ## License
112
121
 
@@ -0,0 +1,3 @@
1
+ import { Artboard } from '../types';
2
+
3
+ export declare const comprehensiveArtboard: Artboard;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/dist/engine.d.ts CHANGED
@@ -12,12 +12,15 @@ export declare class ExodeUIEngine {
12
12
  private layout;
13
13
  private onTrigger?;
14
14
  private onInputUpdate?;
15
+ private justFiredTriggers;
16
+ private lastHoveredObjectId;
15
17
  setTriggerCallback(cb: (triggerName: string, animationName: string) => void): void;
16
18
  setInputUpdateCallback(cb: (nameOrId: string, value: any) => void): void;
17
19
  constructor();
18
20
  private setInternalInput;
19
21
  setLayout(fit: Fit, alignment: Alignment): void;
20
22
  getActiveStateIds(layerName?: string): string[];
23
+ getObjectState(id: string): any;
21
24
  load(data: Artboard): void;
22
25
  reset(): void;
23
26
  private enterStates;
@@ -25,13 +28,26 @@ export declare class ExodeUIEngine {
25
28
  setInputNumber(nameOrId: string, value: number): void;
26
29
  fireTrigger(nameOrId: string): void;
27
30
  setInputText(nameOrId: string, value: string): void;
31
+ setInputNumberArray(nameOrId: string, value: number[]): void;
28
32
  private updateInput;
29
33
  private evaluateTransitions;
34
+ /**
35
+ * Find a global transition from any state in the layer whose conditions are met.
36
+ * This allows inputs to act as "global listeners" that can trigger state changes
37
+ * from any state, not just the current state.
38
+ *
39
+ * @param layer - The state machine layer to search
40
+ * @param currentStateIds - The currently active state IDs (to skip)
41
+ * @returns The first matching transition, or null if none found
42
+ */
43
+ private findGlobalTransition;
30
44
  private checkConditions;
45
+ private evaluateLogicTree;
31
46
  private activeTriggers;
32
47
  advance(dt: number): void;
33
48
  handlePointerInput(type: string, canvasX: number, canvasY: number, canvasWidth: number, canvasHeight: number): void;
34
49
  private handlePointerEvent;
50
+ private fireEventForObject;
35
51
  private hitTest;
36
52
  private applyAnimation;
37
53
  private interpolate;
@@ -39,4 +55,6 @@ export declare class ExodeUIEngine {
39
55
  render(ctx: CanvasRenderingContext2D, width: number, height: number): void;
40
56
  private calculateTransform;
41
57
  private renderObject;
58
+ private renderLineGraph;
59
+ private _catmullRom;
42
60
  }