@vosjs/studio-core 0.42.2 → 0.42.4

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 CHANGED
@@ -3801,6 +3801,16 @@ interface TrackOptions {
3801
3801
  * entrance's last pose to the span's end in one straight line.
3802
3802
  */
3803
3803
  notBefore?: number;
3804
+ /**
3805
+ * The transition windows, in output seconds: the camera rests through
3806
+ * one (`restSpansThroughTransitions`), so no connected pan runs across
3807
+ * it. A span that ends at a boundary ramps out on its own and the span
3808
+ * after the window ramps in on its own, as two spans a wide gap apart.
3809
+ */
3810
+ rests?: readonly {
3811
+ t: number;
3812
+ d: number;
3813
+ }[];
3804
3814
  }
3805
3815
  /**
3806
3816
  * Expand the doc's source-anchored zoom spans into a standard @vosjs/timeline
package/dist/index.js CHANGED
@@ -6449,17 +6449,25 @@ function connectedWindow(o) {
6449
6449
  );
6450
6450
  return { start, land };
6451
6451
  }
6452
- function withEntrance(head, build) {
6453
- return prependEntrance(build({ notBefore: head.at(-1)?.t }), head);
6452
+ function withEntrance(head, build, rests) {
6453
+ return prependEntrance(build({ notBefore: head.at(-1)?.t, rests }), head);
6454
+ }
6455
+ function restsBetween(rests, tOut, nextIn) {
6456
+ return (rests ?? []).some(
6457
+ (w) => w.t > 0 && w.d > 0 && w.t < nextIn && w.t + w.d > tOut
6458
+ );
6454
6459
  }
6455
6460
  var spillLimit = (tIn, tOut) => tIn + (tOut - tIn) / 2;
6461
+ function spansInOutputOrder(spans, segments) {
6462
+ return spans.flatMap((z) => {
6463
+ const ext = spanOutputExtent(segments, z.in, z.out, z.media);
6464
+ return ext ? [{ z, tIn: ext.start, tOut: ext.end }] : [];
6465
+ }).sort((a, b) => a.tIn - b.tIn || a.tOut - b.tOut);
6466
+ }
6456
6467
  function zoomTrackFromDoc(zoom, segments, style = ZOOM_STYLES[DEFAULT_ZOOM_STYLE], opts = {}) {
6457
6468
  const notBefore = opts.notBefore ?? -Infinity;
6458
6469
  const panEase = style.panEase;
6459
- const mapped = [...zoom].sort((a, b) => a.in - b.in).flatMap((z) => {
6460
- const ext = spanOutputExtent(segments, z.in, z.out, z.media);
6461
- return ext ? [{ z, tIn: ext.start, tOut: ext.end }] : [];
6462
- });
6470
+ const mapped = spansInOutputOrder(zoom, segments);
6463
6471
  const { keyframes, push: push2 } = trackEmitter();
6464
6472
  const placedAt = (z) => z.screen && z.focusMode !== "auto" ? z.screen : null;
6465
6473
  const placed = mapped.some(({ z }) => placedAt(z) !== null);
@@ -6490,7 +6498,7 @@ function zoomTrackFromDoc(zoom, segments, style = ZOOM_STYLES[DEFAULT_ZOOM_STYLE
6490
6498
  }
6491
6499
  const arrived = keyframes.at(-1)?.t ?? tIn;
6492
6500
  const next = mapped.at(i + 1);
6493
- const pan = next && next.tIn - tOut <= style.chainGap ? connectedWindow({
6501
+ const pan = next && next.tIn - tOut <= style.chainGap && !restsBetween(opts.rests, tOut, next.tIn) ? connectedWindow({
6494
6502
  arrived,
6495
6503
  tOut,
6496
6504
  landBy: next.tIn + style.rampInOverlap * transitionMult(next.z.transition),
@@ -6567,10 +6575,7 @@ function tiltTrackFromDoc(tilt, segments, motion = {}, opts = {}) {
6567
6575
  const panDur = motion.pan ?? TILT_PAN;
6568
6576
  const panEase = TILT_PAN_EASE;
6569
6577
  const rest = [0, 0];
6570
- const mapped = [...tilt].sort((a, b) => a.in - b.in).flatMap((z) => {
6571
- const ext = spanOutputExtent(segments, z.in, z.out, z.media);
6572
- return ext ? [{ z, tIn: ext.start, tOut: ext.end }] : [];
6573
- });
6578
+ const mapped = spansInOutputOrder(tilt, segments);
6574
6579
  const { keyframes, push: push2 } = trackEmitter();
6575
6580
  let chained = false;
6576
6581
  for (let i = 0; i < mapped.length; i++) {
@@ -6589,7 +6594,7 @@ function tiltTrackFromDoc(tilt, segments, motion = {}, opts = {}) {
6589
6594
  }
6590
6595
  const arrived = keyframes.at(-1)?.t ?? tIn;
6591
6596
  const next = mapped.at(i + 1);
6592
- const swing = next && next.tIn - tOut <= chainGap ? connectedWindow({
6597
+ const swing = next && next.tIn - tOut <= chainGap && !restsBetween(opts.rests, tOut, next.tIn) ? connectedWindow({
6593
6598
  arrived,
6594
6599
  tOut,
6595
6600
  landBy: next.tIn,
@@ -6624,10 +6629,7 @@ function camTrackFromDoc(cam, spans, segments, W, H = 1080) {
6624
6629
  z.size != null ? clampCamSize(z.size) : rest[2]
6625
6630
  ];
6626
6631
  const panEase = CAM_PAN_EASE;
6627
- const mapped = [...spans].sort((a, b) => a.in - b.in).flatMap((z) => {
6628
- const ext = spanOutputExtent(segments, z.in, z.out, z.media);
6629
- return ext ? [{ z, tIn: ext.start, tOut: ext.end }] : [];
6630
- });
6632
+ const mapped = spansInOutputOrder(spans, segments);
6631
6633
  const { keyframes, push: push2 } = trackEmitter();
6632
6634
  let chained = false;
6633
6635
  for (let i = 0; i < mapped.length; i++) {
@@ -6957,7 +6959,9 @@ var SETUP = `async (ctx) => {
6957
6959
  // exactly as it was; preview/scrub never sets the flag.
6958
6960
  const makeWcProvider = async (src) => {
6959
6961
  if (!window.VideoDecoder) return null
6960
- const MB = await import('https://esm.sh/mediabunny@1.55.7?target=es2022')
6962
+ // The page says where mediabunny loads from (the engine template's
6963
+ // window.__vos__.modules, a mirror or esm.sh); esm.sh when it says nothing.
6964
+ const MB = await import((window.__vos__ && window.__vos__.modules && window.__vos__.modules.mediabunny) || 'https://esm.sh/mediabunny@1.55.7?target=es2022')
6961
6965
  const wcBlob = ns.videoBlobs && ns.videoBlobs.get(src)
6962
6966
  const input = new MB.Input({
6963
6967
  formats: MB.ALL_FORMATS,
@@ -8858,7 +8862,8 @@ function lowerToComposition(input) {
8858
8862
  );
8859
8863
  const zoomTrack = withEntrance(
8860
8864
  entranceZoomKeyframes(cardEnter(doc.frame)),
8861
- (opts) => zoomTrackFromDoc(zoomSpans, rated, zoomStyle, opts)
8865
+ (opts) => zoomTrackFromDoc(zoomSpans, rated, zoomStyle, opts),
8866
+ transitions
8862
8867
  );
8863
8868
  const pins = resolvePins(doc, layout, camera, zoomTrack);
8864
8869
  const pinsData = pinsDataOf(doc, pins);
@@ -8958,7 +8963,7 @@ function lowerToComposition(input) {
8958
8963
  TILT_SPAN_MIN
8959
8964
  ) : [];
8960
8965
  const spans = tilts.length ? (opts) => tiltTrackFromDoc(tilts, rated, zoomStyle.tilt, opts) : () => void 0;
8961
- const track = withEntrance(head, spans);
8966
+ const track = withEntrance(head, spans, transitions);
8962
8967
  return track ? { tiltTrack: track } : {};
8963
8968
  })(),
8964
8969
  // The card's pose through its enter and its exit: [scale, dy, opacity]
@@ -9061,7 +9066,8 @@ function docZoomTrack(input) {
9061
9066
  );
9062
9067
  return withEntrance(
9063
9068
  entranceZoomKeyframes(cardEnter(doc.frame)),
9064
- (opts) => zoomTrackFromDoc(spans, rated, zoomStyle, opts)
9069
+ (opts) => zoomTrackFromDoc(spans, rated, zoomStyle, opts),
9070
+ transitions
9065
9071
  );
9066
9072
  }
9067
9073
  function resolvePins(doc, layout, camera, zoomTrack) {