@shotstack/shotstack-studio 2.0.0-beta.8 → 2.0.0-rc.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/dist/index.d.ts +143 -1943
- package/dist/internal.d.ts +476 -0
- package/dist/internal.es.js +45784 -0
- package/dist/internal.umd.js +228 -0
- package/dist/shotstack-studio.es.js +35721 -27668
- package/dist/shotstack-studio.umd.js +496 -258
- package/package.json +20 -17
- package/readme.md +151 -144
- package/dist/schema/assets/fonts/Arapey-Regular.ttf +0 -0
- package/dist/schema/assets/fonts/ClearSans-Regular.ttf +0 -0
- package/dist/schema/assets/fonts/DidactGothic-Regular.ttf +0 -0
- package/dist/schema/assets/fonts/Montserrat-ExtraBold.ttf +0 -0
- package/dist/schema/assets/fonts/Montserrat-SemiBold.ttf +0 -0
- package/dist/schema/assets/fonts/Montserrat.ttf +0 -0
- package/dist/schema/assets/fonts/MovLette.ttf +0 -0
- package/dist/schema/assets/fonts/OpenSans-Bold.ttf +0 -0
- package/dist/schema/assets/fonts/OpenSans.ttf +0 -0
- package/dist/schema/assets/fonts/PermanentMarker-Regular.ttf +0 -0
- package/dist/schema/assets/fonts/Roboto-BlackItalic.ttf +0 -0
- package/dist/schema/assets/fonts/Roboto.ttf +0 -0
- package/dist/schema/assets/fonts/SueEllenFrancisco.ttf +0 -0
- package/dist/schema/assets/fonts/UniNeue-Bold.otf +0 -0
- package/dist/schema/assets/fonts/WorkSans-Light.ttf +0 -0
- package/dist/schema/assets/fonts/WorkSans.ttf +0 -0
- package/dist/schema/assets/images/typescript.svg +0 -1
- package/dist/schema/hb.wasm +0 -0
- package/dist/schema/index.cjs +0 -1
- package/dist/schema/index.d.ts +0 -2475
- package/dist/schema/index.mjs +0 -1555
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"cpuccino",
|
|
6
6
|
"dazzatron"
|
|
7
7
|
],
|
|
8
|
-
"version": "2.0.0-
|
|
8
|
+
"version": "2.0.0-rc.1",
|
|
9
9
|
"description": "A video editing library for creating and editing videos with Shotstack",
|
|
10
10
|
"type": "module",
|
|
11
11
|
"main": "dist/shotstack-studio.umd.js",
|
|
@@ -18,17 +18,18 @@
|
|
|
18
18
|
"require": "./dist/shotstack-studio.umd.js",
|
|
19
19
|
"default": "./dist/shotstack-studio.es.js"
|
|
20
20
|
},
|
|
21
|
-
"./
|
|
22
|
-
"types": "./dist/
|
|
23
|
-
"import": "./dist/
|
|
24
|
-
"require": "./dist/
|
|
25
|
-
"default": "./dist/
|
|
21
|
+
"./internal": {
|
|
22
|
+
"types": "./dist/internal.d.ts",
|
|
23
|
+
"import": "./dist/internal.es.js",
|
|
24
|
+
"require": "./dist/internal.umd.js",
|
|
25
|
+
"default": "./dist/internal.es.js"
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"files": [
|
|
29
29
|
"dist/shotstack-studio.umd.js",
|
|
30
30
|
"dist/shotstack-studio.es.js",
|
|
31
|
-
"dist/
|
|
31
|
+
"dist/internal.umd.js",
|
|
32
|
+
"dist/internal.es.js",
|
|
32
33
|
"dist/**/*.d.ts"
|
|
33
34
|
],
|
|
34
35
|
"keywords": [
|
|
@@ -38,16 +39,20 @@
|
|
|
38
39
|
"ffmpeg"
|
|
39
40
|
],
|
|
40
41
|
"license": "PolyForm Shield License 1.0.0",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=22 <23"
|
|
44
|
+
},
|
|
41
45
|
"repository": {
|
|
42
46
|
"type": "git",
|
|
43
47
|
"url": "https://github.com/shotstack/shotstack-studio-sdk"
|
|
44
48
|
},
|
|
45
49
|
"scripts": {
|
|
46
50
|
"dev": "vite",
|
|
51
|
+
"dev:shotstack": "vite --open /shotstack.html",
|
|
47
52
|
"start": "npm run build && vite preview",
|
|
48
|
-
"build": "npm run build:main && npm run build:
|
|
53
|
+
"build": "npm run build:main && npm run build:internal",
|
|
49
54
|
"build:main": "vite build",
|
|
50
|
-
"build:
|
|
55
|
+
"build:internal": "node scripts/build-internal.mjs",
|
|
51
56
|
"test": "jest",
|
|
52
57
|
"test:watch": "jest --watch",
|
|
53
58
|
"test:package": "node test-package.js",
|
|
@@ -55,11 +60,12 @@
|
|
|
55
60
|
"lint": "eslint --ignore-path .gitignore .",
|
|
56
61
|
"lint:fix": "eslint --ignore-path .gitignore --fix .",
|
|
57
62
|
"format": "prettier --ignore-path .gitignore --write .",
|
|
58
|
-
"
|
|
63
|
+
"verify:ci": "npm run lint && npm run typecheck && npm run test && npm run build && npm run test:package",
|
|
64
|
+
"release:check": "npm run verify:ci && npm pack --dry-run --json",
|
|
65
|
+
"prepublishOnly": "npm run release:check",
|
|
59
66
|
"generate:fonts": "npx tsx scripts/fetch-google-fonts.ts"
|
|
60
67
|
},
|
|
61
68
|
"devDependencies": {
|
|
62
|
-
"@jest/globals": "^30.2.0",
|
|
63
69
|
"@types/howler": "^2.2.12",
|
|
64
70
|
"@types/jest": "^30.0.0",
|
|
65
71
|
"@types/node": "^22.9.0",
|
|
@@ -80,16 +86,13 @@
|
|
|
80
86
|
"vite-plugin-dts": "^4.5.4"
|
|
81
87
|
},
|
|
82
88
|
"dependencies": {
|
|
83
|
-
"@
|
|
84
|
-
"@shotstack/
|
|
85
|
-
"@shotstack/shotstack-canvas": "^1.8.0",
|
|
86
|
-
"fast-deep-equal": "^3.1.3",
|
|
89
|
+
"@shotstack/schemas": "1.7.0",
|
|
90
|
+
"@shotstack/shotstack-canvas": "^1.9.6",
|
|
87
91
|
"howler": "^2.2.4",
|
|
88
92
|
"mediabunny": "^1.11.2",
|
|
89
|
-
"opentype": "^0.1.2",
|
|
90
93
|
"opentype.js": "^1.3.4",
|
|
91
94
|
"pixi-filters": "^6.0.5",
|
|
92
|
-
"pixi.js": "^8.
|
|
95
|
+
"pixi.js": "^8.15.0",
|
|
93
96
|
"zod": "^4.0.0"
|
|
94
97
|
}
|
|
95
98
|
}
|
package/readme.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://polyformproject.org/licenses/shield/1.0.0/)
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
|
|
7
|
-
A JavaScript
|
|
7
|
+
A JavaScript SDK for browser-based video editing with timeline, canvas preview, and export.
|
|
8
8
|
|
|
9
9
|
## Interactive Examples
|
|
10
10
|
|
|
@@ -18,11 +18,11 @@ Try Shotstack Studio in your preferred framework:
|
|
|
18
18
|
|
|
19
19
|
## Features
|
|
20
20
|
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
21
|
+
- Template-driven editing with undo/redo command model
|
|
22
|
+
- Canvas preview rendering
|
|
23
|
+
- Visual timeline with drag, resize, selection, and snapping
|
|
24
|
+
- Extensible UI via `UIController` button API
|
|
25
|
+
- Browser export pipeline via `VideoExporter`
|
|
26
26
|
|
|
27
27
|
## Installation
|
|
28
28
|
|
|
@@ -37,33 +37,57 @@ yarn add @shotstack/shotstack-studio
|
|
|
37
37
|
## Quick Start
|
|
38
38
|
|
|
39
39
|
```typescript
|
|
40
|
-
import { Edit, Canvas, Controls, Timeline } from "@shotstack/shotstack-studio";
|
|
40
|
+
import { Edit, Canvas, Controls, Timeline, UIController } from "@shotstack/shotstack-studio";
|
|
41
41
|
|
|
42
|
-
// 1
|
|
42
|
+
// 1) Load a template
|
|
43
43
|
const response = await fetch("https://shotstack-assets.s3.amazonaws.com/templates/hello-world/hello.json");
|
|
44
44
|
const template = await response.json();
|
|
45
45
|
|
|
46
|
-
// 2
|
|
46
|
+
// 2) Create core components
|
|
47
47
|
const edit = new Edit(template);
|
|
48
|
+
const canvas = new Canvas(edit);
|
|
49
|
+
const ui = UIController.create(edit, canvas);
|
|
50
|
+
|
|
51
|
+
// 3) Load runtime
|
|
52
|
+
await canvas.load();
|
|
48
53
|
await edit.load();
|
|
49
54
|
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
// 4) Add one custom UI button
|
|
56
|
+
ui.registerButton({
|
|
57
|
+
id: "text",
|
|
58
|
+
icon: `<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3H13"/><path d="M8 3V13"/><path d="M5 13H11"/></svg>`,
|
|
59
|
+
tooltip: "Add Text"
|
|
60
|
+
});
|
|
53
61
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
ui.on("button:text", ({ position }) => {
|
|
63
|
+
edit.addTrack(0, {
|
|
64
|
+
clips: [
|
|
65
|
+
{
|
|
66
|
+
asset: {
|
|
67
|
+
type: "rich-text",
|
|
68
|
+
text: "Title",
|
|
69
|
+
font: { family: "Work Sans", size: 72, weight: 600, color: "#ffffff", opacity: 1 },
|
|
70
|
+
align: { horizontal: "center", vertical: "middle" }
|
|
71
|
+
},
|
|
72
|
+
start: position,
|
|
73
|
+
length: 5,
|
|
74
|
+
width: 500,
|
|
75
|
+
height: 200
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
});
|
|
58
79
|
});
|
|
80
|
+
|
|
81
|
+
// 5) Timeline + controls
|
|
82
|
+
const timelineContainer = document.querySelector("[data-shotstack-timeline]") as HTMLElement;
|
|
83
|
+
const timeline = new Timeline(edit, timelineContainer);
|
|
59
84
|
await timeline.load();
|
|
60
85
|
|
|
61
|
-
// 5. Add keyboard controls
|
|
62
86
|
const controls = new Controls(edit);
|
|
63
87
|
await controls.load();
|
|
64
88
|
```
|
|
65
89
|
|
|
66
|
-
Your HTML
|
|
90
|
+
Your HTML must include both containers:
|
|
67
91
|
|
|
68
92
|
```html
|
|
69
93
|
<div data-shotstack-studio></div>
|
|
@@ -74,185 +98,159 @@ Your HTML should include containers for both the canvas and timeline:
|
|
|
74
98
|
|
|
75
99
|
### Edit
|
|
76
100
|
|
|
77
|
-
|
|
101
|
+
`Edit` is the runtime editing session and source of truth for document mutations.
|
|
78
102
|
|
|
79
103
|
```typescript
|
|
80
104
|
import { Edit } from "@shotstack/shotstack-studio";
|
|
81
105
|
|
|
82
|
-
// Create an edit from a template
|
|
83
106
|
const edit = new Edit(templateJson);
|
|
84
107
|
await edit.load();
|
|
85
108
|
|
|
86
|
-
|
|
87
|
-
await edit.loadEdit(newTemplate);
|
|
109
|
+
await edit.loadEdit(nextTemplateJson);
|
|
88
110
|
|
|
89
|
-
// Playback
|
|
111
|
+
// Playback (seconds)
|
|
90
112
|
edit.play();
|
|
91
113
|
edit.pause();
|
|
92
|
-
edit.seek(
|
|
93
|
-
edit.stop();
|
|
94
|
-
|
|
95
|
-
//
|
|
96
|
-
edit.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
src: "https://example.com/image.jpg"
|
|
100
|
-
},
|
|
114
|
+
edit.seek(2);
|
|
115
|
+
edit.stop();
|
|
116
|
+
|
|
117
|
+
// Mutations
|
|
118
|
+
await edit.addTrack(0, { clips: [] });
|
|
119
|
+
await edit.addClip(0, {
|
|
120
|
+
asset: { type: "image", src: "https://example.com/image.jpg" },
|
|
101
121
|
start: 0,
|
|
102
122
|
length: 5
|
|
103
123
|
});
|
|
124
|
+
await edit.updateClip(0, 0, { length: 6 });
|
|
125
|
+
await edit.deleteClip(0, 0);
|
|
104
126
|
|
|
105
|
-
|
|
106
|
-
edit.
|
|
107
|
-
edit.
|
|
108
|
-
|
|
109
|
-
// Undo/Redo
|
|
110
|
-
edit.undo();
|
|
111
|
-
edit.redo();
|
|
112
|
-
edit.canUndo(); // Check if undo is available (useful for UI)
|
|
113
|
-
edit.canRedo(); // Check if redo is available
|
|
127
|
+
// History
|
|
128
|
+
await edit.undo();
|
|
129
|
+
await edit.redo();
|
|
114
130
|
|
|
115
|
-
//
|
|
131
|
+
// Read state
|
|
116
132
|
const clip = edit.getClip(0, 0);
|
|
117
133
|
const track = edit.getTrack(0);
|
|
118
|
-
const
|
|
119
|
-
const
|
|
134
|
+
const snapshot = edit.getEdit();
|
|
135
|
+
const durationSeconds = edit.totalDuration;
|
|
120
136
|
```
|
|
121
137
|
|
|
122
138
|
#### Events
|
|
123
139
|
|
|
124
|
-
|
|
140
|
+
Listen using string event names:
|
|
125
141
|
|
|
126
142
|
```typescript
|
|
127
|
-
|
|
143
|
+
const unsubscribeClipSelected = edit.events.on("clip:selected", data => {
|
|
144
|
+
console.log("Selected clip", data.trackIndex, data.clipIndex);
|
|
145
|
+
});
|
|
128
146
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
console.log("Clip selected:", data.clip);
|
|
132
|
-
console.log("Track index:", data.trackIndex);
|
|
133
|
-
console.log("Clip index:", data.clipIndex);
|
|
147
|
+
edit.events.on("clip:updated", data => {
|
|
148
|
+
console.log("Updated from", data.previous, "to", data.current);
|
|
134
149
|
});
|
|
135
150
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
console.log("Previous state:", data.previous);
|
|
139
|
-
console.log("Current state:", data.current);
|
|
151
|
+
edit.events.on("playback:play", () => {
|
|
152
|
+
console.log("Playback started");
|
|
140
153
|
});
|
|
141
154
|
|
|
142
|
-
//
|
|
143
|
-
|
|
144
|
-
edit.events.on(EditEvent.PlaybackPause, () => console.log("Paused"));
|
|
155
|
+
// Unsubscribe when no longer needed
|
|
156
|
+
unsubscribeClipSelected();
|
|
145
157
|
```
|
|
146
158
|
|
|
147
|
-
Available
|
|
148
|
-
|
|
149
|
-
**Playback:** `PlaybackPlay`, `PlaybackPause`
|
|
150
|
-
|
|
151
|
-
**Clips:** `ClipAdded`, `ClipDeleted`, `ClipSelected`, `ClipUpdated`, `ClipCopied`, `ClipSplit`, `ClipRestored`
|
|
152
|
-
|
|
153
|
-
**Selection:** `SelectionCleared`
|
|
154
|
-
|
|
155
|
-
**Edit State:** `EditChanged`, `EditUndo`, `EditRedo`
|
|
159
|
+
Available event names:
|
|
156
160
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
161
|
+
- Playback: `playback:play`, `playback:pause`
|
|
162
|
+
- Timeline: `timeline:updated`, `timeline:backgroundChanged`
|
|
163
|
+
- Clip lifecycle: `clip:added`, `clip:split`, `clip:selected`, `clip:updated`, `clip:deleted`, `clip:restored`, `clip:copied`, `clip:loadFailed`, `clip:unresolved`
|
|
164
|
+
- Selection: `selection:cleared`
|
|
165
|
+
- Edit state: `edit:changed`, `edit:undo`, `edit:redo`
|
|
166
|
+
- Track: `track:added`, `track:removed`
|
|
167
|
+
- Duration: `duration:changed`
|
|
168
|
+
- Output: `output:resized`, `output:resolutionChanged`, `output:aspectRatioChanged`, `output:fpsChanged`, `output:formatChanged`, `output:destinationsChanged`
|
|
169
|
+
- Merge fields: `mergefield:changed`
|
|
170
|
+
- Luma masking: `luma:attached`, `luma:detached`
|
|
166
171
|
|
|
167
172
|
### Canvas
|
|
168
173
|
|
|
169
|
-
|
|
174
|
+
`Canvas` renders the current edit.
|
|
170
175
|
|
|
171
176
|
```typescript
|
|
172
|
-
|
|
177
|
+
import { Canvas } from "@shotstack/shotstack-studio";
|
|
178
|
+
|
|
173
179
|
const canvas = new Canvas(edit);
|
|
174
180
|
await canvas.load();
|
|
175
181
|
|
|
176
|
-
// Zoom and positioning
|
|
177
182
|
canvas.centerEdit();
|
|
178
183
|
canvas.zoomToFit();
|
|
179
|
-
canvas.setZoom(1.
|
|
180
|
-
canvas.
|
|
184
|
+
canvas.setZoom(1.25);
|
|
185
|
+
canvas.resize();
|
|
186
|
+
canvas.dispose();
|
|
181
187
|
```
|
|
182
188
|
|
|
183
|
-
###
|
|
189
|
+
### UIController
|
|
184
190
|
|
|
185
|
-
|
|
191
|
+
`UIController` manages built-in UI wiring and extensible button events.
|
|
186
192
|
|
|
187
193
|
```typescript
|
|
188
|
-
|
|
189
|
-
|
|
194
|
+
import { UIController } from "@shotstack/shotstack-studio";
|
|
195
|
+
|
|
196
|
+
const ui = UIController.create(edit, canvas, { mergeFields: true });
|
|
197
|
+
|
|
198
|
+
ui.registerButton({
|
|
199
|
+
id: "add-title",
|
|
200
|
+
icon: `<svg viewBox="0 0 16 16">...</svg>`,
|
|
201
|
+
tooltip: "Add Title"
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
const unsubscribe = ui.on("button:add-title", ({ position }) => {
|
|
205
|
+
console.log("Button clicked at", position, "seconds");
|
|
206
|
+
});
|
|
190
207
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
// K - Pause
|
|
195
|
-
// L - Play
|
|
196
|
-
// Left Arrow - Seek backward
|
|
197
|
-
// Right Arrow - Seek forward
|
|
198
|
-
// Shift + Arrow - Seek larger amount
|
|
199
|
-
// Comma - Step backward one frame
|
|
200
|
-
// Period - Step forward one frame
|
|
201
|
-
// Cmd/Ctrl + Z - Undo
|
|
202
|
-
// Cmd/Ctrl + Shift + Z - Redo
|
|
203
|
-
// Cmd/Ctrl + E - Export/download video
|
|
208
|
+
ui.unregisterButton("add-title");
|
|
209
|
+
unsubscribe();
|
|
210
|
+
ui.dispose();
|
|
204
211
|
```
|
|
205
212
|
|
|
206
213
|
### Timeline
|
|
207
214
|
|
|
208
|
-
|
|
215
|
+
`Timeline` provides visual clip editing.
|
|
209
216
|
|
|
210
217
|
```typescript
|
|
211
218
|
import { Timeline } from "@shotstack/shotstack-studio";
|
|
212
219
|
|
|
213
|
-
const container = document.querySelector("[data-shotstack-timeline]");
|
|
214
|
-
const timeline = new Timeline(edit, container
|
|
215
|
-
|
|
216
|
-
toolbar: true, // Playback controls and editing buttons
|
|
217
|
-
ruler: true, // Time ruler with markers
|
|
218
|
-
playhead: true, // Draggable playhead
|
|
219
|
-
snap: true, // Snap clips to grid and other clips
|
|
220
|
-
badges: true // Asset type badges on clips
|
|
221
|
-
}
|
|
222
|
-
});
|
|
220
|
+
const container = document.querySelector("[data-shotstack-timeline]") as HTMLElement;
|
|
221
|
+
const timeline = new Timeline(edit, container);
|
|
222
|
+
|
|
223
223
|
await timeline.load();
|
|
224
|
+
timeline.zoomIn();
|
|
225
|
+
timeline.zoomOut();
|
|
226
|
+
timeline.dispose();
|
|
224
227
|
```
|
|
225
228
|
|
|
226
|
-
###
|
|
229
|
+
### Controls
|
|
227
230
|
|
|
228
|
-
|
|
231
|
+
`Controls` enables keyboard playback/edit shortcuts.
|
|
229
232
|
|
|
230
233
|
```typescript
|
|
231
|
-
|
|
232
|
-
|
|
234
|
+
import { Controls } from "@shotstack/shotstack-studio";
|
|
235
|
+
|
|
236
|
+
const controls = new Controls(edit);
|
|
237
|
+
await controls.load();
|
|
233
238
|
```
|
|
234
239
|
|
|
235
|
-
|
|
240
|
+
### VideoExporter
|
|
236
241
|
|
|
237
|
-
|
|
242
|
+
`VideoExporter` exports a timeline render from the browser runtime.
|
|
238
243
|
|
|
239
244
|
```typescript
|
|
240
|
-
import {
|
|
245
|
+
import { VideoExporter } from "@shotstack/shotstack-studio";
|
|
241
246
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
edit.setMergeField("SUBTITLE", "A great subtitle");
|
|
245
|
-
|
|
246
|
-
// Get all registered merge fields
|
|
247
|
-
const fields = edit.getMergeFields();
|
|
248
|
-
|
|
249
|
-
// Listen for merge field changes
|
|
250
|
-
edit.events.on(EditEvent.MergeFieldUpdated, ({ field }) => {
|
|
251
|
-
console.log(`Field ${field.name} updated to:`, field.value);
|
|
252
|
-
});
|
|
247
|
+
const exporter = new VideoExporter(edit, canvas);
|
|
248
|
+
await exporter.export("my-video.mp4", 25);
|
|
253
249
|
```
|
|
254
250
|
|
|
255
|
-
|
|
251
|
+
## Merge Fields
|
|
252
|
+
|
|
253
|
+
Merge fields are template placeholders, typically in the form `{{ FIELD_NAME }}`.
|
|
256
254
|
|
|
257
255
|
```json
|
|
258
256
|
{
|
|
@@ -263,34 +261,43 @@ In templates, use placeholders that will be replaced with merge field values:
|
|
|
263
261
|
}
|
|
264
262
|
```
|
|
265
263
|
|
|
266
|
-
|
|
264
|
+
When merge-field-aware UI is required, enable it via `UIController` options:
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
const ui = UIController.create(edit, canvas, { mergeFields: true });
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
You can also subscribe to merge field events when integrations update merge data:
|
|
267
271
|
|
|
268
|
-
|
|
272
|
+
```typescript
|
|
273
|
+
edit.events.on("mergefield:changed", ({ fields }) => {
|
|
274
|
+
console.log("Merge fields updated:", fields.length);
|
|
275
|
+
});
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Custom UI Buttons
|
|
279
|
+
|
|
280
|
+
Use `UIController` to register and handle custom button actions.
|
|
269
281
|
|
|
270
282
|
```typescript
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
id: "add-text",
|
|
283
|
+
ui.registerButton({
|
|
284
|
+
id: "text",
|
|
274
285
|
icon: `<svg viewBox="0 0 16 16">...</svg>`,
|
|
275
286
|
tooltip: "Add Text",
|
|
276
|
-
|
|
277
|
-
dividerBefore: true // Optional: add a divider before this button
|
|
287
|
+
dividerBefore: true
|
|
278
288
|
});
|
|
279
289
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
edit.addClip(0, {
|
|
284
|
-
asset: { type: "text", text: "New Text" },
|
|
285
|
-
start: position / 1000,
|
|
286
|
-
length: 5
|
|
287
|
-
});
|
|
290
|
+
ui.on("button:text", ({ position, selectedClip }) => {
|
|
291
|
+
console.log("Current time (seconds):", position);
|
|
292
|
+
console.log("Current selection:", selectedClip);
|
|
288
293
|
});
|
|
294
|
+
|
|
295
|
+
ui.unregisterButton("text");
|
|
289
296
|
```
|
|
290
297
|
|
|
291
298
|
## API Reference
|
|
292
299
|
|
|
293
|
-
For
|
|
300
|
+
For schema-level details and type definitions, see the [Shotstack API Reference](https://shotstack.io/docs/api/#tocs_edit).
|
|
294
301
|
|
|
295
302
|
## License
|
|
296
303
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path fill="#007ACC" d="M0 128v128h256V0H0z"></path><path fill="#FFF" d="m56.612 128.85l-.081 10.483h33.32v94.68h23.568v-94.68h33.321v-10.28c0-5.69-.122-10.444-.284-10.566c-.122-.162-20.4-.244-44.983-.203l-44.74.122l-.121 10.443Zm149.955-10.742c6.501 1.625 11.459 4.51 16.01 9.224c2.357 2.52 5.851 7.111 6.136 8.208c.08.325-11.053 7.802-17.798 11.988c-.244.162-1.22-.894-2.317-2.52c-3.291-4.795-6.745-6.867-12.028-7.233c-7.76-.528-12.759 3.535-12.718 10.321c0 1.992.284 3.17 1.097 4.795c1.707 3.536 4.876 5.649 14.832 9.956c18.326 7.883 26.168 13.084 31.045 20.48c5.445 8.249 6.664 21.415 2.966 31.208c-4.063 10.646-14.14 17.879-28.323 20.276c-4.388.772-14.79.65-19.504-.203c-10.28-1.828-20.033-6.908-26.047-13.572c-2.357-2.6-6.949-9.387-6.664-9.874c.122-.163 1.178-.813 2.356-1.504c1.138-.65 5.446-3.129 9.509-5.485l7.355-4.267l1.544 2.276c2.154 3.29 6.867 7.801 9.712 9.305c8.167 4.307 19.383 3.698 24.909-1.26c2.357-2.153 3.332-4.388 3.332-7.68c0-2.966-.366-4.266-1.91-6.501c-1.99-2.845-6.054-5.242-17.595-10.24c-13.206-5.69-18.895-9.224-24.096-14.832c-3.007-3.25-5.852-8.452-7.03-12.8c-.975-3.617-1.22-12.678-.447-16.335c2.723-12.76 12.353-21.659 26.25-24.3c4.51-.853 14.994-.528 19.424.569Z"></path></svg>
|
package/dist/schema/hb.wasm
DELETED
|
Binary file
|