onda-engine 0.1.0 → 0.1.1
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 +60 -39
- package/dist/wasm/pkg/onda_wasm.d.ts +195 -0
- package/dist/wasm/pkg/onda_wasm_bg.wasm.d.ts +34 -0
- package/dist/wasm-audio/pkg/onda_wasm_audio.d.ts +106 -0
- package/dist/wasm-audio/pkg/onda_wasm_audio_bg.wasm.d.ts +20 -0
- package/dist/wasm-vello/index.d.ts +1 -0
- package/dist/wasm-vello/pkg/onda_wasm_vello.d.ts +96 -0
- package/dist/wasm-vello/pkg/onda_wasm_vello_bg.wasm.d.ts +24 -0
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -1,15 +1,38 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<img src="https://raw.githubusercontent.com/onda-engine/onda-engine/main/assets/brand/readme-hero.svg" alt="ONDA Engine — motion graphics at GPU speed, no browser" width="100%" />
|
|
4
|
+
|
|
5
|
+
<br/>
|
|
6
|
+
|
|
7
|
+
### Motion graphics at GPU speed. No browser. No Chromium.
|
|
8
|
+
|
|
9
|
+
**Author video in React → compile it to a scene graph → render it natively on the GPU.**
|
|
10
|
+
One `npm install` for the entire engine.
|
|
4
11
|
|
|
5
12
|
[](https://www.npmjs.com/package/onda-engine)
|
|
6
|
-
[](#license--read-this-first)
|
|
14
|
+
[](#whats-in-the-box)
|
|
15
|
+
[](#why-onda)
|
|
16
|
+
|
|
17
|
+
[Why ONDA](#why-onda) · [Install](#install) · [What's in the box](#whats-in-the-box) · [Onda Studio](#onda-studio) · [License](#license--read-this-first) · [onda.video](https://onda.video)
|
|
18
|
+
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
---
|
|
7
22
|
|
|
8
|
-
ONDA turns a
|
|
23
|
+
**ONDA turns a React composition into a renderer-agnostic _scene graph_, then rasterizes it with a native GPU renderer ([Vello](https://github.com/linebender/vello))** — or a deterministic CPU reference renderer, or a WebAssembly path for live in-browser preview. No DOM. No headless browser. No screenshot round-trip. Just a scene graph, straight to the GPU.
|
|
9
24
|
|
|
10
|
-
|
|
25
|
+
`onda-engine` is the **all-in-one** package — the React renderer, the motion-language component library, the interactive player, the headless renderer, and the WASM cores — bundled into a single install, one version.
|
|
11
26
|
|
|
12
|
-
> **Pre-1.0.** The Rust + WASM core powers a production studio, but the public API isn't frozen — expect breaking changes before 1.0
|
|
27
|
+
> **Pre-1.0.** The Rust + WASM core already powers a production studio, but the public API isn't frozen — expect breaking changes before `1.0`.
|
|
28
|
+
|
|
29
|
+
## Why ONDA
|
|
30
|
+
|
|
31
|
+
Programmatic video today (e.g. Remotion) renders by driving a **headless browser**: correct, but heavy — a Chromium process per render, slow cold starts, high memory, painful to scale. ONDA keeps the **React authoring model** you already know, but compiles it to a scene graph and renders it **natively**. There is no browser anywhere in the pipeline.
|
|
32
|
+
|
|
33
|
+
> **It's faster because it does less.** Measured on an Apple M4 Pro (1080p, Remotion's best case): **~4.5× faster per thread** and **~9.3× higher machine throughput** than Remotion — and the gap *widens* with scene complexity, GPU acceleration, and cold-start / memory pressure.
|
|
34
|
+
|
|
35
|
+
The scene graph is the universal language; the renderer is the platform. **One composition** drives them all — live browser preview (WebGPU / WASM), native GPU export, or a deterministic CPU reference render.
|
|
13
36
|
|
|
14
37
|
## Install
|
|
15
38
|
|
|
@@ -17,23 +40,19 @@ This is the **all-in-one** package: the React renderer, the motion-language comp
|
|
|
17
40
|
npm install onda-engine react
|
|
18
41
|
```
|
|
19
42
|
|
|
20
|
-
`react` (v19) is a peer dependency
|
|
21
|
-
|
|
22
|
-
> The engine is developed as granular [`@onda-engine/*`](https://github.com/onda-engine/onda-engine) workspace packages; `onda-engine` bundles them into a single public install (one package, one version) — this is the package you install.
|
|
43
|
+
`react` (v19) is a peer dependency you provide. Everything else — including the ~11 MB of WASM cores — ships in the box. No runtime downloads, no extra registry to configure, no Rust toolchain on your machine.
|
|
23
44
|
|
|
24
|
-
## What's
|
|
45
|
+
## What's in the box
|
|
25
46
|
|
|
26
47
|
| Import | What it is |
|
|
27
48
|
| --- | --- |
|
|
28
49
|
| `onda-engine` | The Onda **motion language** — choreography + component library (the main authoring surface) |
|
|
29
50
|
| `onda-engine/react` | The React → scene-graph renderer (`renderToScene`, primitives, hooks) |
|
|
30
|
-
| `onda-engine/player` | Interactive `<Player>` — real-time canvas/WebGPU preview |
|
|
31
|
-
| `onda-engine/render` | **Node-only** headless render to video/still (no Chromium) |
|
|
51
|
+
| `onda-engine/player` | Interactive `<Player>` — real-time canvas / WebGPU preview |
|
|
52
|
+
| `onda-engine/render` | **Node-only** headless render to video / still (no Chromium) |
|
|
32
53
|
| `onda-engine/cinema` | Render a timeline composition payload to an engine element |
|
|
33
54
|
| `onda-engine/components/manifest` | Per-component prop manifest (semantic roles) |
|
|
34
|
-
| `onda-engine/wasm` | The renderer
|
|
35
|
-
| `onda-engine/wasm-audio` | Audio decode + FFT (audio-reactive visuals) |
|
|
36
|
-
| `onda-engine/wasm-vello` | The Vello GPU renderer over WebGPU |
|
|
55
|
+
| `onda-engine/wasm` · `/wasm-audio` · `/wasm-vello` | The renderer, audio FFT, and Vello GPU cores, compiled to WebAssembly |
|
|
37
56
|
|
|
38
57
|
## Usage
|
|
39
58
|
|
|
@@ -41,44 +60,46 @@ npm install onda-engine react
|
|
|
41
60
|
import { TitleCard } from 'onda-engine'
|
|
42
61
|
import { renderToScene } from 'onda-engine/react'
|
|
43
62
|
|
|
44
|
-
const scene = renderToScene(<TitleCard title="Hello" />)
|
|
63
|
+
const scene = renderToScene(<TitleCard title="Hello, motion" />)
|
|
45
64
|
```
|
|
46
65
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
Under a bundler that supports the `new URL(..., import.meta.url)` asset convention (Vite, modern webpack), the WASM **loads itself** — each `.wasm` ships next to its glue and is fetched automatically. Nothing to wire up:
|
|
66
|
+
**The WASM loads itself.** Under a bundler that supports the `new URL(..., import.meta.url)` asset convention (Vite, modern webpack), each `.wasm` ships next to its glue and is fetched automatically — nothing to wire up:
|
|
50
67
|
|
|
51
68
|
```ts
|
|
52
69
|
import { preloadTextMetrics, measureText } from 'onda-engine'
|
|
53
70
|
|
|
54
|
-
await preloadTextMetrics()
|
|
55
|
-
measureText('Hello', 48)
|
|
71
|
+
await preloadTextMetrics() // locates + instantiates the wasm core
|
|
72
|
+
measureText('Hello', 48) // real shaped glyph metrics
|
|
56
73
|
```
|
|
57
74
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
```ts
|
|
61
|
-
import wasmUrl from 'onda-engine/wasm/pkg/onda_wasm_bg.wasm?url'
|
|
62
|
-
import init, { OndaEngine } from 'onda-engine/wasm'
|
|
75
|
+
> **`onda-engine/render` is Node-only** — it uses `fs`, `child_process`, and ffmpeg. Don't import it into browser code; use it from a server or CLI.
|
|
63
76
|
|
|
64
|
-
|
|
65
|
-
const engine = new OndaEngine()
|
|
66
|
-
```
|
|
77
|
+
## Onda Studio
|
|
67
78
|
|
|
68
|
-
|
|
79
|
+
ONDA is the **engine**; **[Onda Studio](https://studio.onda.video)** is the **director**.
|
|
69
80
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
```ts
|
|
73
|
-
import { renderToFile } from 'onda-engine/render'
|
|
74
|
-
```
|
|
81
|
+
Studio is an AI motion-graphics studio — *"Lovable for video."* Describe a scene in plain language and an agent composes, renders, and ships it — frame-accurate, on this exact engine. The engine stands on its own as a programmatic-video toolkit; Studio is what it makes possible.
|
|
75
82
|
|
|
76
83
|
## Requirements
|
|
77
84
|
|
|
78
85
|
- **React 19** (peer dependency)
|
|
79
|
-
- A bundler that handles `.wasm` assets for browser use (Vite recommended), or Node ≥ 20 for server-side
|
|
80
|
-
- WebGPU for the GPU (`wasm-vello`) path; the CPU
|
|
86
|
+
- A bundler that handles `.wasm` assets for browser use (**Vite** recommended), or **Node ≥ 20** for server-side rendering
|
|
87
|
+
- **WebGPU** for the GPU (`wasm-vello`) path; the CPU core (`wasm`) is the always-available fallback
|
|
88
|
+
|
|
89
|
+
## License — read this first
|
|
90
|
+
|
|
91
|
+
**Source-available — _not_ open source.** `onda-engine` is licensed under the **[Functional Source License](https://raw.githubusercontent.com/onda-engine/onda-engine/main/LICENSE)** (`FSL-1.1-Apache-2.0`):
|
|
92
|
+
|
|
93
|
+
- ✅ **You may** read, run, self-host, modify, and build **non-competing** products with it — freely, no fee.
|
|
94
|
+
- 🚫 **You may not** use it to make a product that **competes** with ONDA.
|
|
95
|
+
- ⏳ **It turns into Apache-2.0:** each release automatically converts to full [Apache-2.0](https://raw.githubusercontent.com/onda-engine/onda-engine/main/LICENSE-APACHE) **two years** after it ships.
|
|
96
|
+
|
|
97
|
+
If you need terms beyond the FSL grant, get in touch via [onda.video](https://onda.video).
|
|
81
98
|
|
|
82
|
-
|
|
99
|
+
---
|
|
83
100
|
|
|
84
|
-
|
|
101
|
+
<div align="center">
|
|
102
|
+
<img src="https://raw.githubusercontent.com/onda-engine/onda-engine/main/assets/brand/onda-mark.svg" alt="ONDA" width="34" />
|
|
103
|
+
<br/><br/>
|
|
104
|
+
<sub><b>ONDA</b> · Motion graphics at GPU speed · <a href="https://onda.video">onda.video</a></sub>
|
|
105
|
+
</div>
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Font-level vertical metrics exposed to JS — distances in pixels at the
|
|
6
|
+
* measured font size. Returned by [`OndaEngine::font_metrics`].
|
|
7
|
+
*/
|
|
8
|
+
export class FontMetricsJs {
|
|
9
|
+
private constructor();
|
|
10
|
+
free(): void;
|
|
11
|
+
[Symbol.dispose](): void;
|
|
12
|
+
/**
|
|
13
|
+
* Distance from node's `y` to the baseline (same as `TextMetrics.ascent`, px).
|
|
14
|
+
*/
|
|
15
|
+
readonly ascent: number;
|
|
16
|
+
/**
|
|
17
|
+
* Height of capital letters (top of caps to baseline, px).
|
|
18
|
+
*/
|
|
19
|
+
readonly cap_height: number;
|
|
20
|
+
/**
|
|
21
|
+
* Distance from the node's `y` to the top of capital letters (px).
|
|
22
|
+
*/
|
|
23
|
+
readonly cap_top: number;
|
|
24
|
+
/**
|
|
25
|
+
* Baseline to bottom of the line box (px).
|
|
26
|
+
*/
|
|
27
|
+
readonly descent: number;
|
|
28
|
+
/**
|
|
29
|
+
* Baseline-to-baseline line height (px).
|
|
30
|
+
*/
|
|
31
|
+
readonly lineHeight: number;
|
|
32
|
+
/**
|
|
33
|
+
* x-height in px (top of 'x' to baseline).
|
|
34
|
+
*/
|
|
35
|
+
readonly x_height: number;
|
|
36
|
+
/**
|
|
37
|
+
* Distance from the node's `y` to the top of lowercase x (px).
|
|
38
|
+
*/
|
|
39
|
+
readonly x_top: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The engine: holds a renderer (with the bundled default font) and rasterizes
|
|
44
|
+
* scene-graph JSON to frames. Construct once and reuse across frames.
|
|
45
|
+
*/
|
|
46
|
+
export class OndaEngine {
|
|
47
|
+
free(): void;
|
|
48
|
+
[Symbol.dispose](): void;
|
|
49
|
+
/**
|
|
50
|
+
* Font-level vertical metrics for `font_size` + optional family/weight/italic.
|
|
51
|
+
* Derived by rasterizing 'H' (cap height) and 'x' (x-height) — pixel-accurate
|
|
52
|
+
* for the actual rendered font. Call once per (size, family, weight) combo, not
|
|
53
|
+
* per frame. Use the returned `capTop`/`capHeight` to vertically center text
|
|
54
|
+
* without empirical guesswork.
|
|
55
|
+
*/
|
|
56
|
+
fontMetrics(font_size: number, family?: string | null, weight?: number | null, italic?: boolean | null): FontMetricsJs;
|
|
57
|
+
/**
|
|
58
|
+
* Kerning-aware glyph layout for `content` at `font_size`. Returns a
|
|
59
|
+
* `Float32Array` with 4 floats per cluster: `[start_byte, end_byte, x, advance]`.
|
|
60
|
+
* Unlike calling `measureText` per character, `advance` includes kern pairs.
|
|
61
|
+
* Slice with stride 4; the total advance sum equals the shaped line width.
|
|
62
|
+
*/
|
|
63
|
+
glyphLayout(content: string, font_size: number, family?: string | null, weight?: number | null, italic?: boolean | null, letter_spacing?: number | null): Float32Array;
|
|
64
|
+
/**
|
|
65
|
+
* Load an additional font (`.ttf`/`.otf` bytes) so text can select it by
|
|
66
|
+
* family (e.g. a brand display face for kinetic typography). Returns the
|
|
67
|
+
* family name(s) it provides, newline-joined. Loaded into BOTH the renderer
|
|
68
|
+
* (which draws the glyphs) and the layout/measurement font context, so
|
|
69
|
+
* author-time `measureText`/`glyphLayout`/`fontMetrics` — and therefore
|
|
70
|
+
* `<TextAnimator>`/`KineticText` glyph placement — match what the engine
|
|
71
|
+
* draws. This is the custom-font parity guarantee: same bytes, same shaping,
|
|
72
|
+
* for measure and render. Mirrors `VelloEngine::load_font`.
|
|
73
|
+
*/
|
|
74
|
+
loadFont(data: Uint8Array): string;
|
|
75
|
+
/**
|
|
76
|
+
* Measure `content` at `font_size` (px) with optional family / weight /
|
|
77
|
+
* italic, returning its [`TextMetricsJs`]. The same shaping the engine draws,
|
|
78
|
+
* so a component can size underlines/pills/carets to the real text — in both
|
|
79
|
+
* the browser preview and (warmed once) the Node export path.
|
|
80
|
+
*/
|
|
81
|
+
measureText(content: string, font_size: number, family?: string | null, weight?: number | null, italic?: boolean | null, letter_spacing?: number | null): TextMetricsJs;
|
|
82
|
+
constructor();
|
|
83
|
+
/**
|
|
84
|
+
* Render a scene-graph JSON document (onda-scene format) to a frame.
|
|
85
|
+
* Resolves `data:` images and flex layout first (the same pre-passes the
|
|
86
|
+
* CLI runs), so an in-browser preview matches `onda export`.
|
|
87
|
+
*/
|
|
88
|
+
render(scene_json: string): RenderedFrame;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* A rendered frame: RGBA8 pixels plus dimensions.
|
|
93
|
+
*/
|
|
94
|
+
export class RenderedFrame {
|
|
95
|
+
private constructor();
|
|
96
|
+
free(): void;
|
|
97
|
+
[Symbol.dispose](): void;
|
|
98
|
+
readonly height: number;
|
|
99
|
+
/**
|
|
100
|
+
* Straight-alpha RGBA8 bytes (`width * height * 4`), ready for an
|
|
101
|
+
* `ImageData` and `putImageData`.
|
|
102
|
+
*/
|
|
103
|
+
readonly pixels: Uint8Array;
|
|
104
|
+
readonly width: number;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Rendered text dimensions ([`onda_renderer::TextMetrics`]) for JS — what a
|
|
109
|
+
* component needs to size things to the *actual* text (proportional advance,
|
|
110
|
+
* ascent/descent) instead of a glyph-count guess. Pixels at the measured size.
|
|
111
|
+
*/
|
|
112
|
+
export class TextMetricsJs {
|
|
113
|
+
private constructor();
|
|
114
|
+
free(): void;
|
|
115
|
+
[Symbol.dispose](): void;
|
|
116
|
+
/**
|
|
117
|
+
* Top of the line box to the baseline.
|
|
118
|
+
*/
|
|
119
|
+
readonly ascent: number;
|
|
120
|
+
/**
|
|
121
|
+
* Baseline to the bottom of the line box.
|
|
122
|
+
*/
|
|
123
|
+
readonly descent: number;
|
|
124
|
+
/**
|
|
125
|
+
* Total laid-out height (line height × line count).
|
|
126
|
+
*/
|
|
127
|
+
readonly height: number;
|
|
128
|
+
/**
|
|
129
|
+
* Baseline-to-baseline line height.
|
|
130
|
+
*/
|
|
131
|
+
readonly lineHeight: number;
|
|
132
|
+
/**
|
|
133
|
+
* Shaped advance width — the true rendered width of the string.
|
|
134
|
+
*/
|
|
135
|
+
readonly width: number;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
139
|
+
|
|
140
|
+
export interface InitOutput {
|
|
141
|
+
readonly memory: WebAssembly.Memory;
|
|
142
|
+
readonly __wbg_fontmetricsjs_free: (a: number, b: number) => void;
|
|
143
|
+
readonly __wbg_ondaengine_free: (a: number, b: number) => void;
|
|
144
|
+
readonly __wbg_renderedframe_free: (a: number, b: number) => void;
|
|
145
|
+
readonly __wbg_textmetricsjs_free: (a: number, b: number) => void;
|
|
146
|
+
readonly fontmetricsjs_ascent: (a: number) => number;
|
|
147
|
+
readonly fontmetricsjs_cap_height: (a: number) => number;
|
|
148
|
+
readonly fontmetricsjs_cap_top: (a: number) => number;
|
|
149
|
+
readonly fontmetricsjs_descent: (a: number) => number;
|
|
150
|
+
readonly fontmetricsjs_lineHeight: (a: number) => number;
|
|
151
|
+
readonly fontmetricsjs_x_height: (a: number) => number;
|
|
152
|
+
readonly fontmetricsjs_x_top: (a: number) => number;
|
|
153
|
+
readonly ondaengine_fontMetrics: (a: number, b: number, c: number, d: number, e: number, f: number) => number;
|
|
154
|
+
readonly ondaengine_glyphLayout: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => [number, number];
|
|
155
|
+
readonly ondaengine_loadFont: (a: number, b: number, c: number) => [number, number];
|
|
156
|
+
readonly ondaengine_measureText: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => number;
|
|
157
|
+
readonly ondaengine_new: () => number;
|
|
158
|
+
readonly ondaengine_render: (a: number, b: number, c: number) => [number, number, number];
|
|
159
|
+
readonly renderedframe_height: (a: number) => number;
|
|
160
|
+
readonly renderedframe_pixels: (a: number) => [number, number];
|
|
161
|
+
readonly renderedframe_width: (a: number) => number;
|
|
162
|
+
readonly textmetricsjs_ascent: (a: number) => number;
|
|
163
|
+
readonly textmetricsjs_descent: (a: number) => number;
|
|
164
|
+
readonly textmetricsjs_height: (a: number) => number;
|
|
165
|
+
readonly textmetricsjs_lineHeight: (a: number) => number;
|
|
166
|
+
readonly textmetricsjs_width: (a: number) => number;
|
|
167
|
+
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
168
|
+
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
169
|
+
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
170
|
+
readonly __wbindgen_externrefs: WebAssembly.Table;
|
|
171
|
+
readonly __externref_table_dealloc: (a: number) => void;
|
|
172
|
+
readonly __wbindgen_start: () => void;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Instantiates the given `module`, which can either be bytes or
|
|
179
|
+
* a precompiled `WebAssembly.Module`.
|
|
180
|
+
*
|
|
181
|
+
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
182
|
+
*
|
|
183
|
+
* @returns {InitOutput}
|
|
184
|
+
*/
|
|
185
|
+
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
189
|
+
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
190
|
+
*
|
|
191
|
+
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
192
|
+
*
|
|
193
|
+
* @returns {Promise<InitOutput>}
|
|
194
|
+
*/
|
|
195
|
+
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
export const memory: WebAssembly.Memory;
|
|
4
|
+
export const __wbg_fontmetricsjs_free: (a: number, b: number) => void;
|
|
5
|
+
export const __wbg_ondaengine_free: (a: number, b: number) => void;
|
|
6
|
+
export const __wbg_renderedframe_free: (a: number, b: number) => void;
|
|
7
|
+
export const __wbg_textmetricsjs_free: (a: number, b: number) => void;
|
|
8
|
+
export const fontmetricsjs_ascent: (a: number) => number;
|
|
9
|
+
export const fontmetricsjs_cap_height: (a: number) => number;
|
|
10
|
+
export const fontmetricsjs_cap_top: (a: number) => number;
|
|
11
|
+
export const fontmetricsjs_descent: (a: number) => number;
|
|
12
|
+
export const fontmetricsjs_lineHeight: (a: number) => number;
|
|
13
|
+
export const fontmetricsjs_x_height: (a: number) => number;
|
|
14
|
+
export const fontmetricsjs_x_top: (a: number) => number;
|
|
15
|
+
export const ondaengine_fontMetrics: (a: number, b: number, c: number, d: number, e: number, f: number) => number;
|
|
16
|
+
export const ondaengine_glyphLayout: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => [number, number];
|
|
17
|
+
export const ondaengine_loadFont: (a: number, b: number, c: number) => [number, number];
|
|
18
|
+
export const ondaengine_measureText: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => number;
|
|
19
|
+
export const ondaengine_new: () => number;
|
|
20
|
+
export const ondaengine_render: (a: number, b: number, c: number) => [number, number, number];
|
|
21
|
+
export const renderedframe_height: (a: number) => number;
|
|
22
|
+
export const renderedframe_pixels: (a: number) => [number, number];
|
|
23
|
+
export const renderedframe_width: (a: number) => number;
|
|
24
|
+
export const textmetricsjs_ascent: (a: number) => number;
|
|
25
|
+
export const textmetricsjs_descent: (a: number) => number;
|
|
26
|
+
export const textmetricsjs_height: (a: number) => number;
|
|
27
|
+
export const textmetricsjs_lineHeight: (a: number) => number;
|
|
28
|
+
export const textmetricsjs_width: (a: number) => number;
|
|
29
|
+
export const __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
30
|
+
export const __wbindgen_malloc: (a: number, b: number) => number;
|
|
31
|
+
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
32
|
+
export const __wbindgen_externrefs: WebAssembly.Table;
|
|
33
|
+
export const __externref_table_dealloc: (a: number) => void;
|
|
34
|
+
export const __wbindgen_start: () => void;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A decoded audio clip you can sample a per-frame spectrum from.
|
|
6
|
+
*/
|
|
7
|
+
export class AudioAnalyzer {
|
|
8
|
+
free(): void;
|
|
9
|
+
[Symbol.dispose](): void;
|
|
10
|
+
/**
|
|
11
|
+
* BEAT / onset / tempo analysis over `frame_count` frames at `fps`, for syncing
|
|
12
|
+
* motion to the music. Deterministic — identical to the native export.
|
|
13
|
+
*/
|
|
14
|
+
beats(fps: number, frame_count: number): Beats;
|
|
15
|
+
/**
|
|
16
|
+
* Clip duration in seconds.
|
|
17
|
+
*/
|
|
18
|
+
duration_secs(): number;
|
|
19
|
+
/**
|
|
20
|
+
* Decode audio `bytes` (a fetched file / `Uint8Array`). `ext_hint` is the
|
|
21
|
+
* file extension (`"mp3"`, `"wav"`, …) to aid format detection — `""` is fine
|
|
22
|
+
* (content probing still runs). Throws if the bytes aren't decodable audio.
|
|
23
|
+
*/
|
|
24
|
+
constructor(bytes: Uint8Array, ext_hint: string);
|
|
25
|
+
/**
|
|
26
|
+
* Decoded sample rate (Hz).
|
|
27
|
+
*/
|
|
28
|
+
sample_rate(): number;
|
|
29
|
+
/**
|
|
30
|
+
* Per-frame spectrum: a flat, frame-major `Float32Array` of length
|
|
31
|
+
* `frame_count * bands`, each value `0..1` (low→high). `fps` maps a frame
|
|
32
|
+
* index to its time. Deterministic — identical to the native export.
|
|
33
|
+
*/
|
|
34
|
+
spectrogram(fps: number, frame_count: number, bands: number): Float32Array;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Beat / onset / tempo analysis of a clip, all in VIDEO-FRAME units. Returned by
|
|
39
|
+
* [`AudioAnalyzer::beats`]; read `tempo` + the typed arrays from JS.
|
|
40
|
+
*/
|
|
41
|
+
export class Beats {
|
|
42
|
+
private constructor();
|
|
43
|
+
free(): void;
|
|
44
|
+
[Symbol.dispose](): void;
|
|
45
|
+
/**
|
|
46
|
+
* Frame indices on the beat grid (`Uint32Array`).
|
|
47
|
+
*/
|
|
48
|
+
readonly beats: Uint32Array;
|
|
49
|
+
/**
|
|
50
|
+
* Per-frame onset strength `0..1`, one value per frame (`Float32Array`).
|
|
51
|
+
*/
|
|
52
|
+
readonly onsetEnv: Float32Array;
|
|
53
|
+
/**
|
|
54
|
+
* Frame indices of picked onsets — any transient (`Uint32Array`).
|
|
55
|
+
*/
|
|
56
|
+
readonly onsets: Uint32Array;
|
|
57
|
+
/**
|
|
58
|
+
* Estimated tempo in beats per minute (0 if undetectable).
|
|
59
|
+
*/
|
|
60
|
+
readonly tempo: number;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
64
|
+
|
|
65
|
+
export interface InitOutput {
|
|
66
|
+
readonly memory: WebAssembly.Memory;
|
|
67
|
+
readonly __wbg_audioanalyzer_free: (a: number, b: number) => void;
|
|
68
|
+
readonly __wbg_beats_free: (a: number, b: number) => void;
|
|
69
|
+
readonly audioanalyzer_beats: (a: number, b: number, c: number) => number;
|
|
70
|
+
readonly audioanalyzer_duration_secs: (a: number) => number;
|
|
71
|
+
readonly audioanalyzer_new: (a: number, b: number, c: number, d: number) => [number, number, number];
|
|
72
|
+
readonly audioanalyzer_sample_rate: (a: number) => number;
|
|
73
|
+
readonly audioanalyzer_spectrogram: (a: number, b: number, c: number, d: number) => [number, number];
|
|
74
|
+
readonly beats_beats: (a: number) => [number, number];
|
|
75
|
+
readonly beats_onsetEnv: (a: number) => [number, number];
|
|
76
|
+
readonly beats_onsets: (a: number) => [number, number];
|
|
77
|
+
readonly beats_tempo: (a: number) => number;
|
|
78
|
+
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
79
|
+
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
80
|
+
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
81
|
+
readonly __wbindgen_externrefs: WebAssembly.Table;
|
|
82
|
+
readonly __externref_table_dealloc: (a: number) => void;
|
|
83
|
+
readonly __wbindgen_start: () => void;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Instantiates the given `module`, which can either be bytes or
|
|
90
|
+
* a precompiled `WebAssembly.Module`.
|
|
91
|
+
*
|
|
92
|
+
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
93
|
+
*
|
|
94
|
+
* @returns {InitOutput}
|
|
95
|
+
*/
|
|
96
|
+
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
100
|
+
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
101
|
+
*
|
|
102
|
+
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
103
|
+
*
|
|
104
|
+
* @returns {Promise<InitOutput>}
|
|
105
|
+
*/
|
|
106
|
+
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
export const memory: WebAssembly.Memory;
|
|
4
|
+
export const __wbg_audioanalyzer_free: (a: number, b: number) => void;
|
|
5
|
+
export const __wbg_beats_free: (a: number, b: number) => void;
|
|
6
|
+
export const audioanalyzer_beats: (a: number, b: number, c: number) => number;
|
|
7
|
+
export const audioanalyzer_duration_secs: (a: number) => number;
|
|
8
|
+
export const audioanalyzer_new: (a: number, b: number, c: number, d: number) => [number, number, number];
|
|
9
|
+
export const audioanalyzer_sample_rate: (a: number) => number;
|
|
10
|
+
export const audioanalyzer_spectrogram: (a: number, b: number, c: number, d: number) => [number, number];
|
|
11
|
+
export const beats_beats: (a: number) => [number, number];
|
|
12
|
+
export const beats_onsetEnv: (a: number) => [number, number];
|
|
13
|
+
export const beats_onsets: (a: number) => [number, number];
|
|
14
|
+
export const beats_tempo: (a: number) => number;
|
|
15
|
+
export const __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
16
|
+
export const __wbindgen_malloc: (a: number, b: number) => number;
|
|
17
|
+
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
18
|
+
export const __wbindgen_externrefs: WebAssembly.Table;
|
|
19
|
+
export const __externref_table_dealloc: (a: number) => void;
|
|
20
|
+
export const __wbindgen_start: () => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, initSync, VelloEngine, RenderedFrame } from './pkg/onda_wasm_vello.js'
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A rendered frame: straight-alpha RGBA8 pixels (`width * height * 4`) plus
|
|
6
|
+
* dimensions — ready for an `ImageData` + `putImageData`.
|
|
7
|
+
*/
|
|
8
|
+
export class RenderedFrame {
|
|
9
|
+
private constructor();
|
|
10
|
+
free(): void;
|
|
11
|
+
[Symbol.dispose](): void;
|
|
12
|
+
readonly height: number;
|
|
13
|
+
readonly pixels: Uint8Array;
|
|
14
|
+
readonly width: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The GPU engine: holds a Vello renderer bound to a WebGPU device. Build it
|
|
19
|
+
* once with [`VelloEngine::create`] (async — it acquires the GPU), then reuse
|
|
20
|
+
* it across frames.
|
|
21
|
+
*/
|
|
22
|
+
export class VelloEngine {
|
|
23
|
+
private constructor();
|
|
24
|
+
free(): void;
|
|
25
|
+
[Symbol.dispose](): void;
|
|
26
|
+
/**
|
|
27
|
+
* Acquire a WebGPU device and build the renderer. Async (returns a JS
|
|
28
|
+
* `Promise`); rejects when WebGPU is unavailable so the caller can fall
|
|
29
|
+
* back to the CPU engine or Canvas2D.
|
|
30
|
+
*/
|
|
31
|
+
static create(): Promise<VelloEngine>;
|
|
32
|
+
/**
|
|
33
|
+
* Load an additional font (`.ttf`/`.otf` bytes) so text can select it by
|
|
34
|
+
* family (e.g. a premium display face for Apple-tier type). Returns the
|
|
35
|
+
* family name(s) it provides, newline-joined. Loaded into BOTH the renderer
|
|
36
|
+
* (which draws the glyphs) and the layout/measurement font context, so the
|
|
37
|
+
* in-browser preview's text metrics match what it draws.
|
|
38
|
+
*/
|
|
39
|
+
load_font(data: Uint8Array): string;
|
|
40
|
+
/**
|
|
41
|
+
* Render a scene-graph JSON document (onda-scene format) to a frame.
|
|
42
|
+
* Resolves `data:` images and flex layout first (the same pre-passes the
|
|
43
|
+
* CLI runs), so an in-browser preview matches `onda export`. Async: the GPU
|
|
44
|
+
* readback awaits the buffer map rather than blocking.
|
|
45
|
+
*/
|
|
46
|
+
render(scene_json: string): Promise<RenderedFrame>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
50
|
+
|
|
51
|
+
export interface InitOutput {
|
|
52
|
+
readonly memory: WebAssembly.Memory;
|
|
53
|
+
readonly __wbg_renderedframe_free: (a: number, b: number) => void;
|
|
54
|
+
readonly __wbg_velloengine_free: (a: number, b: number) => void;
|
|
55
|
+
readonly renderedframe_height: (a: number) => number;
|
|
56
|
+
readonly renderedframe_pixels: (a: number) => [number, number];
|
|
57
|
+
readonly renderedframe_width: (a: number) => number;
|
|
58
|
+
readonly velloengine_create: () => any;
|
|
59
|
+
readonly velloengine_load_font: (a: number, b: number, c: number) => [number, number];
|
|
60
|
+
readonly velloengine_render: (a: number, b: number, c: number) => any;
|
|
61
|
+
readonly wasm_bindgen__convert__closures_____invoke__hb7a70be5e517e2b6: (a: number, b: number, c: any) => [number, number];
|
|
62
|
+
readonly wasm_bindgen__convert__closures_____invoke__h4a9e248cef8c86eb: (a: number, b: number, c: any, d: any) => void;
|
|
63
|
+
readonly wasm_bindgen__convert__closures_____invoke__hc31f91f73c930b42: (a: number, b: number, c: any) => void;
|
|
64
|
+
readonly wasm_bindgen__convert__closures_____invoke__hc31f91f73c930b42_2: (a: number, b: number, c: any) => void;
|
|
65
|
+
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
66
|
+
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
67
|
+
readonly __wbindgen_exn_store: (a: number) => void;
|
|
68
|
+
readonly __externref_table_alloc: () => number;
|
|
69
|
+
readonly __wbindgen_externrefs: WebAssembly.Table;
|
|
70
|
+
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
71
|
+
readonly __wbindgen_destroy_closure: (a: number, b: number) => void;
|
|
72
|
+
readonly __externref_table_dealloc: (a: number) => void;
|
|
73
|
+
readonly __wbindgen_start: () => void;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Instantiates the given `module`, which can either be bytes or
|
|
80
|
+
* a precompiled `WebAssembly.Module`.
|
|
81
|
+
*
|
|
82
|
+
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
83
|
+
*
|
|
84
|
+
* @returns {InitOutput}
|
|
85
|
+
*/
|
|
86
|
+
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
90
|
+
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
91
|
+
*
|
|
92
|
+
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
93
|
+
*
|
|
94
|
+
* @returns {Promise<InitOutput>}
|
|
95
|
+
*/
|
|
96
|
+
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
export const memory: WebAssembly.Memory;
|
|
4
|
+
export const __wbg_renderedframe_free: (a: number, b: number) => void;
|
|
5
|
+
export const __wbg_velloengine_free: (a: number, b: number) => void;
|
|
6
|
+
export const renderedframe_height: (a: number) => number;
|
|
7
|
+
export const renderedframe_pixels: (a: number) => [number, number];
|
|
8
|
+
export const renderedframe_width: (a: number) => number;
|
|
9
|
+
export const velloengine_create: () => any;
|
|
10
|
+
export const velloengine_load_font: (a: number, b: number, c: number) => [number, number];
|
|
11
|
+
export const velloengine_render: (a: number, b: number, c: number) => any;
|
|
12
|
+
export const wasm_bindgen__convert__closures_____invoke__hb7a70be5e517e2b6: (a: number, b: number, c: any) => [number, number];
|
|
13
|
+
export const wasm_bindgen__convert__closures_____invoke__h4a9e248cef8c86eb: (a: number, b: number, c: any, d: any) => void;
|
|
14
|
+
export const wasm_bindgen__convert__closures_____invoke__hc31f91f73c930b42: (a: number, b: number, c: any) => void;
|
|
15
|
+
export const wasm_bindgen__convert__closures_____invoke__hc31f91f73c930b42_2: (a: number, b: number, c: any) => void;
|
|
16
|
+
export const __wbindgen_malloc: (a: number, b: number) => number;
|
|
17
|
+
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
18
|
+
export const __wbindgen_exn_store: (a: number) => void;
|
|
19
|
+
export const __externref_table_alloc: () => number;
|
|
20
|
+
export const __wbindgen_externrefs: WebAssembly.Table;
|
|
21
|
+
export const __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
22
|
+
export const __wbindgen_destroy_closure: (a: number, b: number) => void;
|
|
23
|
+
export const __externref_table_dealloc: (a: number) => void;
|
|
24
|
+
export const __wbindgen_start: () => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "onda-engine",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "The source-available motion graphics engine — GPU-native, scene-graph-first, framework-agnostic. One install for the whole engine: React renderer, motion-language components, player, renderer, and the wasm core.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"onda",
|
|
@@ -93,20 +93,20 @@
|
|
|
93
93
|
"@types/react-reconciler": "^0.33.0",
|
|
94
94
|
"tsup": "^8.3.5",
|
|
95
95
|
"typescript": "^5.7.2",
|
|
96
|
+
"@onda-engine/cinema": "0.1.3",
|
|
97
|
+
"@onda-engine/components": "0.3.0",
|
|
96
98
|
"@onda-engine/player": "0.1.1",
|
|
97
99
|
"@onda-engine/react": "0.1.1",
|
|
98
|
-
"@onda-engine/components": "0.3.0",
|
|
99
100
|
"@onda-engine/render": "0.1.1",
|
|
100
|
-
"@onda-engine/cinema": "0.1.3",
|
|
101
101
|
"@onda-engine/wasm-audio": "0.1.1",
|
|
102
|
-
"@onda-engine/wasm
|
|
103
|
-
"@onda-engine/wasm": "0.1.1"
|
|
102
|
+
"@onda-engine/wasm": "0.1.1",
|
|
103
|
+
"@onda-engine/wasm-vello": "0.1.1"
|
|
104
104
|
},
|
|
105
105
|
"publishConfig": {
|
|
106
106
|
"access": "public"
|
|
107
107
|
},
|
|
108
108
|
"scripts": {
|
|
109
|
-
"build": "tsup",
|
|
109
|
+
"build": "tsup && node scripts/copy-wasm.mjs",
|
|
110
110
|
"clean": "rm -rf dist"
|
|
111
111
|
}
|
|
112
112
|
}
|