reframe-video 0.1.2 → 0.2.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.
Files changed (42) hide show
  1. package/assets/sfx/LICENSE.md +1 -1
  2. package/assets/sfx/bong_001.ogg +0 -0
  3. package/assets/sfx/click_001.ogg +0 -0
  4. package/assets/sfx/confirmation_002.ogg +0 -0
  5. package/assets/sfx/confirmation_003.ogg +0 -0
  6. package/assets/sfx/confirmation_004.ogg +0 -0
  7. package/assets/sfx/glass_001.ogg +0 -0
  8. package/assets/sfx/maximize_001.ogg +0 -0
  9. package/assets/sfx/maximize_002.ogg +0 -0
  10. package/assets/sfx/maximize_005.ogg +0 -0
  11. package/assets/sfx/maximize_009.ogg +0 -0
  12. package/assets/sfx/open_001.ogg +0 -0
  13. package/assets/sfx/pluck_001.ogg +0 -0
  14. package/assets/sfx/pluck_002.ogg +0 -0
  15. package/assets/sfx/select_001.ogg +0 -0
  16. package/assets/sfx/select_002.ogg +0 -0
  17. package/assets/sfx/select_003.ogg +0 -0
  18. package/dist/bin.js +724 -131
  19. package/dist/browserEntry.js +130 -68
  20. package/dist/cli.js +445 -85
  21. package/dist/index.js +674 -86
  22. package/dist/labels.js +606 -0
  23. package/dist/renderer-canvas.js +15 -0
  24. package/dist/trace-cli.js +9 -9
  25. package/dist/types/audio.d.ts +9 -0
  26. package/dist/types/compile.d.ts +1 -0
  27. package/dist/types/compose.d.ts +18 -2
  28. package/dist/types/composeComposition.d.ts +27 -0
  29. package/dist/types/devicePreset.d.ts +65 -0
  30. package/dist/types/dsl.d.ts +12 -1
  31. package/dist/types/evaluate.d.ts +32 -0
  32. package/dist/types/index.d.ts +6 -3
  33. package/dist/types/ir.d.ts +68 -0
  34. package/dist/types/motionOps.d.ts +36 -0
  35. package/dist/types/path.d.ts +7 -3
  36. package/dist/types/validate.d.ts +4 -1
  37. package/guides/edsl-guide.md +2 -1
  38. package/package.json +1 -1
  39. package/preview/index.html +56 -3
  40. package/preview/src/main.ts +1132 -46
  41. package/preview/src/panel.ts +478 -8
  42. package/preview/src/store.ts +323 -6
@@ -27,7 +27,7 @@
27
27
  if (n < 2) return 0;
28
28
  return closed ? n : n - 1;
29
29
  }
30
- function pathPoint(points, closed, u) {
30
+ function pathPoint(points, closed, u, curviness = 1) {
31
31
  const n = points.length;
32
32
  if (n === 0) return [0, 0];
33
33
  if (n === 1) return [points[0][0], points[0][1]];
@@ -36,19 +36,41 @@
36
36
  const [p0, p1, p2, p3] = controls(points, closed, i);
37
37
  const t2 = t * t;
38
38
  const t3 = t2 * t;
39
- const f = (a, b, c, d) => 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t2 + (-a + 3 * b - 3 * c + d) * t3);
40
- return [f(p0[0], p1[0], p2[0], p3[0]), f(p0[1], p1[1], p2[1], p3[1])];
39
+ if (curviness === 1) {
40
+ const f = (a, b, c, d) => 0.5 * (2 * b + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t2 + (-a + 3 * b - 3 * c + d) * t3);
41
+ return [f(p0[0], p1[0], p2[0], p3[0]), f(p0[1], p1[1], p2[1], p3[1])];
42
+ }
43
+ const h00 = 2 * t3 - 3 * t2 + 1;
44
+ const h10 = t3 - 2 * t2 + t;
45
+ const h01 = -2 * t3 + 3 * t2;
46
+ const h11 = t3 - t2;
47
+ const k = curviness * 0.5;
48
+ const H = (a, b, c, d) => h00 * b + h10 * k * (c - a) + h01 * c + h11 * k * (d - b);
49
+ return [H(p0[0], p1[0], p2[0], p3[0]), H(p0[1], p1[1], p2[1], p3[1])];
41
50
  }
