@vosjs/studio-core 0.24.0 → 0.25.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/index.d.ts +177 -16
- package/dist/index.js +394 -50
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -236,6 +236,210 @@ var MEDIA_FRAME_KEYS = [
|
|
|
236
236
|
"focusFollow"
|
|
237
237
|
];
|
|
238
238
|
|
|
239
|
+
// src/callout.ts
|
|
240
|
+
var CALLOUT_SHAPES = ["tag", "note", "code"];
|
|
241
|
+
var CALLOUT_TYPE_RATIO = 1.35;
|
|
242
|
+
var CALLOUT_DEFAULT_BODY_PX = 14;
|
|
243
|
+
var HOUSE_REGISTER = {
|
|
244
|
+
ground: "#ffffff",
|
|
245
|
+
accent: "#7c3aed"
|
|
246
|
+
};
|
|
247
|
+
var DEFAULT_FACE = "'Inter',-apple-system,system-ui,sans-serif";
|
|
248
|
+
var DEFAULT_MONO = "'JetBrains Mono',ui-monospace,monospace";
|
|
249
|
+
function calloutLook(register, scale = 1) {
|
|
250
|
+
const ground = hexToRgb(register.ground) ?? [255, 255, 255];
|
|
251
|
+
const accent = hexToRgb(register.accent) ?? [124, 58, 237];
|
|
252
|
+
const light = relativeLuminance(ground) > 0.4;
|
|
253
|
+
const [h, s] = rgbToHsl(accent);
|
|
254
|
+
const cardGround = light ? hslToHex(h, Math.min(0.35, s * 0.6), 0.07) : hslToHex(h, Math.min(0.25, s * 0.35), 0.97);
|
|
255
|
+
const bodyPx = register.body ?? CALLOUT_DEFAULT_BODY_PX;
|
|
256
|
+
const titlePx = Math.max(20, Math.round(CALLOUT_TYPE_RATIO * bodyPx * scale));
|
|
257
|
+
return {
|
|
258
|
+
light,
|
|
259
|
+
cardGround,
|
|
260
|
+
cardInk: light ? "#fafafa" : "#101012",
|
|
261
|
+
cardMuted: light ? "rgba(255,255,255,0.64)" : "rgba(16,16,18,0.6)",
|
|
262
|
+
hairline: light ? "rgba(255,255,255,0.12)" : "rgba(0,0,0,0.1)",
|
|
263
|
+
accent: rgbToHex(accent),
|
|
264
|
+
shadow: "0 24px 60px rgba(0,0,0,0.35), 0 2px 6px rgba(0,0,0,0.16)",
|
|
265
|
+
face: register.face ? quoteFamily(register.face) : DEFAULT_FACE,
|
|
266
|
+
mono: register.mono ? quoteFamily(register.mono) : DEFAULT_MONO,
|
|
267
|
+
kickerPx: Math.max(11, Math.round(titlePx * 0.55)),
|
|
268
|
+
titlePx,
|
|
269
|
+
bodyPx: Math.max(15, Math.round(titlePx * 0.75)),
|
|
270
|
+
codePx: Math.max(14, Math.round(titlePx * 0.68)),
|
|
271
|
+
radius: 16,
|
|
272
|
+
padX: 24,
|
|
273
|
+
padY: 20
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
function calloutBox(shape, look, words) {
|
|
277
|
+
const em = (px, chars, adv) => Math.ceil(px * adv * chars);
|
|
278
|
+
if (shape === "tag") {
|
|
279
|
+
const text = words.kicker ?? words.title ?? "";
|
|
280
|
+
const w = em(look.kickerPx * 1.1, text.length, 0.62) + 14 + 18 * 2;
|
|
281
|
+
return {
|
|
282
|
+
width: clamp(w, 120, 720),
|
|
283
|
+
height: Math.max(36, Math.round(look.kickerPx * 1.1 * 2.6))
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
if (shape === "code") {
|
|
287
|
+
const lines = (words.code ?? "").split("\n");
|
|
288
|
+
const longest = Math.max(1, ...lines.map((l) => l.length));
|
|
289
|
+
const lineH = Math.round(look.codePx * 1.7);
|
|
290
|
+
const w = em(look.codePx, longest, 0.62) + look.padX * 2;
|
|
291
|
+
const h = lines.length * lineH + look.padY * 2 + (words.kicker ? look.kickerPx * 2 : 0);
|
|
292
|
+
return { width: clamp(w, 360, 820), height: clamp(h, 72, 640) };
|
|
293
|
+
}
|
|
294
|
+
const title = words.title ?? "";
|
|
295
|
+
const body = words.body ?? "";
|
|
296
|
+
const titleW = em(look.titlePx, title.length, 0.56);
|
|
297
|
+
const width = clamp(Math.max(titleW, 320) + look.padX * 2, 360, 640);
|
|
298
|
+
const inner = width - look.padX * 2;
|
|
299
|
+
const bodyLines = body ? Math.max(1, Math.ceil(em(look.bodyPx, body.length, 0.54) / inner)) : 0;
|
|
300
|
+
const titleLines = Math.max(1, Math.ceil(titleW / inner));
|
|
301
|
+
const height = look.padY * 2 + (words.kicker ? Math.round(look.kickerPx * 1.6) : 0) + titleLines * Math.round(look.titlePx * 1.25) + (bodyLines ? 8 + bodyLines * Math.round(look.bodyPx * 1.5) : 0);
|
|
302
|
+
return { width, height: clamp(height, 64, 480) };
|
|
303
|
+
}
|
|
304
|
+
function calloutSource(shape, look, words, box) {
|
|
305
|
+
const base = `box-sizing:border-box;width:${box.width}px;height:${box.height}px;background:${look.cardGround};color:${look.cardInk};border:1px solid ${look.hairline};border-radius:${look.radius}px;box-shadow:${look.shadow};-webkit-font-smoothing:antialiased;`;
|
|
306
|
+
if (shape === "tag") {
|
|
307
|
+
const text = esc(words.kicker ?? words.title ?? "");
|
|
308
|
+
return {
|
|
309
|
+
html: `<div class="tag"><span class="dot"></span><span class="t">${text}</span></div>`,
|
|
310
|
+
css: `.tag{font-family:${look.face};display:flex;align-items:center;gap:10px;${base}border-radius:999px;padding:0 18px;background:${look.accent};color:#fff;border-color:rgba(255,255,255,0.18);font-size:${Math.round(look.kickerPx * 1.1)}px;font-weight:600;letter-spacing:0.02em;text-transform:uppercase;white-space:nowrap}.dot{width:8px;height:8px;border-radius:99px;background:#fff;opacity:0.9;flex:none}`
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
if (shape === "code") {
|
|
314
|
+
const lines = (words.code ?? "").split("\n").map(
|
|
315
|
+
(l) => /^\s*(\/\/|#|\$)/.test(l) ? `<span class="mut">${esc(l)}</span>` : esc(l)
|
|
316
|
+
).join("\n");
|
|
317
|
+
const kicker2 = words.kicker ? `<div class="k">${esc(words.kicker)}</div>` : "";
|
|
318
|
+
return {
|
|
319
|
+
html: `<div class="code">${kicker2}<pre class="p">${lines}</pre></div>`,
|
|
320
|
+
css: `.code{font-family:${look.mono};${base}padding:${look.padY}px ${look.padX}px;font-size:${look.codePx}px;line-height:1.7;letter-spacing:-0.01em}.k{font-family:${look.face};font-size:${look.kickerPx}px;font-weight:600;letter-spacing:0.08em;text-transform:uppercase;color:${look.accent};margin:0 0 ${Math.round(look.kickerPx * 0.9)}px}.p{margin:0;white-space:pre;font:inherit}.mut{color:${look.cardMuted}}`
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
const kicker = words.kicker ? `<div class="k"><span class="dot"></span>${esc(words.kicker)}</div>` : "";
|
|
324
|
+
const body = words.body ? `<div class="b">${esc(words.body)}</div>` : "";
|
|
325
|
+
return {
|
|
326
|
+
html: `<div class="note">${kicker}<div class="t">${esc(words.title ?? "")}</div>${body}</div>`,
|
|
327
|
+
css: `.note{font-family:${look.face};${base}padding:${look.padY}px ${look.padX}px;display:flex;flex-direction:column;justify-content:center}.k{display:flex;align-items:center;gap:8px;font-size:${look.kickerPx}px;font-weight:600;letter-spacing:0.08em;text-transform:uppercase;color:${look.accent};margin-bottom:${Math.round(look.kickerPx * 0.6)}px}.dot{width:7px;height:7px;border-radius:99px;background:${look.accent};box-shadow:0 0 10px ${look.accent}}.t{font-size:${look.titlePx}px;font-weight:600;line-height:1.25;letter-spacing:-0.01em}.b{margin-top:8px;font-size:${look.bodyPx}px;line-height:1.5;color:${look.cardMuted}}`
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
function calloutClip(shape, register, words, opts) {
|
|
331
|
+
const look = calloutLook(register, opts.scale ?? 1);
|
|
332
|
+
const box = calloutBox(shape, look, words);
|
|
333
|
+
const { html, css } = calloutSource(shape, look, words, box);
|
|
334
|
+
return {
|
|
335
|
+
id: opts.id,
|
|
336
|
+
kind: "html",
|
|
337
|
+
start: opts.start,
|
|
338
|
+
duration: opts.duration,
|
|
339
|
+
html,
|
|
340
|
+
css,
|
|
341
|
+
box,
|
|
342
|
+
transform: {
|
|
343
|
+
x: opts.at?.x ?? 0.5,
|
|
344
|
+
y: opts.at?.y ?? 0.5,
|
|
345
|
+
scale: 1,
|
|
346
|
+
rotation: 0
|
|
347
|
+
},
|
|
348
|
+
anim: { enter: "rise", exit: "fade" },
|
|
349
|
+
...opts.pin ? { pin: opts.pin } : {}
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function calloutGroundOf(css) {
|
|
353
|
+
const m = /background(?:-color)?\s*:\s*(#[0-9a-fA-F]{3,8}|rgba?\([^)]*\))/.exec(css);
|
|
354
|
+
if (!m) return null;
|
|
355
|
+
const rgb = parseCssColour(m[1]);
|
|
356
|
+
return rgb ? rgbToHex(rgb) : null;
|
|
357
|
+
}
|
|
358
|
+
function hexToRgb(hex) {
|
|
359
|
+
const m = /^#?([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.exec(hex.trim());
|
|
360
|
+
if (!m) return null;
|
|
361
|
+
let h = m[1];
|
|
362
|
+
if (h.length === 3)
|
|
363
|
+
h = h.split("").map((c) => c + c).join("");
|
|
364
|
+
return [
|
|
365
|
+
parseInt(h.slice(0, 2), 16),
|
|
366
|
+
parseInt(h.slice(2, 4), 16),
|
|
367
|
+
parseInt(h.slice(4, 6), 16)
|
|
368
|
+
];
|
|
369
|
+
}
|
|
370
|
+
function rgbToHex([r, g, b]) {
|
|
371
|
+
const c = (v) => Math.round(clamp(v, 0, 255)).toString(16).padStart(2, "0");
|
|
372
|
+
return `#${c(r)}${c(g)}${c(b)}`;
|
|
373
|
+
}
|
|
374
|
+
function parseCssColour(s) {
|
|
375
|
+
const hex = hexToRgb(s);
|
|
376
|
+
if (hex) return hex;
|
|
377
|
+
const m = /rgba?\(\s*([\d.]+)[,\s]+([\d.]+)[,\s]+([\d.]+)/.exec(s);
|
|
378
|
+
if (!m) return null;
|
|
379
|
+
return [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
380
|
+
}
|
|
381
|
+
function relativeLuminance([r, g, b]) {
|
|
382
|
+
const lin = (v) => {
|
|
383
|
+
const c = v / 255;
|
|
384
|
+
return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
|
385
|
+
};
|
|
386
|
+
return 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
|
|
387
|
+
}
|
|
388
|
+
function rgbToHsl([r, g, b]) {
|
|
389
|
+
const rr = r / 255;
|
|
390
|
+
const gg = g / 255;
|
|
391
|
+
const bb = b / 255;
|
|
392
|
+
const max = Math.max(rr, gg, bb);
|
|
393
|
+
const min = Math.min(rr, gg, bb);
|
|
394
|
+
const l = (max + min) / 2;
|
|
395
|
+
if (max === min) return [0, 0, l];
|
|
396
|
+
const d = max - min;
|
|
397
|
+
const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
398
|
+
let h = 0;
|
|
399
|
+
if (max === rr) h = (gg - bb) / d + (gg < bb ? 6 : 0);
|
|
400
|
+
else if (max === gg) h = (bb - rr) / d + 2;
|
|
401
|
+
else h = (rr - gg) / d + 4;
|
|
402
|
+
return [h / 6, s, l];
|
|
403
|
+
}
|
|
404
|
+
function hslToHex(h, s, l) {
|
|
405
|
+
const f = (n) => {
|
|
406
|
+
const k = (n + h * 12) % 12;
|
|
407
|
+
const a = s * Math.min(l, 1 - l);
|
|
408
|
+
return l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));
|
|
409
|
+
};
|
|
410
|
+
return rgbToHex([f(0) * 255, f(8) * 255, f(4) * 255]);
|
|
411
|
+
}
|
|
412
|
+
function deltaE(a, b) {
|
|
413
|
+
const la = rgbToLab(a);
|
|
414
|
+
const lb = rgbToLab(b);
|
|
415
|
+
return Math.hypot(la[0] - lb[0], la[1] - lb[1], la[2] - lb[2]);
|
|
416
|
+
}
|
|
417
|
+
function rgbToLab([r, g, b]) {
|
|
418
|
+
const lin = (v) => {
|
|
419
|
+
const c = v / 255;
|
|
420
|
+
return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
|
421
|
+
};
|
|
422
|
+
const R = lin(r);
|
|
423
|
+
const G = lin(g);
|
|
424
|
+
const B = lin(b);
|
|
425
|
+
const x = (R * 0.4124 + G * 0.3576 + B * 0.1805) / 0.95047;
|
|
426
|
+
const y = R * 0.2126 + G * 0.7152 + B * 0.0722;
|
|
427
|
+
const z = (R * 0.0193 + G * 0.1192 + B * 0.9505) / 1.08883;
|
|
428
|
+
const f = (t) => t > 8856e-6 ? Math.cbrt(t) : 7.787 * t + 16 / 116;
|
|
429
|
+
return [116 * f(y) - 16, 500 * (f(x) - f(y)), 200 * (f(y) - f(z))];
|
|
430
|
+
}
|
|
431
|
+
function quoteFamily(family) {
|
|
432
|
+
const first = family.split(",")[0].trim().replace(/^['"]|['"]$/g, "");
|
|
433
|
+
const rest = family.includes(",") ? family.slice(family.indexOf(",") + 1).trim() : /mono/i.test(first) ? "ui-monospace,monospace" : "-apple-system,system-ui,sans-serif";
|
|
434
|
+
return /^[a-z-]+$/i.test(first) && /^(ui-|system-ui|sans-serif|serif|monospace)/.test(first) ? `${first},${rest}` : `'${first}',${rest}`;
|
|
435
|
+
}
|
|
436
|
+
function esc(s) {
|
|
437
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
438
|
+
}
|
|
439
|
+
function clamp(v, lo, hi) {
|
|
440
|
+
return Math.max(lo, Math.min(hi, v));
|
|
441
|
+
}
|
|
442
|
+
|
|
239
443
|
// src/capture.ts
|
|
240
444
|
var CHROME_TOP_MIN = 20;
|
|
241
445
|
var CHROME_TOP_MAX = 220;
|
|
@@ -1102,7 +1306,7 @@ function sampleAt(points, t) {
|
|
|
1102
1306
|
return { x: last.x, y: last.y };
|
|
1103
1307
|
}
|
|
1104
1308
|
function smoothCursor(track, options = {}) {
|
|
1105
|
-
const factor =
|
|
1309
|
+
const factor = clamp2(options.factor ?? 0.15, 0.01, 1);
|
|
1106
1310
|
const fps = options.fps ?? 60;
|
|
1107
1311
|
const raw = track.filter((e) => e.type === "move" || e.type === "down" || e.type === "up").map((e) => ({ t: e.t / 1e3, x: e.x, y: e.y }));
|
|
1108
1312
|
if (raw.length === 0) return [];
|
|
@@ -1121,7 +1325,7 @@ function smoothCursor(track, options = {}) {
|
|
|
1121
1325
|
if (clicks.length) {
|
|
1122
1326
|
while (ci < clicks.length - 1 && t > clicks[ci].t + SNAP_AFTER) ci++;
|
|
1123
1327
|
const ck = clicks[ci];
|
|
1124
|
-
const u =
|
|
1328
|
+
const u = clamp2(
|
|
1125
1329
|
(t - (ck.t - SNAP_BEFORE)) / SNAP_BEFORE,
|
|
1126
1330
|
0,
|
|
1127
1331
|
t <= ck.t + SNAP_AFTER ? 1 : 0
|
|
@@ -1136,7 +1340,7 @@ function smoothCursor(track, options = {}) {
|
|
|
1136
1340
|
}
|
|
1137
1341
|
return out;
|
|
1138
1342
|
}
|
|
1139
|
-
function
|
|
1343
|
+
function clamp2(v, lo, hi) {
|
|
1140
1344
|
return Math.max(lo, Math.min(hi, v));
|
|
1141
1345
|
}
|
|
1142
1346
|
|
|
@@ -1782,7 +1986,7 @@ function focusFor(cluster, width, height, targetFill, minLevel, maxLevel) {
|
|
|
1782
1986
|
const cx = clamp012(sx / n / width);
|
|
1783
1987
|
const cy = clamp012(sy / n / height);
|
|
1784
1988
|
const level = fitLevel({ x: 0, y: 0, w: maxW, h: maxH }, width, height, targetFill) ?? maxLevel;
|
|
1785
|
-
return { cx, cy, level:
|
|
1989
|
+
return { cx, cy, level: clamp3(level, minLevel, maxLevel) };
|
|
1786
1990
|
}
|
|
1787
1991
|
function clusterFocus(events, width, height) {
|
|
1788
1992
|
let sx = 0;
|
|
@@ -1815,11 +2019,11 @@ function clusterFocus(events, width, height) {
|
|
|
1815
2019
|
} : null;
|
|
1816
2020
|
return { cx: clamp012(sx / n / width), cy: clamp012(sy / n / height), rect };
|
|
1817
2021
|
}
|
|
1818
|
-
function
|
|
2022
|
+
function clamp3(v, lo, hi) {
|
|
1819
2023
|
return Math.max(lo, Math.min(hi, v));
|
|
1820
2024
|
}
|
|
1821
2025
|
function clamp012(v) {
|
|
1822
|
-
return
|
|
2026
|
+
return clamp3(v, 0, 1);
|
|
1823
2027
|
}
|
|
1824
2028
|
function round(v) {
|
|
1825
2029
|
return Math.round(v * 1e3) / 1e3;
|
|
@@ -3058,7 +3262,7 @@ function round2(v) {
|
|
|
3058
3262
|
}
|
|
3059
3263
|
|
|
3060
3264
|
// src/lower/pin.ts
|
|
3061
|
-
import { lerpArray, sample } from "@vosjs/timeline";
|
|
3265
|
+
import { lerpArray, mapTime, sample } from "@vosjs/timeline";
|
|
3062
3266
|
var PIN_GAP = 24;
|
|
3063
3267
|
var PIN_MARGIN = 24;
|
|
3064
3268
|
var PIN_SAMPLE_HZ = 30;
|
|
@@ -3077,19 +3281,27 @@ function pinReferent(doc, pin) {
|
|
|
3077
3281
|
if (pin.step !== void 0) {
|
|
3078
3282
|
const step = findStep(meta.steps ?? [], pin.step);
|
|
3079
3283
|
if (!step || step.skipped) return null;
|
|
3284
|
+
const carry = dragCarry(doc, step.tStart - 0.05, step.tEnd + 0.05);
|
|
3080
3285
|
if (step.rect && validRect(step.rect) && w > 0 && h > 0) {
|
|
3081
3286
|
return {
|
|
3082
3287
|
rect: normRect(step.rect, w, h),
|
|
3083
3288
|
by: "step",
|
|
3084
3289
|
step,
|
|
3085
|
-
at: step.tStart
|
|
3290
|
+
at: step.tStart,
|
|
3291
|
+
...carry ? { carry } : {}
|
|
3086
3292
|
};
|
|
3087
3293
|
}
|
|
3088
3294
|
const union = unionRects(
|
|
3089
3295
|
pressRects(doc, step.tStart - 0.05, step.tEnd + 0.05)
|
|
3090
3296
|
);
|
|
3091
3297
|
if (!union || w <= 0 || h <= 0) return null;
|
|
3092
|
-
return {
|
|
3298
|
+
return {
|
|
3299
|
+
rect: normRect(union, w, h),
|
|
3300
|
+
by: "step",
|
|
3301
|
+
step,
|
|
3302
|
+
at: step.tStart,
|
|
3303
|
+
...carry ? { carry } : {}
|
|
3304
|
+
};
|
|
3093
3305
|
}
|
|
3094
3306
|
if (pin.press !== void 0 && Number.isFinite(pin.press)) {
|
|
3095
3307
|
let best = null;
|
|
@@ -3101,10 +3313,42 @@ function pinReferent(doc, pin) {
|
|
|
3101
3313
|
if (!best || d < Math.abs(best.t - pin.press)) best = { t, rect: e.rect };
|
|
3102
3314
|
}
|
|
3103
3315
|
if (!best || w <= 0 || h <= 0) return null;
|
|
3104
|
-
|
|
3316
|
+
const carry = dragCarry(doc, best.t - 0.01, best.t + 0.01);
|
|
3317
|
+
return {
|
|
3318
|
+
rect: normRect(best.rect, w, h),
|
|
3319
|
+
by: "press",
|
|
3320
|
+
at: best.t,
|
|
3321
|
+
...carry ? { carry } : {}
|
|
3322
|
+
};
|
|
3105
3323
|
}
|
|
3106
3324
|
return null;
|
|
3107
3325
|
}
|
|
3326
|
+
function dragCarry(doc, from, to) {
|
|
3327
|
+
const meta = doc.source.meta;
|
|
3328
|
+
if (!(meta.width > 0) || !(meta.height > 0)) return null;
|
|
3329
|
+
const d = dragsFromTrack(doc.source.cursor, meta.width, meta.height).find(
|
|
3330
|
+
(g) => g.t0 >= from && g.t0 <= to
|
|
3331
|
+
);
|
|
3332
|
+
if (!d) return null;
|
|
3333
|
+
return { t0: d.t0, t1: d.t1, x0: d.nx, y0: d.ny };
|
|
3334
|
+
}
|
|
3335
|
+
function cursorAt(cursor, t, space) {
|
|
3336
|
+
let prev = null;
|
|
3337
|
+
for (const e of cursor) {
|
|
3338
|
+
if (e.type !== "move" && e.type !== "down" && e.type !== "up") continue;
|
|
3339
|
+
const cur = { t: e.t / 1e3, nx: e.x / space.w, ny: e.y / space.h };
|
|
3340
|
+
if (cur.t >= t) {
|
|
3341
|
+
if (!prev) return { nx: cur.nx, ny: cur.ny };
|
|
3342
|
+
const k = cur.t > prev.t ? (t - prev.t) / (cur.t - prev.t) : 1;
|
|
3343
|
+
return {
|
|
3344
|
+
nx: prev.nx + (cur.nx - prev.nx) * k,
|
|
3345
|
+
ny: prev.ny + (cur.ny - prev.ny) * k
|
|
3346
|
+
};
|
|
3347
|
+
}
|
|
3348
|
+
prev = cur;
|
|
3349
|
+
}
|
|
3350
|
+
return prev ? { nx: prev.nx, ny: prev.ny } : null;
|
|
3351
|
+
}
|
|
3108
3352
|
function findStep(steps, ref) {
|
|
3109
3353
|
const byId = steps.find((s) => s.id !== void 0 && s.id === ref);
|
|
3110
3354
|
if (byId) return byId;
|
|
@@ -3188,6 +3432,20 @@ function pinRectOnScreen(rect, t, layout, camera, zoomTrack) {
|
|
|
3188
3432
|
const b = map(rect.x + rect.w, rect.y + rect.h);
|
|
3189
3433
|
return { x: a.x, y: a.y, w: b.x - a.x, h: b.y - a.y };
|
|
3190
3434
|
}
|
|
3435
|
+
function pinReferentAt(referent, t, input) {
|
|
3436
|
+
const { carry, cursor, space, rated } = input;
|
|
3437
|
+
if (!carry || !cursor || !space || !rated) return referent;
|
|
3438
|
+
const s = mapTime(rated, t);
|
|
3439
|
+
const sc = Math.max(carry.t0, Math.min(carry.t1, s));
|
|
3440
|
+
const p = cursorAt(cursor, sc, space);
|
|
3441
|
+
if (!p) return referent;
|
|
3442
|
+
return {
|
|
3443
|
+
x: referent.x + (p.nx - carry.x0),
|
|
3444
|
+
y: referent.y + (p.ny - carry.y0),
|
|
3445
|
+
w: referent.w,
|
|
3446
|
+
h: referent.h
|
|
3447
|
+
};
|
|
3448
|
+
}
|
|
3191
3449
|
function pinPlacement(input) {
|
|
3192
3450
|
const { clip, referent, layout, camera, zoomTrack, base, motion } = input;
|
|
3193
3451
|
const dur = Math.max(1e-3, clip.duration);
|
|
@@ -3195,7 +3453,13 @@ function pinPlacement(input) {
|
|
|
3195
3453
|
const box = pinBox(clip, layout);
|
|
3196
3454
|
const W = layout.W;
|
|
3197
3455
|
const H = layout.H;
|
|
3198
|
-
const refAt = (local) => pinRectOnScreen(
|
|
3456
|
+
const refAt = (local) => pinRectOnScreen(
|
|
3457
|
+
pinReferentAt(referent, clip.start + local, input),
|
|
3458
|
+
clip.start + local,
|
|
3459
|
+
layout,
|
|
3460
|
+
camera,
|
|
3461
|
+
zoomTrack
|
|
3462
|
+
);
|
|
3199
3463
|
const centreFor = (r, side2) => {
|
|
3200
3464
|
switch (side2) {
|
|
3201
3465
|
case "right":
|
|
@@ -6670,6 +6934,15 @@ var ON_FRAME = `(ctx, content, dt) => {
|
|
|
6670
6934
|
if (pn.dur - pnT < 0.35) { var pnV = (pn.dur - pnT) / 0.35; pnA = Math.min(pnA, 1 - Math.pow(1 - pnV, 3)) }
|
|
6671
6935
|
if (pnA <= 0.004) continue
|
|
6672
6936
|
var pnX = dx + pn.x * dw, pnY = dy + pn.y * dh, pnW = pn.w * dw, pnH = pn.h * dh
|
|
6937
|
+
// a carried referent (a drag): moved by where the pointer has taken
|
|
6938
|
+
// it at the on-screen source moment, held at the release
|
|
6939
|
+
if (pn.carry) {
|
|
6940
|
+
var pcC = (actM ? actM.cursor : d.cursor) || []
|
|
6941
|
+
var pcT = Math.max(pn.carry.t0, Math.min(pn.carry.t1, srcT))
|
|
6942
|
+
var pcx = -1, pcy = -1
|
|
6943
|
+
for (var pk = 0; pk < pcC.length; pk++) { if (pcC[pk].t <= pcT) { pcx = pcC[pk].x; pcy = pcC[pk].y } }
|
|
6944
|
+
if (pcx >= 0) { pnX += (pcx / (space.w || vw) - pn.carry.x0) * dw; pnY += (pcy / (space.h || vh) - pn.carry.y0) * dh }
|
|
6945
|
+
}
|
|
6673
6946
|
var pnLw = 2 * s2 / ceZs, pnPad = 6 * s2 / ceZs
|
|
6674
6947
|
var pnCol = pn.color || 'rgba(255,255,255,0.95)'
|
|
6675
6948
|
c.save()
|
|
@@ -6839,6 +7112,15 @@ var ON_FRAME = `(ctx, content, dt) => {
|
|
|
6839
7112
|
// the referent's corners in frame space under the live camera
|
|
6840
7113
|
var pqAx = dx + pq.x * dw, pqAy = dy + pq.y * dh
|
|
6841
7114
|
var pqBx = dx + (pq.x + pq.w) * dw, pqBy = dy + (pq.y + pq.h) * dh
|
|
7115
|
+
if (pq.carry) {
|
|
7116
|
+
var pqcT = Math.max(pq.carry.t0, Math.min(pq.carry.t1, srcT))
|
|
7117
|
+
var pqcx = -1, pqcy = -1
|
|
7118
|
+
for (var pqk = 0; pqk < cur.length; pqk++) { if (cur[pqk].t <= pqcT) { pqcx = cur[pqk].x; pqcy = cur[pqk].y } }
|
|
7119
|
+
if (pqcx >= 0) {
|
|
7120
|
+
var pqOx = (pqcx / (space.w || vw) - pq.carry.x0) * dw, pqOy = (pqcy / (space.h || vh) - pq.carry.y0) * dh
|
|
7121
|
+
pqAx += pqOx; pqBx += pqOx; pqAy += pqOy; pqBy += pqOy
|
|
7122
|
+
}
|
|
7123
|
+
}
|
|
6842
7124
|
if (lvl > 1.001 && !d.zoomSuppressed) {
|
|
6843
7125
|
if (camStage) {
|
|
6844
7126
|
pqAx = W / 2 + (pqAx - wcx) * lvl; pqAy = H / 2 + (pqAy - wcy) * lvl
|
|
@@ -7423,6 +7705,8 @@ function docZoomTrack(input) {
|
|
|
7423
7705
|
}
|
|
7424
7706
|
function resolvePins(doc, layout, camera, zoomTrack) {
|
|
7425
7707
|
const out = /* @__PURE__ */ new Map();
|
|
7708
|
+
const rated = ratedSegments(doc);
|
|
7709
|
+
const space = { w: doc.source.meta.width, h: doc.source.meta.height };
|
|
7426
7710
|
for (const o of doc.overlays ?? []) {
|
|
7427
7711
|
if (!o.pin) continue;
|
|
7428
7712
|
const ref = pinReferent(doc, o.pin);
|
|
@@ -7442,12 +7726,39 @@ function resolvePins(doc, layout, camera, zoomTrack) {
|
|
|
7442
7726
|
camera,
|
|
7443
7727
|
zoomTrack,
|
|
7444
7728
|
base,
|
|
7445
|
-
motion
|
|
7729
|
+
motion,
|
|
7730
|
+
carry: ref.carry ?? null,
|
|
7731
|
+
cursor: doc.source.cursor,
|
|
7732
|
+
space,
|
|
7733
|
+
rated
|
|
7446
7734
|
})
|
|
7447
7735
|
);
|
|
7448
7736
|
}
|
|
7449
7737
|
return out;
|
|
7450
7738
|
}
|
|
7739
|
+
function pinCandidates(doc, clip) {
|
|
7740
|
+
const rated = ratedSegments(doc);
|
|
7741
|
+
const out = [];
|
|
7742
|
+
const a0 = clip.start;
|
|
7743
|
+
const a1 = clip.start + clip.duration;
|
|
7744
|
+
for (const s of doc.source.meta.steps ?? []) {
|
|
7745
|
+
if (s.skipped) continue;
|
|
7746
|
+
const ref = pinReferent(doc, { step: s.id ?? s.step });
|
|
7747
|
+
if (!ref) continue;
|
|
7748
|
+
const ext = spanOutputExtent(rated, s.tStart, s.tEnd);
|
|
7749
|
+
if (!ext) continue;
|
|
7750
|
+
const overlap = Math.min(a1, ext.end) - Math.max(a0, ext.start);
|
|
7751
|
+
if (overlap <= 0) continue;
|
|
7752
|
+
out.push({
|
|
7753
|
+
step: s.id ?? s.step,
|
|
7754
|
+
do: s.do,
|
|
7755
|
+
...s.selector ? { selector: s.selector } : {},
|
|
7756
|
+
output: { start: round7(ext.start), end: round7(ext.end) },
|
|
7757
|
+
overlap: round7(overlap)
|
|
7758
|
+
});
|
|
7759
|
+
}
|
|
7760
|
+
return out.sort((x, y) => y.overlap - x.overlap);
|
|
7761
|
+
}
|
|
7451
7762
|
function overlayPinPoseAt(doc, o, t) {
|
|
7452
7763
|
if (!o.pin) return null;
|
|
7453
7764
|
const layout = docCardLayout(doc);
|
|
@@ -7484,6 +7795,16 @@ function pinsDataOf(doc, pins) {
|
|
|
7484
7795
|
mark,
|
|
7485
7796
|
leader: !!p.leader,
|
|
7486
7797
|
...p.color ? { color: p.color } : {},
|
|
7798
|
+
// A carried referent (a drag): ON_FRAME moves the mark and the
|
|
7799
|
+
// leader's end with the pointer through [t0, t1], source seconds.
|
|
7800
|
+
...ref.carry ? {
|
|
7801
|
+
carry: {
|
|
7802
|
+
t0: round7(ref.carry.t0),
|
|
7803
|
+
t1: round7(ref.carry.t1),
|
|
7804
|
+
x0: round43(ref.carry.x0),
|
|
7805
|
+
y0: round43(ref.carry.y0)
|
|
7806
|
+
}
|
|
7807
|
+
} : {},
|
|
7487
7808
|
enter: enterKey(o),
|
|
7488
7809
|
tip: placed.tip
|
|
7489
7810
|
});
|
|
@@ -8439,12 +8760,12 @@ function round10(v) {
|
|
|
8439
8760
|
}
|
|
8440
8761
|
|
|
8441
8762
|
// src/timeline/rangeActions.ts
|
|
8442
|
-
import { mapTime } from "@vosjs/timeline";
|
|
8763
|
+
import { mapTime as mapTime2 } from "@vosjs/timeline";
|
|
8443
8764
|
function outputRangeToSource(doc, t0, t1) {
|
|
8444
8765
|
const rated = ratedSegments(doc);
|
|
8445
8766
|
return {
|
|
8446
|
-
srcIn:
|
|
8447
|
-
srcOut:
|
|
8767
|
+
srcIn: mapTime2(rated, Math.max(0, t0)),
|
|
8768
|
+
srcOut: mapTime2(rated, Math.max(0, t1))
|
|
8448
8769
|
};
|
|
8449
8770
|
}
|
|
8450
8771
|
var EPS = 1e-6;
|
|
@@ -8985,24 +9306,31 @@ function destinationsForChannel(channel) {
|
|
|
8985
9306
|
}
|
|
8986
9307
|
|
|
8987
9308
|
// src/htmlStarters.ts
|
|
9309
|
+
function grammarStarter(id, name, words) {
|
|
9310
|
+
const clip = calloutClip(id, HOUSE_REGISTER, words, {
|
|
9311
|
+
id,
|
|
9312
|
+
start: 0,
|
|
9313
|
+
duration: 1,
|
|
9314
|
+
scale: 1.4
|
|
9315
|
+
});
|
|
9316
|
+
return { id, name, html: clip.html, css: clip.css ?? "", box: clip.box };
|
|
9317
|
+
}
|
|
8988
9318
|
var WORDS = "font-family:'Inter',-apple-system,system-ui,sans-serif;color:#fafafa;-webkit-font-smoothing:antialiased;";
|
|
8989
9319
|
var MONO = "font-family:'JetBrains Mono',ui-monospace,monospace;";
|
|
8990
9320
|
var CARD = "background:#0b0b0d;border:1px solid rgba(255,255,255,.08);border-radius:16px;box-shadow:0 24px 60px rgba(0,0,0,.45);";
|
|
8991
9321
|
var HTML_STARTERS = [
|
|
8992
|
-
|
|
8993
|
-
|
|
8994
|
-
|
|
8995
|
-
|
|
8996
|
-
|
|
8997
|
-
|
|
8998
|
-
},
|
|
8999
|
-
{
|
|
9000
|
-
|
|
9001
|
-
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
css: `.code{${MONO}${CARD}color:#e8e8ec;box-sizing:border-box;width:460px;height:168px;padding:22px 24px;font-size:14px;line-height:1.8;white-space:pre;letter-spacing:-0.01em}.kw{color:#c4b5fd}.fn{color:#7dd3fc}.tag{color:#f0abfc}.mut{color:#5b5b66}`
|
|
9005
|
-
},
|
|
9322
|
+
// The callout grammar (three shapes a viewer learns once), in the house
|
|
9323
|
+
// register: a dark card in the house hue over a light app.
|
|
9324
|
+
grammarStarter("note", "Note", {
|
|
9325
|
+
kicker: "Presets",
|
|
9326
|
+
title: "One of 43, picked here.",
|
|
9327
|
+
body: "One line that says what this is about."
|
|
9328
|
+
}),
|
|
9329
|
+
grammarStarter("tag", "Tag", { kicker: "New in 2.0" }),
|
|
9330
|
+
grammarStarter("code", "Code", {
|
|
9331
|
+
kicker: "index.css",
|
|
9332
|
+
code: ":root {\n --primary: oklch(0.63 0.06 4.6);\n --radius: 2.25rem;\n}"
|
|
9333
|
+
}),
|
|
9006
9334
|
{
|
|
9007
9335
|
id: "terminal",
|
|
9008
9336
|
name: "Terminal",
|
|
@@ -9209,7 +9537,7 @@ function applyLook(frame, look, size, video, placement) {
|
|
|
9209
9537
|
|
|
9210
9538
|
// src/timeline/lanes.ts
|
|
9211
9539
|
import {
|
|
9212
|
-
mapTime as
|
|
9540
|
+
mapTime as mapTime3,
|
|
9213
9541
|
removeSegment,
|
|
9214
9542
|
segmentRate as segmentRate3,
|
|
9215
9543
|
sourceToTimeline as sourceToTimeline2,
|
|
@@ -9277,7 +9605,7 @@ var videoLane = {
|
|
|
9277
9605
|
index === 0 || !contiguous(segments, index)
|
|
9278
9606
|
);
|
|
9279
9607
|
const anchorOut = sourceToTimeline2(fullMap, Math.min(edgeSrc, sourceDuration)) ?? edgeSrc;
|
|
9280
|
-
const sourceT =
|
|
9608
|
+
const sourceT = mapTime3(fullMap, anchorOut + (g.t - edgeOutNow));
|
|
9281
9609
|
const next = trimSegment(
|
|
9282
9610
|
segments,
|
|
9283
9611
|
index,
|
|
@@ -9313,7 +9641,7 @@ var videoLane = {
|
|
|
9313
9641
|
return null;
|
|
9314
9642
|
}
|
|
9315
9643
|
const sourceT = round12(
|
|
9316
|
-
|
|
9644
|
+
mapTime3(segmentPieces(s, speeds, freezes, leading), local)
|
|
9317
9645
|
);
|
|
9318
9646
|
if (sourceT - s.in < 0.05 || s.out - sourceT < 0.05) return null;
|
|
9319
9647
|
const next = [
|
|
@@ -9403,7 +9731,7 @@ var freezeLane = {
|
|
|
9403
9731
|
if (g.t >= m.t - 1e-9 && g.t <= m.t + m.duration + 1e-9) return null;
|
|
9404
9732
|
}
|
|
9405
9733
|
if (g.t > totalDuration7(rated) + 1e-9) return null;
|
|
9406
|
-
const srcT = round12(
|
|
9734
|
+
const srcT = round12(mapTime3(rated, Math.max(0, g.t)));
|
|
9407
9735
|
if (!kept(srcT) || !clear(srcT)) return null;
|
|
9408
9736
|
const id = nextFreezeId(doc);
|
|
9409
9737
|
const mediaHere = mediaAtOutput(rated, Math.max(0, g.t));
|
|
@@ -9446,7 +9774,7 @@ var freezeLane = {
|
|
|
9446
9774
|
const mine = marks.get(f.id);
|
|
9447
9775
|
const endOut = mine ? mine.t + mine.duration : null;
|
|
9448
9776
|
const srcT = round12(
|
|
9449
|
-
Math.min(sourceDuration,
|
|
9777
|
+
Math.min(sourceDuration, mapTime3(base, Math.max(0, g.t)))
|
|
9450
9778
|
);
|
|
9451
9779
|
if (!kept(srcT) || !clear(srcT, f.id)) return null;
|
|
9452
9780
|
return (d) => {
|
|
@@ -9517,7 +9845,7 @@ var zoomLane = {
|
|
|
9517
9845
|
const rated = ratedSegments(doc);
|
|
9518
9846
|
const sourceDuration = anchorSourceDuration(doc);
|
|
9519
9847
|
if (g.type === "create") {
|
|
9520
|
-
const srcT =
|
|
9848
|
+
const srcT = mapTime3(rated, Math.max(0, g.t));
|
|
9521
9849
|
const mediaHere = mediaAtOutput(rated, Math.max(0, g.t));
|
|
9522
9850
|
const here = spans.filter((z) => (z.media ?? "") === mediaHere);
|
|
9523
9851
|
const mediaLen = mediaDuration(mediaSource(doc, mediaHere) ?? doc.source);
|
|
@@ -9551,7 +9879,7 @@ var zoomLane = {
|
|
|
9551
9879
|
const len = sp.out - sp.in;
|
|
9552
9880
|
let newIn = clampToKept(
|
|
9553
9881
|
effectiveSegments(doc),
|
|
9554
|
-
|
|
9882
|
+
mapTime3(rated, Math.max(0, g.t)),
|
|
9555
9883
|
len
|
|
9556
9884
|
);
|
|
9557
9885
|
for (const o of others) {
|
|
@@ -9581,7 +9909,7 @@ var zoomLane = {
|
|
|
9581
9909
|
sourceDuration,
|
|
9582
9910
|
...others.filter((o) => o.in >= sp.out).map((o) => o.in)
|
|
9583
9911
|
);
|
|
9584
|
-
const sourceT =
|
|
9912
|
+
const sourceT = mapTime3(rated, Math.max(0, g.t));
|
|
9585
9913
|
const minSrc = Math.min(
|
|
9586
9914
|
ZOOM_SPAN_MIN * rateAt(rated, sp.in),
|
|
9587
9915
|
sp.out - sp.in
|
|
@@ -9646,7 +9974,7 @@ var tiltLane = {
|
|
|
9646
9974
|
const rated = ratedSegments(doc);
|
|
9647
9975
|
const sourceDuration = anchorSourceDuration(doc);
|
|
9648
9976
|
if (g.type === "create") {
|
|
9649
|
-
const srcT =
|
|
9977
|
+
const srcT = mapTime3(rated, Math.max(0, g.t));
|
|
9650
9978
|
const mediaHere = mediaAtOutput(rated, Math.max(0, g.t));
|
|
9651
9979
|
const here = spans.filter((z) => (z.media ?? "") === mediaHere);
|
|
9652
9980
|
const mediaLen = mediaDuration(mediaSource(doc, mediaHere) ?? doc.source);
|
|
@@ -9678,7 +10006,7 @@ var tiltLane = {
|
|
|
9678
10006
|
const len = sp.out - sp.in;
|
|
9679
10007
|
let newIn = clampToKept(
|
|
9680
10008
|
effectiveSegments(doc),
|
|
9681
|
-
|
|
10009
|
+
mapTime3(rated, Math.max(0, g.t)),
|
|
9682
10010
|
len
|
|
9683
10011
|
);
|
|
9684
10012
|
for (const o of others) {
|
|
@@ -9708,7 +10036,7 @@ var tiltLane = {
|
|
|
9708
10036
|
sourceDuration,
|
|
9709
10037
|
...others.filter((o) => o.in >= sp.out).map((o) => o.in)
|
|
9710
10038
|
);
|
|
9711
|
-
const sourceT =
|
|
10039
|
+
const sourceT = mapTime3(rated, Math.max(0, g.t));
|
|
9712
10040
|
const minSrc = Math.min(
|
|
9713
10041
|
TILT_SPAN_MIN * rateAt(rated, sp.in),
|
|
9714
10042
|
sp.out - sp.in
|
|
@@ -9764,7 +10092,7 @@ var camMoveLane = {
|
|
|
9764
10092
|
const sourceDuration = anchorSourceDuration(doc);
|
|
9765
10093
|
if (g.type === "create") {
|
|
9766
10094
|
if (!doc.source.camKey) return null;
|
|
9767
|
-
const srcT =
|
|
10095
|
+
const srcT = mapTime3(rated, Math.max(0, g.t));
|
|
9768
10096
|
if (spans.some((z) => srcT >= z.in && srcT < z.out)) return null;
|
|
9769
10097
|
const next = spans.filter((z) => z.in > srcT).sort((a, b) => a.in - b.in).at(0);
|
|
9770
10098
|
const limit = Math.min(sourceDuration, next ? next.in : sourceDuration);
|
|
@@ -9791,7 +10119,7 @@ var camMoveLane = {
|
|
|
9791
10119
|
const len = sp.out - sp.in;
|
|
9792
10120
|
let newIn = clampToKept(
|
|
9793
10121
|
effectiveSegments(doc),
|
|
9794
|
-
|
|
10122
|
+
mapTime3(rated, Math.max(0, g.t)),
|
|
9795
10123
|
len
|
|
9796
10124
|
);
|
|
9797
10125
|
for (const o of others) {
|
|
@@ -9821,7 +10149,7 @@ var camMoveLane = {
|
|
|
9821
10149
|
sourceDuration,
|
|
9822
10150
|
...others.filter((o) => o.in >= sp.out).map((o) => o.in)
|
|
9823
10151
|
);
|
|
9824
|
-
const sourceT =
|
|
10152
|
+
const sourceT = mapTime3(rated, Math.max(0, g.t));
|
|
9825
10153
|
const minSrc = Math.min(
|
|
9826
10154
|
CAM_SPAN_MIN * rateAt(rated, sp.in),
|
|
9827
10155
|
sp.out - sp.in
|
|
@@ -9895,7 +10223,7 @@ var camLane = {
|
|
|
9895
10223
|
if (!seg) return null;
|
|
9896
10224
|
const clipSrcStart = Math.max(seg.in, Math.max(current.in, first.in));
|
|
9897
10225
|
const span = Math.max(0.05, current.out - current.in);
|
|
9898
|
-
const delta =
|
|
10226
|
+
const delta = mapTime3(rated, Math.max(0, g.t)) - clipSrcStart;
|
|
9899
10227
|
const base = Math.max(first.in, current.in);
|
|
9900
10228
|
const newIn = Math.min(
|
|
9901
10229
|
Math.max(first.in, base + delta),
|
|
@@ -9911,7 +10239,7 @@ var camLane = {
|
|
|
9911
10239
|
})).filter((x) => x.len > 1e-6);
|
|
9912
10240
|
const edgeIdx = g.edge === "start" ? overlapping.at(0)?.i : overlapping.at(-1)?.i;
|
|
9913
10241
|
if (edgeIdx === void 0 || g.id !== `cam-${edgeIdx}`) return null;
|
|
9914
|
-
const sourceT = Math.min(Math.max(
|
|
10242
|
+
const sourceT = Math.min(Math.max(mapTime3(rated, g.t), 0), sourceDuration);
|
|
9915
10243
|
const next = g.edge === "start" ? { in: Math.min(sourceT, current.out - 0.05), out: current.out } : { in: current.in, out: Math.max(sourceT, current.in + 0.05) };
|
|
9916
10244
|
return (d) => {
|
|
9917
10245
|
d.cam.window = {
|
|
@@ -10005,7 +10333,7 @@ var speedLane = {
|
|
|
10005
10333
|
const rated = ratedSegments(doc);
|
|
10006
10334
|
const sourceDuration = anchorSourceDuration(doc);
|
|
10007
10335
|
if (g.type === "create") {
|
|
10008
|
-
const srcT =
|
|
10336
|
+
const srcT = mapTime3(rated, Math.max(0, g.t));
|
|
10009
10337
|
if (spans.some((s) => srcT >= s.in && srcT < s.out)) return null;
|
|
10010
10338
|
const next = spans.filter((s) => s.in > srcT).sort((a, b) => a.in - b.in).at(0);
|
|
10011
10339
|
const limit = Math.min(sourceDuration, next ? next.in : sourceDuration);
|
|
@@ -10035,7 +10363,7 @@ var speedLane = {
|
|
|
10035
10363
|
const len = sp.out - sp.in;
|
|
10036
10364
|
let newIn = clampToKept(
|
|
10037
10365
|
effectiveSegments(doc),
|
|
10038
|
-
|
|
10366
|
+
mapTime3(base, Math.max(0, g.t)),
|
|
10039
10367
|
len
|
|
10040
10368
|
);
|
|
10041
10369
|
for (const o of others) {
|
|
@@ -10064,7 +10392,7 @@ var speedLane = {
|
|
|
10064
10392
|
const minSrc = Math.min(SPEED_SPAN_MIN * sp.rate, sp.out - sp.in);
|
|
10065
10393
|
let next;
|
|
10066
10394
|
if (g.edge === "start") {
|
|
10067
|
-
const sourceT =
|
|
10395
|
+
const sourceT = mapTime3(base, Math.max(0, g.t));
|
|
10068
10396
|
next = {
|
|
10069
10397
|
in: Math.min(Math.max(lo, sourceT), sp.out - minSrc),
|
|
10070
10398
|
out: sp.out
|
|
@@ -10432,7 +10760,7 @@ function computePeaks(channels, buckets) {
|
|
|
10432
10760
|
}
|
|
10433
10761
|
|
|
10434
10762
|
// src/lower/duckCurve.ts
|
|
10435
|
-
import { mapTime as
|
|
10763
|
+
import { mapTime as mapTime4 } from "@vosjs/timeline";
|
|
10436
10764
|
var DEFAULT_DUCK = {
|
|
10437
10765
|
threshold: 0.02,
|
|
10438
10766
|
duckTo: 0.25,
|
|
@@ -10468,7 +10796,7 @@ function duckCurve(rms, segments, durationSec2, opts = DEFAULT_DUCK) {
|
|
|
10468
10796
|
const steps = Math.ceil(durationSec2 * opts.gridHz);
|
|
10469
10797
|
for (let i = 0; i <= steps; i++) {
|
|
10470
10798
|
const t = Math.min(durationSec2, i * dt);
|
|
10471
|
-
const srcT =
|
|
10799
|
+
const srcT = mapTime4(segments, t);
|
|
10472
10800
|
const w = Math.min(
|
|
10473
10801
|
rms.values.length - 1,
|
|
10474
10802
|
Math.max(0, Math.floor(srcT * rms.rate))
|
|
@@ -10543,6 +10871,9 @@ export {
|
|
|
10543
10871
|
AUDIO_PLAN_STEP,
|
|
10544
10872
|
BACKGROUND_Z,
|
|
10545
10873
|
BASE_FRAME_STYLE,
|
|
10874
|
+
CALLOUT_DEFAULT_BODY_PX,
|
|
10875
|
+
CALLOUT_SHAPES,
|
|
10876
|
+
CALLOUT_TYPE_RATIO,
|
|
10546
10877
|
CAMERA_CENTRE_RAMP,
|
|
10547
10878
|
CAMERA_COVER_MIN,
|
|
10548
10879
|
CAMERA_FAR,
|
|
@@ -10617,6 +10948,7 @@ export {
|
|
|
10617
10948
|
FREEZE_SECONDS_MAX,
|
|
10618
10949
|
FREEZE_SECONDS_MIN,
|
|
10619
10950
|
HOUSE_GRADIENT,
|
|
10951
|
+
HOUSE_REGISTER,
|
|
10620
10952
|
HTML_LAYER_FOREIGN_FIELDS,
|
|
10621
10953
|
HTML_LAYER_MAX_BYTES,
|
|
10622
10954
|
HTML_LAYER_SVG_CODE,
|
|
@@ -10708,6 +11040,11 @@ export {
|
|
|
10708
11040
|
audioLane,
|
|
10709
11041
|
backdropMedia,
|
|
10710
11042
|
buildDigest,
|
|
11043
|
+
calloutBox,
|
|
11044
|
+
calloutClip,
|
|
11045
|
+
calloutGroundOf,
|
|
11046
|
+
calloutLook,
|
|
11047
|
+
calloutSource,
|
|
10711
11048
|
camBubbleRect,
|
|
10712
11049
|
camBubbleRectAt,
|
|
10713
11050
|
camLane,
|
|
@@ -10742,6 +11079,7 @@ export {
|
|
|
10742
11079
|
cssFamilies,
|
|
10743
11080
|
cssWeights,
|
|
10744
11081
|
cursorIdleFade,
|
|
11082
|
+
deltaE,
|
|
10745
11083
|
deriveViewportCrop,
|
|
10746
11084
|
destinationById,
|
|
10747
11085
|
destinationsForChannel,
|
|
@@ -10779,6 +11117,7 @@ export {
|
|
|
10779
11117
|
frameGeometry,
|
|
10780
11118
|
freezeLane,
|
|
10781
11119
|
freezeOutputExtents,
|
|
11120
|
+
hexToRgb,
|
|
10782
11121
|
hexToRgbTriplet,
|
|
10783
11122
|
houseLook,
|
|
10784
11123
|
htmlLayerBleed,
|
|
@@ -10849,12 +11188,15 @@ export {
|
|
|
10849
11188
|
overlaysLane,
|
|
10850
11189
|
ownFreezes,
|
|
10851
11190
|
pageDisplayUrl,
|
|
11191
|
+
parseCssColour,
|
|
10852
11192
|
parsePoseId,
|
|
10853
11193
|
pickStyle,
|
|
10854
11194
|
pinBox,
|
|
11195
|
+
pinCandidates,
|
|
10855
11196
|
pinPlacement,
|
|
10856
11197
|
pinRectOnScreen,
|
|
10857
11198
|
pinReferent,
|
|
11199
|
+
pinReferentAt,
|
|
10858
11200
|
placeFreezes,
|
|
10859
11201
|
planAutoSpeed,
|
|
10860
11202
|
planAutoTilt,
|
|
@@ -10868,6 +11210,7 @@ export {
|
|
|
10868
11210
|
recommendedExportResolution,
|
|
10869
11211
|
refillAudioBeds,
|
|
10870
11212
|
rejectSpan,
|
|
11213
|
+
relativeLuminance,
|
|
10871
11214
|
removeSourceRange,
|
|
10872
11215
|
removeSpeedInRange,
|
|
10873
11216
|
resolveExportSize,
|
|
@@ -10878,6 +11221,7 @@ export {
|
|
|
10878
11221
|
resolveZoomStyle,
|
|
10879
11222
|
restLeanOf,
|
|
10880
11223
|
restSpansThroughTransitions,
|
|
11224
|
+
rgbToHex,
|
|
10881
11225
|
sameMedia,
|
|
10882
11226
|
sceneChanges,
|
|
10883
11227
|
scrollRuns,
|