@pixerate/editor 0.229.0 → 0.231.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/dist/animation-editor/camera-tools.d.cts +10 -0
- package/dist/animation-editor/camera-tools.d.ts +10 -0
- package/dist/animation-editor/camera.d.cts +67 -0
- package/dist/animation-editor/camera.d.ts +67 -0
- package/dist/animation-editor/compile.d.cts +4 -0
- package/dist/animation-editor/compile.d.ts +4 -0
- package/dist/animation-editor/controller.d.cts +34 -2
- package/dist/animation-editor/controller.d.ts +34 -2
- package/dist/animation-editor/effect-tools.d.cts +2 -1
- package/dist/animation-editor/effect-tools.d.ts +2 -1
- package/dist/animation-editor/evaluate.d.cts +9 -0
- package/dist/animation-editor/evaluate.d.ts +9 -0
- package/dist/animation-editor/flair.d.cts +8 -0
- package/dist/animation-editor/flair.d.ts +8 -0
- package/dist/animation-editor/index.cjs +603 -217
- package/dist/animation-editor/index.d.cts +2 -0
- package/dist/animation-editor/index.d.ts +2 -0
- package/dist/animation-editor/index.js +454 -68
- package/dist/animation-editor/issues.d.cts +16 -0
- package/dist/animation-editor/issues.d.ts +16 -0
- package/dist/animation-editor/tools.d.cts +1 -1
- package/dist/animation-editor/tools.d.ts +1 -1
- package/dist/animation-editor/types.d.cts +21 -3
- package/dist/animation-editor/types.d.ts +21 -3
- package/dist/canvas/index.cjs +7 -7
- package/dist/canvas/index.js +1 -1
- package/dist/{chunk-IGPEBXUD.cjs → chunk-5T3H7CGG.cjs} +21 -11
- package/dist/{chunk-K5GXW5TR.cjs → chunk-C73U5UI3.cjs} +14 -14
- package/dist/{chunk-LPTFDCJO.js → chunk-CSM5T6SE.js} +14 -4
- package/dist/{chunk-EBDZWIOP.cjs → chunk-ERJA5CGT.cjs} +5 -1
- package/dist/{chunk-5MQOBTNP.cjs → chunk-OPSK22DL.cjs} +80 -9
- package/dist/{chunk-PB6JV62G.js → chunk-SBPGIZQN.js} +1 -1
- package/dist/{chunk-UGYUGZE2.js → chunk-TCZ2J7PR.js} +71 -0
- package/dist/{chunk-W4KFNAWC.js → chunk-TYCJGFCF.js} +5 -1
- package/dist/effects/helpers.d.cts +35 -1
- package/dist/effects/helpers.d.ts +35 -1
- package/dist/effects/index.cjs +60 -44
- package/dist/effects/index.js +18 -2
- package/dist/effects/types.d.cts +15 -0
- package/dist/effects/types.d.ts +15 -0
- package/dist/image-editor/index.cjs +13 -13
- package/dist/image-editor/index.js +1 -1
- package/dist/paint-editor/index.cjs +7 -7
- package/dist/paint-editor/index.js +2 -2
- package/dist/vector/index.cjs +6 -6
- package/dist/vector/index.js +1 -1
- package/dist/video-editor/camera-tools.d.cts +10 -0
- package/dist/video-editor/camera-tools.d.ts +10 -0
- package/dist/video-editor/camera.d.cts +47 -0
- package/dist/video-editor/camera.d.ts +47 -0
- package/dist/video-editor/check.d.cts +1 -1
- package/dist/video-editor/check.d.ts +1 -1
- package/dist/video-editor/controller.d.cts +37 -2
- package/dist/video-editor/controller.d.ts +37 -2
- package/dist/video-editor/effect-tools.d.cts +2 -1
- package/dist/video-editor/effect-tools.d.ts +2 -1
- package/dist/video-editor/index.cjs +705 -390
- package/dist/video-editor/index.d.cts +2 -0
- package/dist/video-editor/index.d.ts +2 -0
- package/dist/video-editor/index.js +334 -19
- package/dist/video-editor/keyframes.d.cts +10 -3
- package/dist/video-editor/keyframes.d.ts +10 -3
- package/dist/video-editor/parse.d.cts +5 -3
- package/dist/video-editor/parse.d.ts +5 -3
- package/dist/video-editor/tools.d.cts +18 -0
- package/dist/video-editor/tools.d.ts +18 -0
- package/dist/video-editor/types.d.cts +37 -1
- package/dist/video-editor/types.d.ts +37 -1
- package/package.json +1 -1
- package/skills/pixerate-animation-editor/SKILL.md +28 -1
- package/skills/pixerate-animation-motion-graphics/SKILL.md +3 -0
- package/skills/pixerate-video-editor/SKILL.md +16 -1
- package/skills/pixerate-video-montage/SKILL.md +2 -1
|
@@ -209,6 +209,69 @@ async function sampleEffectCameraMove(provider, id, request) {
|
|
|
209
209
|
const { from, to, ms, stage, values } = request;
|
|
210
210
|
return sampleCameraViews((u) => provider.cameraView(id, { from, to, u, ms, stage }, values), { ms, fps: request.fps, cut: d.camera.cut });
|
|
211
211
|
}
|
|
212
|
+
var cameraMoveField = (role) => role === "transition" ? "in" : "during";
|
|
213
|
+
function cameraMovesFor(catalog, role) {
|
|
214
|
+
return catalog.filter((e) => e.kind === "camera" && _optionalChain([e, 'access', _2 => _2.camera, 'optionalAccess', _3 => _3.role]) === role);
|
|
215
|
+
}
|
|
216
|
+
function cameraMoveIdList(catalog, role) {
|
|
217
|
+
const ids = cameraMovesFor(catalog, role).map((e) => JSON.stringify(e.id));
|
|
218
|
+
return ids.length ? ids.join(", ") : "none (the provider has no camera moves of that role)";
|
|
219
|
+
}
|
|
220
|
+
function cameraMoveParts(spec) {
|
|
221
|
+
if (typeof spec === "string") return spec ? { move: spec } : void 0;
|
|
222
|
+
if (spec && typeof spec === "object" && !Array.isArray(spec) && typeof spec.move === "string") return spec;
|
|
223
|
+
return void 0;
|
|
224
|
+
}
|
|
225
|
+
var CAMERA_MOVE_MAX_MS = 6e4;
|
|
226
|
+
async function resolveCameraMoveSpec(provider, spec, role) {
|
|
227
|
+
const field = cameraMoveField(role);
|
|
228
|
+
if (!provider.capabilities.supportsCamera || !provider.cameraView) throw new EffectUnsupportedError(`${provider.name} has no camera moves (capabilities.supportsCamera is not set), so camera "${field}" cannot be set.`);
|
|
229
|
+
const parts = cameraMoveParts(spec);
|
|
230
|
+
const catalog = await provider.list({ kind: "camera" });
|
|
231
|
+
if (!parts) throw new EffectUnsupportedError(`Camera "${field}" is a camera move's id, or { move, ms?, preset?, values? }; it takes one of ${cameraMoveIdList(catalog, role)}.`);
|
|
232
|
+
let description;
|
|
233
|
+
try {
|
|
234
|
+
description = await provider.describe(parts.move);
|
|
235
|
+
} catch (error) {
|
|
236
|
+
if (error instanceof UnknownEffectError || error.code === "unknown_effect")
|
|
237
|
+
throw new EffectError("unknown_effect", `There is no camera move "${parts.move}"; camera "${field}" takes one of ${cameraMoveIdList(catalog, role)}.`, parts.move);
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
if (description.kind !== "camera" || !description.camera) throw new EffectUnsupportedError(`"${parts.move}" is a ${description.kind} effect, not a camera move; camera "${field}" takes one of ${cameraMoveIdList(catalog, role)}.`, parts.move);
|
|
241
|
+
if (description.camera.role !== role) {
|
|
242
|
+
const other = cameraMoveField(description.camera.role);
|
|
243
|
+
throw new EffectUnsupportedError(
|
|
244
|
+
`"${parts.move}" moves the camera ${description.camera.role === "hold" ? "while a shot holds" : "into a shot"}, so it goes in camera "${other}", not "${field}"; camera "${field}" takes one of ${cameraMoveIdList(catalog, role)}.`,
|
|
245
|
+
parts.move
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
if (parts.ms !== void 0) {
|
|
249
|
+
if (role === "hold") throw new EffectUnsupportedError(`A move while the shot holds plays across the shot's hold; set the hold's length instead of "ms".`, parts.move);
|
|
250
|
+
if (!(typeof parts.ms === "number" && Number.isFinite(parts.ms) && parts.ms >= 0 && parts.ms <= CAMERA_MOVE_MAX_MS))
|
|
251
|
+
throw new EffectUnsupportedError(`Camera "in" ms is how long the move takes, 0 to ${CAMERA_MOVE_MAX_MS} (default ${description.camera.durationMs} for "${parts.move}").`, parts.move);
|
|
252
|
+
}
|
|
253
|
+
let presetValues = {};
|
|
254
|
+
if (parts.preset !== void 0) {
|
|
255
|
+
const preset = description.presets.find((p) => p.name === parts.preset);
|
|
256
|
+
if (!preset) throw new EffectUnsupportedError(`"${parts.move}" has no preset ${JSON.stringify(parts.preset)}; its presets are ${description.presets.length ? description.presets.map((p) => JSON.stringify(p.name)).join(", ") : "none"}.`, parts.move);
|
|
257
|
+
presetValues = preset.values;
|
|
258
|
+
}
|
|
259
|
+
const values = { ...presetValues, ..._nullishCoalesce(parts.values, () => ( {})) };
|
|
260
|
+
resolveEffectValues(description, values);
|
|
261
|
+
return {
|
|
262
|
+
spec: { move: description.id, ...parts.ms !== void 0 ? { ms: parts.ms } : {}, ...parts.preset !== void 0 ? { preset: parts.preset } : {}, ...Object.keys(values).length ? { values } : {} },
|
|
263
|
+
description
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function cameraViewOfBox(box, stage) {
|
|
267
|
+
const zoom = Math.min(stage.width / box.width, stage.height / box.height);
|
|
268
|
+
return { zoom, scrollX: stage.width / (2 * zoom) - (box.x + box.width / 2), scrollY: stage.height / (2 * zoom) - (box.y + box.height / 2) };
|
|
269
|
+
}
|
|
270
|
+
function cameraBoxOfView(view, stage) {
|
|
271
|
+
const width = stage.width / view.zoom;
|
|
272
|
+
const height = stage.height / view.zoom;
|
|
273
|
+
return { x: -view.scrollX, y: -view.scrollY, width, height };
|
|
274
|
+
}
|
|
212
275
|
|
|
213
276
|
// src/effects/types.ts
|
|
214
277
|
var EFFECT_KINDS = ["shader", "vector", "motion", "camera"];
|
|
@@ -243,7 +306,7 @@ var summaryOut = (e) => ({
|
|
|
243
306
|
category: e.category,
|
|
244
307
|
uses: e.uses,
|
|
245
308
|
...e.description ? { description: e.description } : {},
|
|
246
|
-
..._optionalChain([e, 'access',
|
|
309
|
+
..._optionalChain([e, 'access', _4 => _4.tags, 'optionalAccess', _5 => _5.length]) ? { tags: e.tags } : {},
|
|
247
310
|
transparent: e.transparent,
|
|
248
311
|
loop: e.loop,
|
|
249
312
|
...e.duration !== void 0 ? { duration: e.duration } : {},
|
|
@@ -255,7 +318,7 @@ function createEffectToolProvider(host) {
|
|
|
255
318
|
const notify = () => listeners.forEach((l) => l());
|
|
256
319
|
const catalogFor = (provider) => {
|
|
257
320
|
if (!provider) return null;
|
|
258
|
-
if (_optionalChain([catalog, 'optionalAccess',
|
|
321
|
+
if (_optionalChain([catalog, 'optionalAccess', _6 => _6.provider]) !== provider) {
|
|
259
322
|
const entry = { provider, effects: null };
|
|
260
323
|
catalog = entry;
|
|
261
324
|
Promise.resolve().then(() => provider.list()).then((effects) => {
|
|
@@ -291,7 +354,7 @@ function createEffectToolProvider(host) {
|
|
|
291
354
|
description: `${what}: control name \u2192 value, as listed by describe_effect (its "controls" schema: types, ranges, units and defaults). Only the given controls change; colours are "#rrggbb".${keyframes ? " A number control may instead be keyframes { keys: [{ t: ms from the start, v, ease }] }." : ""} Unknown controls and out-of-range values are refused with the valid ones.`
|
|
292
355
|
});
|
|
293
356
|
const effectIdSchema = (uses) => {
|
|
294
|
-
const effects = _optionalChain([catalogFor, 'call',
|
|
357
|
+
const effects = _optionalChain([catalogFor, 'call', _7 => _7(host.provider()), 'optionalAccess', _8 => _8.filter, 'call', _9 => _9((e) => effectOffered(e, uses))]);
|
|
295
358
|
const base = `An effect id from search_effects (use ${uses.map((u) => `"${u}"`).join(" or ")}).`;
|
|
296
359
|
return effects && effects.length && effects.length <= ENUM_LIMIT ? { type: "string", enum: effects.map((e) => e.id), description: `${base} One of: ${effects.map((e) => `${e.id} (${e.name})`).join(", ")}.` } : { type: "string", minLength: 1, description: base };
|
|
297
360
|
};
|
|
@@ -322,7 +385,7 @@ function createEffectToolProvider(host) {
|
|
|
322
385
|
const found = (await explain(async () => p.search(_nullishCoalesce(args.query, () => ( "")), { kind: args.kind, category: args.category, use: args.use, tags }))).filter((e) => hasEffectTags(e, tags));
|
|
323
386
|
const limit = _nullishCoalesce(args.limit, () => ( 20));
|
|
324
387
|
const out = { available: true, provider: { id: p.id, name: p.name, capabilities: p.capabilities }, effects: found.slice(0, limit).map(summaryOut), total: found.length, tags: countEffectTags(found).slice(0, TAG_LIMIT) };
|
|
325
|
-
if (_optionalChain([tags, 'optionalAccess',
|
|
388
|
+
if (_optionalChain([tags, 'optionalAccess', _10 => _10.length]) && !found.length) {
|
|
326
389
|
const known = countEffectTags(await explain(async () => p.list()));
|
|
327
390
|
const have = new Set(known.map((k) => k.tag));
|
|
328
391
|
const unknown = tags.filter((t) => !have.has(normaliseEffectTag(t)));
|
|
@@ -437,16 +500,16 @@ function createEffectToolProvider(host) {
|
|
|
437
500
|
...host.description ? { description: host.description } : {},
|
|
438
501
|
...host.skill ? { skill: host.skill } : {},
|
|
439
502
|
tools: () => {
|
|
440
|
-
const extra = _nullishCoalesce(_optionalChain([host, 'access',
|
|
441
|
-
if (host.readOnlyReason()) return [...readTools(), ...extra.filter((t) => _optionalChain([t, 'access',
|
|
503
|
+
const extra = _nullishCoalesce(_optionalChain([host, 'access', _11 => _11.extraTools, 'optionalCall', _12 => _12(context)]), () => ( []));
|
|
504
|
+
if (host.readOnlyReason()) return [...readTools(), ...extra.filter((t) => _optionalChain([t, 'access', _13 => _13.annotations, 'optionalAccess', _14 => _14.readOnlyHint]))];
|
|
442
505
|
return [...readTools(), ...writeTools(), ...extra];
|
|
443
506
|
},
|
|
444
507
|
subscribe: (l) => {
|
|
445
508
|
listeners.add(l);
|
|
446
|
-
const off = _optionalChain([host, 'access',
|
|
509
|
+
const off = _optionalChain([host, 'access', _15 => _15.subscribe, 'optionalCall', _16 => _16(l)]);
|
|
447
510
|
return () => {
|
|
448
511
|
listeners.delete(l);
|
|
449
|
-
_optionalChain([off, 'optionalCall',
|
|
512
|
+
_optionalChain([off, 'optionalCall', _17 => _17()]);
|
|
450
513
|
};
|
|
451
514
|
}
|
|
452
515
|
};
|
|
@@ -482,4 +545,12 @@ function createEffectToolProvider(host) {
|
|
|
482
545
|
|
|
483
546
|
|
|
484
547
|
|
|
485
|
-
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
exports.EFFECT_ERROR_CODES = EFFECT_ERROR_CODES; exports.EffectError = EffectError; exports.UnknownEffectError = UnknownEffectError; exports.EffectControlError = EffectControlError; exports.EffectUnsupportedError = EffectUnsupportedError; exports.EffectDisposedError = EffectDisposedError; exports.NoEffectsProviderError = NoEffectsProviderError; exports.isEffectError = isEffectError; exports.effectValueErrors = effectValueErrors; exports.resolveEffectValues = resolveEffectValues; exports.effectOffered = effectOffered; exports.normaliseEffectTag = normaliseEffectTag; exports.hasEffectTags = hasEffectTags; exports.countEffectTags = countEffectTags; exports.searchEffectSummaries = searchEffectSummaries; exports.createEffectPixels = createEffectPixels; exports.isEffectPixels = isEffectPixels; exports.srgbToLinear = srgbToLinear; exports.linearToSrgb = linearToSrgb; exports.encodeEffectFloat = encodeEffectFloat; exports.applyEffectMask = applyEffectMask; exports.EffectsSlot = EffectsSlot; exports.isCameraView = isCameraView; exports.sampleCameraViews = sampleCameraViews; exports.sampleEffectCameraMove = sampleEffectCameraMove; exports.cameraMoveField = cameraMoveField; exports.cameraMovesFor = cameraMovesFor; exports.cameraMoveIdList = cameraMoveIdList; exports.cameraMoveParts = cameraMoveParts; exports.CAMERA_MOVE_MAX_MS = CAMERA_MOVE_MAX_MS; exports.resolveCameraMoveSpec = resolveCameraMoveSpec; exports.cameraViewOfBox = cameraViewOfBox; exports.cameraBoxOfView = cameraBoxOfView; exports.EFFECT_KINDS = EFFECT_KINDS; exports.EFFECT_USES = EFFECT_USES; exports.CAMERA_MOVE_ROLES = CAMERA_MOVE_ROLES; exports.createEffectToolProvider = createEffectToolProvider;
|
|
@@ -209,6 +209,69 @@ async function sampleEffectCameraMove(provider, id, request) {
|
|
|
209
209
|
const { from, to, ms, stage, values } = request;
|
|
210
210
|
return sampleCameraViews((u) => provider.cameraView(id, { from, to, u, ms, stage }, values), { ms, fps: request.fps, cut: d.camera.cut });
|
|
211
211
|
}
|
|
212
|
+
var cameraMoveField = (role) => role === "transition" ? "in" : "during";
|
|
213
|
+
function cameraMovesFor(catalog, role) {
|
|
214
|
+
return catalog.filter((e) => e.kind === "camera" && e.camera?.role === role);
|
|
215
|
+
}
|
|
216
|
+
function cameraMoveIdList(catalog, role) {
|
|
217
|
+
const ids = cameraMovesFor(catalog, role).map((e) => JSON.stringify(e.id));
|
|
218
|
+
return ids.length ? ids.join(", ") : "none (the provider has no camera moves of that role)";
|
|
219
|
+
}
|
|
220
|
+
function cameraMoveParts(spec) {
|
|
221
|
+
if (typeof spec === "string") return spec ? { move: spec } : void 0;
|
|
222
|
+
if (spec && typeof spec === "object" && !Array.isArray(spec) && typeof spec.move === "string") return spec;
|
|
223
|
+
return void 0;
|
|
224
|
+
}
|
|
225
|
+
var CAMERA_MOVE_MAX_MS = 6e4;
|
|
226
|
+
async function resolveCameraMoveSpec(provider, spec, role) {
|
|
227
|
+
const field = cameraMoveField(role);
|
|
228
|
+
if (!provider.capabilities.supportsCamera || !provider.cameraView) throw new EffectUnsupportedError(`${provider.name} has no camera moves (capabilities.supportsCamera is not set), so camera "${field}" cannot be set.`);
|
|
229
|
+
const parts = cameraMoveParts(spec);
|
|
230
|
+
const catalog = await provider.list({ kind: "camera" });
|
|
231
|
+
if (!parts) throw new EffectUnsupportedError(`Camera "${field}" is a camera move's id, or { move, ms?, preset?, values? }; it takes one of ${cameraMoveIdList(catalog, role)}.`);
|
|
232
|
+
let description;
|
|
233
|
+
try {
|
|
234
|
+
description = await provider.describe(parts.move);
|
|
235
|
+
} catch (error) {
|
|
236
|
+
if (error instanceof UnknownEffectError || error.code === "unknown_effect")
|
|
237
|
+
throw new EffectError("unknown_effect", `There is no camera move "${parts.move}"; camera "${field}" takes one of ${cameraMoveIdList(catalog, role)}.`, parts.move);
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
if (description.kind !== "camera" || !description.camera) throw new EffectUnsupportedError(`"${parts.move}" is a ${description.kind} effect, not a camera move; camera "${field}" takes one of ${cameraMoveIdList(catalog, role)}.`, parts.move);
|
|
241
|
+
if (description.camera.role !== role) {
|
|
242
|
+
const other = cameraMoveField(description.camera.role);
|
|
243
|
+
throw new EffectUnsupportedError(
|
|
244
|
+
`"${parts.move}" moves the camera ${description.camera.role === "hold" ? "while a shot holds" : "into a shot"}, so it goes in camera "${other}", not "${field}"; camera "${field}" takes one of ${cameraMoveIdList(catalog, role)}.`,
|
|
245
|
+
parts.move
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
if (parts.ms !== void 0) {
|
|
249
|
+
if (role === "hold") throw new EffectUnsupportedError(`A move while the shot holds plays across the shot's hold; set the hold's length instead of "ms".`, parts.move);
|
|
250
|
+
if (!(typeof parts.ms === "number" && Number.isFinite(parts.ms) && parts.ms >= 0 && parts.ms <= CAMERA_MOVE_MAX_MS))
|
|
251
|
+
throw new EffectUnsupportedError(`Camera "in" ms is how long the move takes, 0 to ${CAMERA_MOVE_MAX_MS} (default ${description.camera.durationMs} for "${parts.move}").`, parts.move);
|
|
252
|
+
}
|
|
253
|
+
let presetValues = {};
|
|
254
|
+
if (parts.preset !== void 0) {
|
|
255
|
+
const preset = description.presets.find((p) => p.name === parts.preset);
|
|
256
|
+
if (!preset) throw new EffectUnsupportedError(`"${parts.move}" has no preset ${JSON.stringify(parts.preset)}; its presets are ${description.presets.length ? description.presets.map((p) => JSON.stringify(p.name)).join(", ") : "none"}.`, parts.move);
|
|
257
|
+
presetValues = preset.values;
|
|
258
|
+
}
|
|
259
|
+
const values = { ...presetValues, ...parts.values ?? {} };
|
|
260
|
+
resolveEffectValues(description, values);
|
|
261
|
+
return {
|
|
262
|
+
spec: { move: description.id, ...parts.ms !== void 0 ? { ms: parts.ms } : {}, ...parts.preset !== void 0 ? { preset: parts.preset } : {}, ...Object.keys(values).length ? { values } : {} },
|
|
263
|
+
description
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function cameraViewOfBox(box, stage) {
|
|
267
|
+
const zoom = Math.min(stage.width / box.width, stage.height / box.height);
|
|
268
|
+
return { zoom, scrollX: stage.width / (2 * zoom) - (box.x + box.width / 2), scrollY: stage.height / (2 * zoom) - (box.y + box.height / 2) };
|
|
269
|
+
}
|
|
270
|
+
function cameraBoxOfView(view, stage) {
|
|
271
|
+
const width = stage.width / view.zoom;
|
|
272
|
+
const height = stage.height / view.zoom;
|
|
273
|
+
return { x: -view.scrollX, y: -view.scrollY, width, height };
|
|
274
|
+
}
|
|
212
275
|
|
|
213
276
|
// src/effects/types.ts
|
|
214
277
|
var EFFECT_KINDS = ["shader", "vector", "motion", "camera"];
|
|
@@ -478,6 +541,14 @@ export {
|
|
|
478
541
|
isCameraView,
|
|
479
542
|
sampleCameraViews,
|
|
480
543
|
sampleEffectCameraMove,
|
|
544
|
+
cameraMoveField,
|
|
545
|
+
cameraMovesFor,
|
|
546
|
+
cameraMoveIdList,
|
|
547
|
+
cameraMoveParts,
|
|
548
|
+
CAMERA_MOVE_MAX_MS,
|
|
549
|
+
resolveCameraMoveSpec,
|
|
550
|
+
cameraViewOfBox,
|
|
551
|
+
cameraBoxOfView,
|
|
481
552
|
EFFECT_KINDS,
|
|
482
553
|
EFFECT_USES,
|
|
483
554
|
CAMERA_MOVE_ROLES,
|
|
@@ -33,7 +33,11 @@ var MOTION_ISSUE_CODES = {
|
|
|
33
33
|
"scene-too-short": { severity: "warning", wording: "The scene ends before its target length." },
|
|
34
34
|
"unknown-control-color": { severity: "warning", wording: "A control stands for a colour the scene never uses." },
|
|
35
35
|
"empty-shot": { severity: "note", wording: "A shot neither moves the camera nor runs a command." },
|
|
36
|
-
"camera-aspect": { severity: "note", wording: "A camera rectangle has a different shape from the artwork, so it is letterboxed." }
|
|
36
|
+
"camera-aspect": { severity: "note", wording: "A camera rectangle has a different shape from the artwork, so it is letterboxed." },
|
|
37
|
+
"camera-move-first-shot": { severity: "note", wording: "The first shot cuts to its framing, so the move its camera gets in with does not play." },
|
|
38
|
+
"camera-move-not-played": { severity: "note", wording: "A shot names a camera move, but there is no effects provider with camera moves to play it, so the camera eases instead." },
|
|
39
|
+
"camera-move-unknown": { severity: "error", wording: "A shot names a camera move the effects provider does not have, or one of the wrong role." },
|
|
40
|
+
"camera-move-values": { severity: "error", wording: "A camera move's preset or values do not fit its controls." }
|
|
37
41
|
};
|
|
38
42
|
function motionIssue(code, message, extra = {}) {
|
|
39
43
|
return { code, severity: MOTION_ISSUE_CODES[code].severity, message, ...extra };
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* and a provider slot editors hold.
|
|
4
4
|
*/
|
|
5
5
|
import { type SchemaValidationError } from '../tools/schema.cjs';
|
|
6
|
-
import type { CameraMoveSample, CameraMoveSampleRequest, CameraView, EffectDescription, EffectImageSource, EffectPixels, EffectProvider, EffectSearchOptions, EffectSummary, EffectUse, EffectValues } from './types.cjs';
|
|
6
|
+
import type { CameraMoveRole, CameraMoveSpec, CameraMoveSample, CameraMoveSampleRequest, CameraStage, CameraView, EffectDescription, EffectImageSource, EffectPixels, EffectProvider, EffectSearchOptions, EffectSummary, EffectUse, EffectValues } from './types.cjs';
|
|
7
7
|
/** Problems with `values` against an effect's control schema (unknown controls, types, ranges). Partial values are fine. */
|
|
8
8
|
export declare function effectValueErrors(description: Pick<EffectDescription, 'controls'>, values: unknown): SchemaValidationError[];
|
|
9
9
|
/**
|
|
@@ -82,3 +82,37 @@ export declare function sampleCameraViews(view: (u: number) => CameraView, optio
|
|
|
82
82
|
* `EffectUnsupportedError` when the provider has no camera support.
|
|
83
83
|
*/
|
|
84
84
|
export declare function sampleEffectCameraMove(provider: EffectProvider, id: string, request: CameraMoveSampleRequest): Promise<CameraMoveSample>;
|
|
85
|
+
/** The field a shot names a move of `role` in: `in` for a transition, `during` for a hold. */
|
|
86
|
+
export declare const cameraMoveField: (role: CameraMoveRole) => "in" | "during";
|
|
87
|
+
/** The camera moves of `role` in a catalog, in its order. */
|
|
88
|
+
export declare function cameraMovesFor<T extends Pick<EffectSummary, 'kind' | 'camera'>>(catalog: readonly T[], role: CameraMoveRole): T[];
|
|
89
|
+
/** The ids of a catalog's camera moves of `role` as a sentence's list: `"a", "b"` (or `none`). */
|
|
90
|
+
export declare function cameraMoveIdList(catalog: readonly Pick<EffectSummary, 'id' | 'kind' | 'camera'>[], role: CameraMoveRole): string;
|
|
91
|
+
/** A camera move spec as its parts (`"id"` → `{ move: "id" }`); undefined when it is neither form. */
|
|
92
|
+
export declare function cameraMoveParts(spec: unknown): Exclude<CameraMoveSpec, string> | undefined;
|
|
93
|
+
/** Longest `ms` a transition move takes (ms). */
|
|
94
|
+
export declare const CAMERA_MOVE_MAX_MS = 60000;
|
|
95
|
+
/**
|
|
96
|
+
* A camera move spec checked against a provider for a role, with its preset's values written out
|
|
97
|
+
* into `values`, so a document plays it without asking the provider for the preset again.
|
|
98
|
+
* Throws an error that says what to do: an unknown id or a move of the other role names the
|
|
99
|
+
* moves the role takes, an unknown preset names the presets, and bad values name the controls.
|
|
100
|
+
*/
|
|
101
|
+
export declare function resolveCameraMoveSpec(provider: EffectProvider, spec: CameraMoveSpec, role: CameraMoveRole): Promise<{
|
|
102
|
+
spec: Exclude<CameraMoveSpec, string>;
|
|
103
|
+
description: EffectDescription;
|
|
104
|
+
}>;
|
|
105
|
+
/** A box of the scene, in its units. */
|
|
106
|
+
export interface CameraBox {
|
|
107
|
+
x: number;
|
|
108
|
+
y: number;
|
|
109
|
+
width: number;
|
|
110
|
+
height: number;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* The view that shows `box` on `stage`: the box's centre in the middle, at the zoom that fits it
|
|
114
|
+
* whole (as SVG's `xMidYMid meet`).
|
|
115
|
+
*/
|
|
116
|
+
export declare function cameraViewOfBox(box: CameraBox, stage: CameraStage): CameraView;
|
|
117
|
+
/** The box of the scene a view shows on `stage` (its tilt, turn, roll and blur aside). */
|
|
118
|
+
export declare function cameraBoxOfView(view: CameraView, stage: CameraStage): CameraBox;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* and a provider slot editors hold.
|
|
4
4
|
*/
|
|
5
5
|
import { type SchemaValidationError } from '../tools/schema.js';
|
|
6
|
-
import type { CameraMoveSample, CameraMoveSampleRequest, CameraView, EffectDescription, EffectImageSource, EffectPixels, EffectProvider, EffectSearchOptions, EffectSummary, EffectUse, EffectValues } from './types.js';
|
|
6
|
+
import type { CameraMoveRole, CameraMoveSpec, CameraMoveSample, CameraMoveSampleRequest, CameraStage, CameraView, EffectDescription, EffectImageSource, EffectPixels, EffectProvider, EffectSearchOptions, EffectSummary, EffectUse, EffectValues } from './types.js';
|
|
7
7
|
/** Problems with `values` against an effect's control schema (unknown controls, types, ranges). Partial values are fine. */
|
|
8
8
|
export declare function effectValueErrors(description: Pick<EffectDescription, 'controls'>, values: unknown): SchemaValidationError[];
|
|
9
9
|
/**
|
|
@@ -82,3 +82,37 @@ export declare function sampleCameraViews(view: (u: number) => CameraView, optio
|
|
|
82
82
|
* `EffectUnsupportedError` when the provider has no camera support.
|
|
83
83
|
*/
|
|
84
84
|
export declare function sampleEffectCameraMove(provider: EffectProvider, id: string, request: CameraMoveSampleRequest): Promise<CameraMoveSample>;
|
|
85
|
+
/** The field a shot names a move of `role` in: `in` for a transition, `during` for a hold. */
|
|
86
|
+
export declare const cameraMoveField: (role: CameraMoveRole) => "in" | "during";
|
|
87
|
+
/** The camera moves of `role` in a catalog, in its order. */
|
|
88
|
+
export declare function cameraMovesFor<T extends Pick<EffectSummary, 'kind' | 'camera'>>(catalog: readonly T[], role: CameraMoveRole): T[];
|
|
89
|
+
/** The ids of a catalog's camera moves of `role` as a sentence's list: `"a", "b"` (or `none`). */
|
|
90
|
+
export declare function cameraMoveIdList(catalog: readonly Pick<EffectSummary, 'id' | 'kind' | 'camera'>[], role: CameraMoveRole): string;
|
|
91
|
+
/** A camera move spec as its parts (`"id"` → `{ move: "id" }`); undefined when it is neither form. */
|
|
92
|
+
export declare function cameraMoveParts(spec: unknown): Exclude<CameraMoveSpec, string> | undefined;
|
|
93
|
+
/** Longest `ms` a transition move takes (ms). */
|
|
94
|
+
export declare const CAMERA_MOVE_MAX_MS = 60000;
|
|
95
|
+
/**
|
|
96
|
+
* A camera move spec checked against a provider for a role, with its preset's values written out
|
|
97
|
+
* into `values`, so a document plays it without asking the provider for the preset again.
|
|
98
|
+
* Throws an error that says what to do: an unknown id or a move of the other role names the
|
|
99
|
+
* moves the role takes, an unknown preset names the presets, and bad values name the controls.
|
|
100
|
+
*/
|
|
101
|
+
export declare function resolveCameraMoveSpec(provider: EffectProvider, spec: CameraMoveSpec, role: CameraMoveRole): Promise<{
|
|
102
|
+
spec: Exclude<CameraMoveSpec, string>;
|
|
103
|
+
description: EffectDescription;
|
|
104
|
+
}>;
|
|
105
|
+
/** A box of the scene, in its units. */
|
|
106
|
+
export interface CameraBox {
|
|
107
|
+
x: number;
|
|
108
|
+
y: number;
|
|
109
|
+
width: number;
|
|
110
|
+
height: number;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* The view that shows `box` on `stage`: the box's centre in the middle, at the zoom that fits it
|
|
114
|
+
* whole (as SVG's `xMidYMid meet`).
|
|
115
|
+
*/
|
|
116
|
+
export declare function cameraViewOfBox(box: CameraBox, stage: CameraStage): CameraView;
|
|
117
|
+
/** The box of the scene a view shows on `stage` (its tilt, turn, roll and blur aside). */
|
|
118
|
+
export declare function cameraBoxOfView(view: CameraView, stage: CameraStage): CameraBox;
|