42
- function pathTangentAngle(points, closed, u) {
51
+ function pathTangentAngle(points, closed, u, curviness = 1) {
43
52
  const n = points.length;
44
53
  if (n < 2) return 0;
45
54
  const segs = segCountOf(points, closed);
46
55
  const { i, t } = locate(segs, u);
47
56
  const [p0, p1, p2, p3] = controls(points, closed, i);
48
57
  const t2 = t * t;
49
- const d = (a, b, c, e) => 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - e) * t + 3 * (-a + 3 * b - 3 * c + e) * t2);
50
- const dx = d(p0[0], p1[0], p2[0], p3[0]);
51
- const dy = d(p0[1], p1[1], p2[1], p3[1]);
58
+ let dx;
59
+ let dy;
60
+ if (curviness === 1) {
61
+ const d = (a, b, c, e) => 0.5 * (-a + c + 2 * (2 * a - 5 * b + 4 * c - e) * t + 3 * (-a + 3 * b - 3 * c + e) * t2);
62
+ dx = d(p0[0], p1[0], p2[0], p3[0]);
63
+ dy = d(p0[1], p1[1], p2[1], p3[1]);
64
+ } else {
65
+ const g00 = 6 * t2 - 6 * t;
66
+ const g10 = 3 * t2 - 4 * t + 1;
67
+ const g01 = -6 * t2 + 6 * t;
68
+ const g11 = 3 * t2 - 2 * t;
69
+ const k = curviness * 0.5;
70
+ const D = (a, b, c, e) => g00 * b + g10 * k * (c - a) + g01 * c + g11 * k * (e - b);
71
+ dx = D(p0[0], p1[0], p2[0], p3[0]);
72
+ dy = D(p0[1], p1[1], p2[1], p3[1]);
73
+ }
52
74
  if (dx === 0 && dy === 0) return 0;
53
75
  return Math.atan2(dy, dx) * 180 / Math.PI;
54
76
  }
@@ -125,8 +147,8 @@
125
147
  const currentValue = (target, prop) => {
126
148
  const v = current.get(key(target, prop));
127
149
  if (v !== void 0) return v;
128
- if (prop === "opacity" || prop === "scale" || prop === "progress") return 1;
129
- if (prop === "rotation") return 0;
150
+ if (prop === "opacity" || prop === "scale" || prop === "progress" || prop === "scaleX" || prop === "scaleY") return 1;
151
+ if (prop === "rotation" || prop === "skewX" || prop === "skewY") return 0;
130
152
  throw new Error(`cannot animate "${prop}" of "${target}": no base value to start from`);
131
153
  };
132
154
  const labelTimes = /* @__PURE__ */ new Map();
@@ -229,16 +251,17 @@
229
251
  const duration = tl.duration ?? DEFAULT_MOTIONPATH_DURATION;
230
252
  const points = tl.points;
231
253
  const closed = tl.closed ?? false;
254
+ const curviness = tl.curviness ?? 1;
232
255
  const autoRotate = tl.autoRotate ?? false;
233
256
  const rotateOffset = tl.rotateOffset ?? 0;
234
257
  let list = motionPaths.get(tl.target);
235
258
  if (!list) motionPaths.set(tl.target, list = []);
236
- list.push({ t0: start, t1: start + duration, points, closed, autoRotate, rotateOffset, ...tl.ease !== void 0 && { ease: tl.ease } });
259
+ list.push({ t0: start, t1: start + duration, points, closed, curviness, autoRotate, rotateOffset, ...tl.ease !== void 0 && { ease: tl.ease } });
237
260
  if (points.length > 0) {
238
- const [ex, ey] = pathPoint(points, closed, 1);
261
+ const [ex, ey] = pathPoint(points, closed, 1, curviness);
239
262
  current.set(key(tl.target, "x"), ex);
240
263
  current.set(key(tl.target, "y"), ey);
241
- if (autoRotate) current.set(key(tl.target, "rotation"), pathTangentAngle(points, closed, 1) + rotateOffset);
264
+ if (autoRotate) current.set(key(tl.target, "rotation"), pathTangentAngle(points, closed, 1, curviness) + rotateOffset);
242
265
  }
243
266
  return start + duration;
244
267
  }
@@ -285,7 +308,7 @@
285
308
  }
