reframe-video 0.6.13 → 0.6.14
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/bin.js +12 -5
- package/dist/browserEntry.js +3 -2
- package/dist/cli.js +3 -2
- package/dist/diff.js +3 -2
- package/dist/index.js +4 -2
- package/dist/labels.js +3 -2
- package/dist/types/ir.d.ts +3 -0
- package/guides/directing-guide.md +5 -0
- package/guides/edsl-guide.md +6 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -10,13 +10,14 @@ var __export = (target, all) => {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
// ../core/src/ir.ts
|
|
13
|
-
var DEFAULT_TO_DURATION, DEFAULT_TWEEN_DURATION, DEFAULT_MOTIONPATH_DURATION;
|
|
13
|
+
var DEFAULT_TO_DURATION, DEFAULT_TWEEN_DURATION, DEFAULT_MOTIONPATH_DURATION, DEFAULT_STILL_DURATION;
|
|
14
14
|
var init_ir = __esm({
|
|
15
15
|
"../core/src/ir.ts"() {
|
|
16
16
|
"use strict";
|
|
17
17
|
DEFAULT_TO_DURATION = 0.5;
|
|
18
18
|
DEFAULT_TWEEN_DURATION = 0.5;
|
|
19
19
|
DEFAULT_MOTIONPATH_DURATION = 1;
|
|
20
|
+
DEFAULT_STILL_DURATION = 1;
|
|
20
21
|
}
|
|
21
22
|
});
|
|
22
23
|
|
|
@@ -319,14 +320,14 @@ function compileScene(ir) {
|
|
|
319
320
|
}
|
|
320
321
|
}
|
|
321
322
|
};
|
|
322
|
-
const inferredEnd = ir.timeline ? walk(ir.timeline, 0) : 0;
|
|
323
|
+
const inferredEnd = (ir.timeline ? walk(ir.timeline, 0) : 0) || 0;
|
|
323
324
|
for (const list of segments.values()) list.sort((a, b) => a.t0 - b.t0);
|
|
324
325
|
for (const list of motionPaths.values()) list.sort((a, b) => a.t0 - b.t0);
|
|
325
326
|
const hasCamera = !cameraIsNode && (ir.camera !== void 0 || motionPaths.has("camera") || [...segments.keys()].some((k) => k.startsWith("camera.")));
|
|
326
327
|
const hasPerspective = !cameraIsNode && (ir.camera?.perspective !== void 0 || segments.has("camera.perspective"));
|
|
327
328
|
return {
|
|
328
329
|
ir,
|
|
329
|
-
duration: ir.duration ?? inferredEnd,
|
|
330
|
+
duration: ir.duration ?? (inferredEnd > 0 ? inferredEnd : DEFAULT_STILL_DURATION),
|
|
330
331
|
segments,
|
|
331
332
|
motionPaths,
|
|
332
333
|
initialValues,
|
|
@@ -2843,10 +2844,16 @@ ${USAGE}`);
|
|
|
2843
2844
|
}
|
|
2844
2845
|
preflightFfmpeg();
|
|
2845
2846
|
const outBase = PACKAGED ? join9(USER_CWD, "out") : join9(ROOT2, "out");
|
|
2847
|
+
const stem = `${basename(input).replace(/\.[^.]+$/, "")}.mp4`;
|
|
2846
2848
|
let outArgs = args;
|
|
2847
|
-
|
|
2849
|
+
const oIdx = args.indexOf("-o");
|
|
2850
|
+
if (oIdx === -1) {
|
|
2848
2851
|
await mkdir4(outBase, { recursive: true });
|
|
2849
|
-
outArgs = [...args, "-o", join9(outBase,
|
|
2852
|
+
outArgs = [...args, "-o", join9(outBase, stem)];
|
|
2853
|
+
} else if (args[oIdx + 1] && !args[oIdx + 1].startsWith("-") && !/\.\w{2,4}$/.test(args[oIdx + 1])) {
|
|
2854
|
+
const dir = userPath(args[oIdx + 1]);
|
|
2855
|
+
await mkdir4(dir, { recursive: true });
|
|
2856
|
+
outArgs = args.map((a, i) => i === oIdx + 1 ? join9(dir, stem) : a);
|
|
2850
2857
|
}
|
|
2851
2858
|
outArgs = outArgs.map(
|
|
2852
2859
|
(a, i) => outArgs[i - 1] === "--overlay" || outArgs[i - 1] === "-o" ? userPath(a) : a
|
package/dist/browserEntry.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
var DEFAULT_TO_DURATION = 0.5;
|
|
5
5
|
var DEFAULT_TWEEN_DURATION = 0.5;
|
|
6
6
|
var DEFAULT_MOTIONPATH_DURATION = 1;
|
|
7
|
+
var DEFAULT_STILL_DURATION = 1;
|
|
7
8
|
|
|
8
9
|
// ../core/src/path.ts
|
|
9
10
|
function pathBBox(d) {
|
|
@@ -316,14 +317,14 @@
|
|
|
316
317
|
}
|
|
317
318
|
}
|
|
318
319
|
};
|
|
319
|
-
const inferredEnd = ir.timeline ? walk(ir.timeline, 0) : 0;
|
|
320
|
+
const inferredEnd = (ir.timeline ? walk(ir.timeline, 0) : 0) || 0;
|
|
320
321
|
for (const list of segments.values()) list.sort((a, b) => a.t0 - b.t0);
|
|
321
322
|
for (const list of motionPaths.values()) list.sort((a, b) => a.t0 - b.t0);
|
|
322
323
|
const hasCamera = !cameraIsNode && (ir.camera !== void 0 || motionPaths.has("camera") || [...segments.keys()].some((k) => k.startsWith("camera.")));
|
|
323
324
|
const hasPerspective = !cameraIsNode && (ir.camera?.perspective !== void 0 || segments.has("camera.perspective"));
|
|
324
325
|
return {
|
|
325
326
|
ir,
|
|
326
|
-
duration: ir.duration ?? inferredEnd,
|
|
327
|
+
duration: ir.duration ?? (inferredEnd > 0 ? inferredEnd : DEFAULT_STILL_DURATION),
|
|
327
328
|
segments,
|
|
328
329
|
motionPaths,
|
|
329
330
|
initialValues,
|
package/dist/cli.js
CHANGED
|
@@ -10,6 +10,7 @@ var DEFAULT_CROSSFADE = 0.5;
|
|
|
10
10
|
var DEFAULT_TO_DURATION = 0.5;
|
|
11
11
|
var DEFAULT_TWEEN_DURATION = 0.5;
|
|
12
12
|
var DEFAULT_MOTIONPATH_DURATION = 1;
|
|
13
|
+
var DEFAULT_STILL_DURATION = 1;
|
|
13
14
|
|
|
14
15
|
// ../core/src/path.ts
|
|
15
16
|
function locate(segCount, u) {
|
|
@@ -306,14 +307,14 @@ function compileScene(ir) {
|
|
|
306
307
|
}
|
|
307
308
|
}
|
|
308
309
|
};
|
|
309
|
-
const inferredEnd = ir.timeline ? walk(ir.timeline, 0) : 0;
|
|
310
|
+
const inferredEnd = (ir.timeline ? walk(ir.timeline, 0) : 0) || 0;
|
|
310
311
|
for (const list of segments.values()) list.sort((a, b) => a.t0 - b.t0);
|
|
311
312
|
for (const list of motionPaths.values()) list.sort((a, b) => a.t0 - b.t0);
|
|
312
313
|
const hasCamera = !cameraIsNode && (ir.camera !== void 0 || motionPaths.has("camera") || [...segments.keys()].some((k) => k.startsWith("camera.")));
|
|
313
314
|
const hasPerspective = !cameraIsNode && (ir.camera?.perspective !== void 0 || segments.has("camera.perspective"));
|
|
314
315
|
return {
|
|
315
316
|
ir,
|
|
316
|
-
duration: ir.duration ?? inferredEnd,
|
|
317
|
+
duration: ir.duration ?? (inferredEnd > 0 ? inferredEnd : DEFAULT_STILL_DURATION),
|
|
317
318
|
segments,
|
|
318
319
|
motionPaths,
|
|
319
320
|
initialValues,
|
package/dist/diff.js
CHANGED
|
@@ -16,6 +16,7 @@ import { fileURLToPath } from "node:url";
|
|
|
16
16
|
var DEFAULT_TO_DURATION = 0.5;
|
|
17
17
|
var DEFAULT_TWEEN_DURATION = 0.5;
|
|
18
18
|
var DEFAULT_MOTIONPATH_DURATION = 1;
|
|
19
|
+
var DEFAULT_STILL_DURATION = 1;
|
|
19
20
|
|
|
20
21
|
// ../core/src/path.ts
|
|
21
22
|
function locate(segCount, u) {
|
|
@@ -312,14 +313,14 @@ function compileScene(ir) {
|
|
|
312
313
|
}
|
|
313
314
|
}
|
|
314
315
|
};
|
|
315
|
-
const inferredEnd = ir.timeline ? walk(ir.timeline, 0) : 0;
|
|
316
|
+
const inferredEnd = (ir.timeline ? walk(ir.timeline, 0) : 0) || 0;
|
|
316
317
|
for (const list of segments.values()) list.sort((a, b) => a.t0 - b.t0);
|
|
317
318
|
for (const list of motionPaths.values()) list.sort((a, b) => a.t0 - b.t0);
|
|
318
319
|
const hasCamera = !cameraIsNode && (ir.camera !== void 0 || motionPaths.has("camera") || [...segments.keys()].some((k) => k.startsWith("camera.")));
|
|
319
320
|
const hasPerspective = !cameraIsNode && (ir.camera?.perspective !== void 0 || segments.has("camera.perspective"));
|
|
320
321
|
return {
|
|
321
322
|
ir,
|
|
322
|
-
duration: ir.duration ?? inferredEnd,
|
|
323
|
+
duration: ir.duration ?? (inferredEnd > 0 ? inferredEnd : DEFAULT_STILL_DURATION),
|
|
323
324
|
segments,
|
|
324
325
|
motionPaths,
|
|
325
326
|
initialValues,
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ var DEFAULT_TO_DURATION = 0.5;
|
|
|
4
4
|
var DEFAULT_TWEEN_DURATION = 0.5;
|
|
5
5
|
var DEFAULT_MOTIONPATH_DURATION = 1;
|
|
6
6
|
var DEFAULT_FPS = 30;
|
|
7
|
+
var DEFAULT_STILL_DURATION = 1;
|
|
7
8
|
|
|
8
9
|
// ../core/src/path.ts
|
|
9
10
|
function pathBBox(d) {
|
|
@@ -316,14 +317,14 @@ function compileScene(ir) {
|
|
|
316
317
|
}
|
|
317
318
|
}
|
|
318
319
|
};
|
|
319
|
-
const inferredEnd = ir.timeline ? walk(ir.timeline, 0) : 0;
|
|
320
|
+
const inferredEnd = (ir.timeline ? walk(ir.timeline, 0) : 0) || 0;
|
|
320
321
|
for (const list of segments.values()) list.sort((a, b) => a.t0 - b.t0);
|
|
321
322
|
for (const list of motionPaths.values()) list.sort((a, b) => a.t0 - b.t0);
|
|
322
323
|
const hasCamera = !cameraIsNode && (ir.camera !== void 0 || motionPaths.has("camera") || [...segments.keys()].some((k) => k.startsWith("camera.")));
|
|
323
324
|
const hasPerspective = !cameraIsNode && (ir.camera?.perspective !== void 0 || segments.has("camera.perspective"));
|
|
324
325
|
return {
|
|
325
326
|
ir,
|
|
326
|
-
duration: ir.duration ?? inferredEnd,
|
|
327
|
+
duration: ir.duration ?? (inferredEnd > 0 ? inferredEnd : DEFAULT_STILL_DURATION),
|
|
327
328
|
segments,
|
|
328
329
|
motionPaths,
|
|
329
330
|
initialValues,
|
|
@@ -3505,6 +3506,7 @@ export {
|
|
|
3505
3506
|
DEFAULT_CROSSFADE,
|
|
3506
3507
|
DEFAULT_FPS,
|
|
3507
3508
|
DEFAULT_MOTIONPATH_DURATION,
|
|
3509
|
+
DEFAULT_STILL_DURATION,
|
|
3508
3510
|
DEFAULT_TO_DURATION,
|
|
3509
3511
|
DEFAULT_TWEEN_DURATION,
|
|
3510
3512
|
DEVICE_PRESET_NAMES,
|
package/dist/labels.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
var DEFAULT_TO_DURATION = 0.5;
|
|
5
5
|
var DEFAULT_TWEEN_DURATION = 0.5;
|
|
6
6
|
var DEFAULT_MOTIONPATH_DURATION = 1;
|
|
7
|
+
var DEFAULT_STILL_DURATION = 1;
|
|
7
8
|
|
|
8
9
|
// ../core/src/path.ts
|
|
9
10
|
function locate(segCount, u) {
|
|
@@ -300,14 +301,14 @@ function compileScene(ir) {
|
|
|
300
301
|
}
|
|
301
302
|
}
|
|
302
303
|
};
|
|
303
|
-
const inferredEnd = ir.timeline ? walk(ir.timeline, 0) : 0;
|
|
304
|
+
const inferredEnd = (ir.timeline ? walk(ir.timeline, 0) : 0) || 0;
|
|
304
305
|
for (const list of segments.values()) list.sort((a, b) => a.t0 - b.t0);
|
|
305
306
|
for (const list of motionPaths.values()) list.sort((a, b) => a.t0 - b.t0);
|
|
306
307
|
const hasCamera = !cameraIsNode && (ir.camera !== void 0 || motionPaths.has("camera") || [...segments.keys()].some((k) => k.startsWith("camera.")));
|
|
307
308
|
const hasPerspective = !cameraIsNode && (ir.camera?.perspective !== void 0 || segments.has("camera.perspective"));
|
|
308
309
|
return {
|
|
309
310
|
ir,
|
|
310
|
-
duration: ir.duration ?? inferredEnd,
|
|
311
|
+
duration: ir.duration ?? (inferredEnd > 0 ? inferredEnd : DEFAULT_STILL_DURATION),
|
|
311
312
|
segments,
|
|
312
313
|
motionPaths,
|
|
313
314
|
initialValues,
|
package/dist/types/ir.d.ts
CHANGED
|
@@ -508,3 +508,6 @@ export declare const DEFAULT_TO_DURATION = 0.5;
|
|
|
508
508
|
export declare const DEFAULT_TWEEN_DURATION = 0.5;
|
|
509
509
|
export declare const DEFAULT_MOTIONPATH_DURATION = 1;
|
|
510
510
|
export declare const DEFAULT_FPS = 30;
|
|
511
|
+
/** Fallback length (seconds) for a scene with no animating timeline — a static
|
|
512
|
+
* frame still needs a positive duration to render. Override with scene `duration`. */
|
|
513
|
+
export declare const DEFAULT_STILL_DURATION = 1;
|
|
@@ -43,6 +43,11 @@ reframe diff ref.png scene.ts --mode blend # 50% overlay — spot drift
|
|
|
43
43
|
|
|
44
44
|
Loop: `--mode grid` to measure → write the node tree → `--mode side`/`diff` to compare →
|
|
45
45
|
fix coordinates/sizes/colors → repeat until faithful. Pick the frame with `--t <sec>`.
|
|
46
|
+
The grid is rendered at the reference's **full resolution** — the printed numbers are
|
|
47
|
+
exact scene pixels, so place nodes at the labelled coordinates directly (no scaling).
|
|
48
|
+
`diff`/`blend` are sharpest on hard edges (type, icons, frames); over large **soft
|
|
49
|
+
gradients/glows** they always light up "different" even when close, so tune those by
|
|
50
|
+
eye with `--mode side` rather than chasing the diff to black.
|
|
46
51
|
|
|
47
52
|
### 3. Apply the cinematic-craft checklist
|
|
48
53
|
|
package/guides/edsl-guide.md
CHANGED
|
@@ -68,6 +68,9 @@ Factories return plain data. Every node needs a unique `id`.
|
|
|
68
68
|
`"top-left"` (default) | `"top-center"` | `"top-right"` | `"center-left"` |
|
|
69
69
|
`"center"` | `"center-right"` | `"bottom-left"` | `"bottom-center"` | `"bottom-right"`.
|
|
70
70
|
Example: a bar that grows upward = `anchor: "bottom-left"` + animate `height`.
|
|
71
|
+
**Text alignment is `anchor`, not a separate `align` prop:** the anchor's horizontal
|
|
72
|
+
half sets the text align — `"…-left"` left-aligns, `"…-center"`/`"center"` centers,
|
|
73
|
+
`"…-right"` right-aligns (a right-aligned wordmark in a corner = `anchor: "bottom-right"`).
|
|
71
74
|
Font: use `fontFamily: "Inter"` (weights 400/700/800 are available).
|
|
72
75
|
|
|
73
76
|
### Layout helpers (evenly spacing things)
|
|
@@ -133,7 +136,9 @@ target then settles — a pop/snap), `easeIn/Out/InOutElastic` (rings around the
|
|
|
133
136
|
target — a playful spring), `easeIn/Out/InOutBounce` (drops and bounces to rest).
|
|
134
137
|
A logo or card "popping" in usually wants `easeOutBack`; a stamp landing,
|
|
135
138
|
`easeOutBounce`.
|
|
136
|
-
Scene duration is inferred from the timeline.
|
|
139
|
+
Scene duration is inferred from the timeline. For a **static frame** you can omit
|
|
140
|
+
`timeline` entirely (or set scene `duration: <seconds>`) — a still defaults to a 1s
|
|
141
|
+
render; no throwaway `wait` is needed.
|
|
137
142
|
|
|
138
143
|
## Behaviors: continuous motion during holds
|
|
139
144
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reframe-video",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.14",
|
|
4
4
|
"description": "Declarative motion graphics that AI can write and humans can tweak — human edits survive AI regeneration. Deterministic mp4 renders from a plain-data scene format.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"motion-graphics",
|