286
309
 
287
310
  // ../core/src/validate.ts
288
- var COMMON_PROPS = ["x", "y", "opacity", "rotation", "scale", "anchor"];
311
+ var COMMON_PROPS = ["x", "y", "opacity", "rotation", "scale", "scaleX", "scaleY", "skewX", "skewY", "anchor"];
289
312
  var PROPS_BY_TYPE = {
290
313
  rect: [...COMMON_PROPS, "width", "height", "fill", "stroke", "strokeWidth", "radius"],
291
314
  ellipse: [...COMMON_PROPS, "width", "height", "fill", "stroke", "strokeWidth"],
@@ -450,11 +473,22 @@
450
473
  m[1] * n[4] + m[3] * n[5] + m[5]
451
474
  ];
452
475
  }
453
- function localMatrix(x, y, rotationDeg, scale) {
476
+ function localMatrix(x, y, rotationDeg, scale, scaleX = 1, scaleY = 1, skewXDeg = 0, skewYDeg = 0) {
454
477
  const r = rotationDeg * Math.PI / 180;
455
- const cos = Math.cos(r) * scale;
456
- const sin = Math.sin(r) * scale;
457
- return [cos, sin, -sin, cos, x, y];
478
+ if (scaleX === 1 && scaleY === 1 && skewXDeg === 0 && skewYDeg === 0) {
479
+ const cos = Math.cos(r) * scale;
480
+ const sin = Math.sin(r) * scale;
481
+ return [cos, sin, -sin, cos, x, y];
482
+ }
483
+ const c = Math.cos(r);
484
+ const s = Math.sin(r);
485
+ const tx = Math.tan(skewXDeg * Math.PI / 180);
486
+ const ty = Math.tan(skewYDeg * Math.PI / 180);
487
+ const R = [c, s, -s, c, 0, 0];
488
+ const K = [1, ty, tx, 1, 0, 0];
489
+ const S = [scale * scaleX, 0, 0, scale * scaleY, 0, 0];
490
+ const m = multiply(R, multiply(K, S));
491
+ return [m[0], m[1], m[2], m[3], x, y];
458
492
  }
459
493
  var ANCHOR_FACTORS = {
460
494
  "top-left": [0, 0],
@@ -479,53 +513,54 @@
479
513
  if (Number.isFinite(until) && ramp > 0) envelope = Math.min(envelope, (until - t) / ramp);
480
514
  return Math.max(0, Math.min(1, envelope));
481
515
  }
482
- function evaluate(compiled2, t) {
483
- const ops = [];
484
- const valueAt = (target, prop, fallback) => {
485
- let value = compiled2.initialValues.get(`${target}.${prop}`) ?? fallback;
486
- let segStart = Number.NEGATIVE_INFINITY;
487
- const segs = compiled2.segments.get(`${target}.${prop}`);
488
- if (segs) {
516
+ function sampleProp(compiled2, t, target, prop, fallback) {
517
+ let value = compiled2.initialValues.get(`${target}.${prop}`) ?? fallback;
518
+ let segStart = Number.NEGATIVE_INFINITY;
519
+ const segs = compiled2.segments.get(`${target}.${prop}`);
520
+ if (segs) {
521
+ let active;
522
+ for (const seg of segs) {
523
+ if (seg.t0 <= t) active = seg;
524
+ else break;
525
+ }
526
+ if (active) {
527
+ segStart = active.t0;
528
+ if (t >= active.t1) {
529
+ value = active.to;
530
+ } else {
531
+ const u = resolveEase(active.ease)((t - active.t0) / (active.t1 - active.t0));
532
+ value = lerpValue(active.from, active.to, u);
533
+ }
534
+ }
535
+ }
536
+ if (prop === "x" || prop === "y" || prop === "rotation") {
537
+ const drivers = compiled2.motionPaths.get(target);
538
+ if (drivers) {
489
539
  let active;
490
- for (const seg of segs) {
491
- if (seg.t0 <= t) active = seg;
540
+ for (const d of drivers) {
541
+ if (d.t0 <= t) active = d;
492
542
  else break;
493
543
  }
494
- if (active) {
495
- segStart = active.t0;
496
- if (t >= active.t1) {
497
- value = active.to;
498
- } else {
499
- const u = resolveEase(active.ease)((t - active.t0) / (active.t1 - active.t0));
500
- value = lerpValue(active.from, active.to, u);
501
- }
502
- }
503
- }
504
- if (prop === "x" || prop === "y" || prop === "rotation") {
505
- const drivers = compiled2.motionPaths.get(target);
506
- if (drivers) {
507
- let active;
508
- for (const d of drivers) {
509
- if (d.t0 <= t) active = d;
510
- else break;
511
- }
512
- if (active && active.t0 >= segStart && (prop !== "rotation" || active.autoRotate) && active.points.length > 0) {
513
- const span = active.t1 - active.t0;
514
- const u = span <= 0 ? 1 : resolveEase(active.ease)(Math.max(0, Math.min(1, (t - active.t0) / span)));
515
- if (prop === "x") value = pathPoint(active.points, active.closed, u)[0];
516
- else if (prop === "y") value = pathPoint(active.points, active.closed, u)[1];
517
- else value = pathTangentAngle(active.points, active.closed, u) + active.rotateOffset;
518
- }
544
+ if (active && active.t0 >= segStart && (prop !== "rotation" || active.autoRotate) && active.points.length > 0) {
545
+ const span = active.t1 - active.t0;
546
+ const u = span <= 0 ? 1 : resolveEase(active.ease)(Math.max(0, Math.min(1, (t - active.t0) / span)));
547
+ if (prop === "x") value = pathPoint(active.points, active.closed, u, active.curviness)[0];
548
+ else if (prop === "y") value = pathPoint(active.points, active.closed, u, active.curviness)[1];
549
+ else value = pathTangentAngle(active.points, active.closed, u, active.curviness) + active.rotateOffset;
519
550
  }
520
551
  }
521
- for (const b of compiled2.ir.behaviors ?? []) {
522
- if (b.target === target && b.prop === prop && typeof value === "number") {
523
- const envelope = behaviorEnvelope(b, t);
524
- if (envelope > 0) value = value + envelope * sampleBehavior(b.behavior, t);
525
- }
552
+ }
553
+ for (const b of compiled2.ir.behaviors ?? []) {
554
+ if (b.target === target && b.prop === prop && typeof value === "number") {
555
+ const envelope = behaviorEnvelope(b, t);
556
+ if (envelope > 0) value = value + envelope * sampleBehavior(b.behavior, t);
526
557
  }
527
- return value;
528
- };
558
+ }
559
+ return value;
560
+ }
561
+ function evaluate(compiled2, t) {
562
+ const ops = [];
563
+ const valueAt = (target, prop, fallback) => sampleProp(compiled2, t, target, prop, fallback);
529
564
  const num = (target, prop, fallback) => {
530
565
  const v = valueAt(target, prop, fallback);
531
566
  return typeof v === "number" ? v : fallback;
@@ -538,8 +573,9 @@
538
573
  const v = valueAt(target, prop, base ?? "");
539
574
  return v === "" && base === void 0 ? void 0 : String(v);
540
575
  };
541
- const walk = (node, parent, parentOpacity) => {
576
+ const walk = (node, parent, parentOpacity, clips) => {
542
577
  const id = node.id;
578
+ const clipSpread = clips.length > 0 ? { clips } : void 0;
543
579
  if (node.type === "line") {
544
580
  const opacity2 = parentOpacity * num(id, "opacity", node.props.opacity ?? 1);
545
581
  if (opacity2 <= 0) return;
@@ -556,7 +592,8 @@
556
592
  x2: x1 + (num(id, "x2", node.props.x2) - x1) * progress,
557
593
  y2: y1 + (num(id, "y2", node.props.y2) - y1) * progress,
558
594
  stroke: str(id, "stroke", node.props.stroke),
559
- strokeWidth: num(id, "strokeWidth", node.props.strokeWidth ?? 1)
595
+ strokeWidth: num(id, "strokeWidth", node.props.strokeWidth ?? 1),
596
+ ...clipSpread
560
597
  });
561
598
  return;
562
599
  }
@@ -568,13 +605,19 @@
568
605
  num(id, "x", node.props.x),
569
606
  num(id, "y", node.props.y),
570
607
  num(id, "rotation", node.props.rotation ?? 0),
571
- num(id, "scale", node.props.scale ?? 1)
608
+ num(id, "scale", node.props.scale ?? 1),
609
+ num(id, "scaleX", node.props.scaleX ?? 1),
610
+ num(id, "scaleY", node.props.scaleY ?? 1),
611
+ num(id, "skewX", node.props.skewX ?? 0),
612
+ num(id, "skewY", node.props.skewY ?? 0)
572
613
  )
573
614
  );
574
615
  switch (node.type) {
575
- case "group":
576
- for (const child of node.children) walk(child, matrix, opacity);
616
+ case "group": {
617
+ const childClips = node.props.clip ? [...clips, { transform: matrix, shape: node.props.clip }] : clips;
618
+ for (const child of node.children) walk(child, matrix, opacity, childClips);
577
619
  return;
620
+ }
578
621
  case "rect":
579
622
  case "ellipse": {
580
623
  const width = num(id, "width", node.props.width);
@@ -594,7 +637,8 @@
594
637
  offsetY: -height * ay,
595
638
  ...fill !== void 0 && { fill },
596
639
  ...stroke !== void 0 && { stroke, strokeWidth },
597
- ...node.type === "rect" && { radius: num(id, "radius", node.props.radius ?? 0) }
640
+ ...node.type === "rect" && { radius: num(id, "radius", node.props.radius ?? 0) },
641
+ ...clipSpread
598
642
  });
599
643
  return;
600
644
  }
@@ -611,7 +655,8 @@
611
655
  width,
612
656
  height,
613
657
  offsetX: -width * ax,
614
- offsetY: -height * ay
658
+ offsetY: -height * ay,
659
+ ...clipSpread
615
660
  });
616
661
  return;
617
662
  }
@@ -628,7 +673,8 @@
628
673
  d: str(id, "d", node.props.d),
629
674
  progress: Math.max(0, Math.min(1, num(id, "progress", node.props.progress ?? 1))),
630
675
  ...fill !== void 0 && { fill },
631
- ...stroke !== void 0 && { stroke, strokeWidth: num(id, "strokeWidth", node.props.strokeWidth ?? 1) }
676
+ ...stroke !== void 0 && { stroke, strokeWidth: num(id, "strokeWidth", node.props.strokeWidth ?? 1) },
677
+ ...clipSpread
632
678
  });
633
679
  return;
634
680
  }
@@ -651,13 +697,14 @@
651
697
  fill: str(id, "fill", node.props.fill ?? "#ffffff"),
652
698
  letterSpacing: num(id, "letterSpacing", node.props.letterSpacing ?? 0),
653
699
  align: TEXT_ALIGN[ax] ?? "left",
654
- baseline: TEXT_BASELINE[ay] ?? "top"
700
+ baseline: TEXT_BASELINE[ay] ?? "top",
701
+ ...clipSpread
655
702
  });
656
703
  return;
657
704
  }
658
705
  }
659
706
  };
660
- for (const node of compiled2.ir.nodes) walk(node, IDENTITY, 1);
707
+ for (const node of compiled2.ir.nodes) walk(node, IDENTITY, 1, []);
661
708
  return ops;
662
709
  }
663
710
 
@@ -675,6 +722,21 @@
675
722
  function drawDisplayList(ctx2, ops, images2) {
676
723
  for (const op of ops) {
677
724
  ctx2.save();
725
+ if (op.clips) {
726
+ for (const clip of op.clips) {
727
+ ctx2.setTransform(...clip.transform);
728
+ ctx2.beginPath();
729
+ const { shape } = clip;
730
+ if (shape.kind === "ellipse") {
731
+ ctx2.ellipse(shape.x + shape.width / 2, shape.y + shape.height / 2, Math.abs(shape.width / 2), Math.abs(shape.height / 2), 0, 0, Math.PI * 2);
732
+ } else if (shape.radius && shape.radius > 0) {
733
+ ctx2.roundRect(shape.x, shape.y, shape.width, shape.height, shape.radius);
734
+ } else {
735
+ ctx2.rect(shape.x, shape.y, shape.width, shape.height);
736
+ }
737
+ ctx2.clip();
738
+ }
739
+ }
678
740
  ctx2.setTransform(...op.transform);
679
741
  ctx2.globalAlpha = Math.max(0, Math.min(1, op.opacity));
680
742
  switch (op.type) {