@remotion/transitions 4.0.489 → 4.0.491

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.
@@ -1,17 +1,19 @@
1
1
  import type { FC, PropsWithChildren } from 'react';
2
+ import React from 'react';
2
3
  import type { AbsoluteFillLayout, LayoutAndStyle, SequencePropsWithoutDuration } from 'remotion';
3
4
  import { NoReactInternals } from 'remotion/no-react';
4
5
  import type { TransitionSeriesOverlayProps, TransitionSeriesTransitionProps } from './types.js';
6
+ type TransitionSeriesTransitionComponent = <PresentationProps extends Record<string, unknown>>(props: TransitionSeriesTransitionProps<PresentationProps>) => React.ReactNode;
5
7
  type LayoutBasedProps = true extends typeof NoReactInternals.ENABLE_V5_BREAKING_CHANGES ? AbsoluteFillLayout : LayoutAndStyle;
6
8
  type SeriesSequenceProps = PropsWithChildren<{
7
9
  readonly durationInFrames: number;
8
10
  readonly offset?: number;
9
11
  readonly className?: string;
10
- } & LayoutBasedProps & Pick<SequencePropsWithoutDuration, 'name' | 'showInTimeline' | 'freeze'>>;
12
+ } & LayoutBasedProps & Pick<SequencePropsWithoutDuration, 'name' | 'showInTimeline' | 'freeze' | 'hidden'>>;
11
13
  export type DrawFunction = (prevImage: ElementImage | null, nextImage: ElementImage | null, progress: number) => void;
12
14
  declare const TransitionSeries: FC<SequencePropsWithoutDuration> & {
13
- Sequence: ({ children }: SeriesSequenceProps) => import("react/jsx-runtime").JSX.Element;
14
- Transition: <PresentationProps extends Record<string, unknown>>(_props: TransitionSeriesTransitionProps<PresentationProps>) => null;
15
+ Sequence: FC<SeriesSequenceProps>;
16
+ Transition: TransitionSeriesTransitionComponent;
15
17
  Overlay: FC<TransitionSeriesOverlayProps>;
16
18
  };
17
19
  export { TransitionSeries };
@@ -1,8 +1,41 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.TransitionSeries = void 0;
4
37
  const jsx_runtime_1 = require("react/jsx-runtime");
5
- const react_1 = require("react");
38
+ const react_1 = __importStar(require("react"));
6
39
  const remotion_1 = require("remotion");
7
40
  const no_react_1 = require("remotion/no-react");
8
41
  const context_js_1 = require("./context.js");
@@ -10,16 +43,61 @@ const flatten_children_js_1 = require("./flatten-children.js");
10
43
  const slide_js_1 = require("./presentations/slide.js");
11
44
  const validate_js_1 = require("./validate.js");
12
45
  const { SequenceWithoutSchema } = remotion_1.Internals;
13
- const TransitionSeriesTransition = function (_props) {
46
+ const TransitionSeriesTransitionInner = ({ stack = null, _remotionInternalRender = null, ...props }) => {
47
+ if (_remotionInternalRender) {
48
+ return _remotionInternalRender({ ...props, stack });
49
+ }
14
50
  return null;
15
51
  };
16
- const SeriesOverlay = () => {
52
+ const transitionSeriesTransitionSchema = {};
53
+ const TransitionSeriesTransition = remotion_1.Interactive.withSchema({
54
+ Component: TransitionSeriesTransitionInner,
55
+ componentName: '<TransitionSeries.Transition>',
56
+ componentIdentity: 'dev.remotion.transitions.TransitionSeries.Transition',
57
+ schema: transitionSeriesTransitionSchema,
58
+ supportsEffects: false,
59
+ });
60
+ const SeriesOverlayInner = ({ stack = null, _remotionInternalRender = null, ...props }) => {
61
+ if (_remotionInternalRender) {
62
+ return _remotionInternalRender({ ...props, stack });
63
+ }
17
64
  return null;
18
65
  };
19
- const SeriesSequence = ({ children }) => {
66
+ const transitionSeriesOverlaySchema = {};
67
+ const SeriesOverlay = remotion_1.Interactive.withSchema({
68
+ Component: SeriesOverlayInner,
69
+ componentName: '<TransitionSeries.Overlay>',
70
+ componentIdentity: 'dev.remotion.transitions.TransitionSeries.Overlay',
71
+ schema: transitionSeriesOverlaySchema,
72
+ supportsEffects: false,
73
+ });
74
+ const transitionSeriesSequenceSchema = {
75
+ durationInFrames: remotion_1.Internals.durationInFramesField,
76
+ name: remotion_1.Internals.sequenceSchema.name,
77
+ hidden: remotion_1.Internals.sequenceSchema.hidden,
78
+ showInTimeline: remotion_1.Internals.sequenceSchema.showInTimeline,
79
+ freeze: remotion_1.Internals.freezeField,
80
+ layout: remotion_1.Internals.sequenceSchema.layout,
81
+ };
82
+ const SeriesSequenceInner = ({ offset = 0, className = '', stack = null, _remotionInternalRender = null, ...props }) => {
83
+ if (_remotionInternalRender) {
84
+ return _remotionInternalRender({
85
+ ...props,
86
+ offset,
87
+ className: className || undefined,
88
+ stack,
89
+ });
90
+ }
20
91
  // eslint-disable-next-line react/jsx-no-useless-fragment
21
- return jsx_runtime_1.jsx(jsx_runtime_1.Fragment, { children: children });
92
+ return jsx_runtime_1.jsx(jsx_runtime_1.Fragment, { children: props.children });
22
93
  };
94
+ const SeriesSequence = remotion_1.Interactive.withSchema({
95
+ Component: SeriesSequenceInner,
96
+ componentName: '<TransitionSeries.Sequence>',
97
+ componentIdentity: 'dev.remotion.transitions.TransitionSeries.Sequence',
98
+ schema: transitionSeriesSequenceSchema,
99
+ supportsEffects: false,
100
+ });
23
101
  const transitionSeriesSchema = {
24
102
  name: remotion_1.Internals.sequenceSchema.name,
25
103
  hidden: remotion_1.Internals.sequenceSchema.hidden,
@@ -67,20 +145,23 @@ const TransitionSeriesChildren = ({ children, }) => {
67
145
  drawIfSynced(index);
68
146
  }, [drawIfSynced]);
69
147
  const childrenValue = (0, react_1.useMemo)(() => {
70
- let transitionOffsets = 0;
71
- let startFrame = 0;
72
- // Collect overlay render info to emit after the main loop
73
- const overlayRenders = [];
74
- // Track sequence durations for overlay validation
75
- const sequenceDurations = [];
76
- let pendingOverlayValidation = false;
77
- const mainChildren = react_1.Children.map(flattedChildren, (child, i) => {
78
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
148
+ const renderChildren = (state) => {
149
+ const { index: i, transitionOffsets, startFrame, overlayRenders, sequenceDurations, pendingOverlayValidation, } = state;
150
+ if (i === flattedChildren.length) {
151
+ return overlayRenders.map((info) => {
152
+ var _a, _b;
153
+ return (jsx_runtime_1.jsx(SequenceWithoutSchema, { from: Math.round(info.overlayFrom), durationInFrames: info.durationInFrames, name: "<TS.Overlay>", _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/transitions/transitionseries", _remotionInternalStack: (_a = info.stack) !== null && _a !== void 0 ? _a : undefined, controls: (_b = info.controls) !== null && _b !== void 0 ? _b : undefined, layout: "absolute-fill", children: info.children }, `overlay-${info.index}`));
154
+ });
155
+ }
156
+ const child = flattedChildren[i];
79
157
  const current = child;
158
+ const renderNext = (overrides = {}) => {
159
+ return renderChildren({ ...state, ...overrides, index: i + 1 });
160
+ };
80
161
  if (typeof current === 'string') {
81
162
  // Don't throw if it's just some accidential whitespace
82
163
  if (current.trim() === '') {
83
- return null;
164
+ return renderNext();
84
165
  }
85
166
  throw new TypeError(`The <TransitionSeries /> component only accepts a list of <TransitionSeries.Sequence /> components as its children, but you passed a string "${current}"`);
86
167
  }
@@ -108,49 +189,58 @@ const TransitionSeriesChildren = ({ children, }) => {
108
189
  if (nextIsTransition) {
109
190
  throw new TypeError(`A <TransitionSeries.Overlay /> component must not be followed by a <TransitionSeries.Transition /> component (nth children = ${i} and ${i + 1})`);
110
191
  }
111
- const overlayProps = current.props;
112
- (0, validate_js_1.validateDurationInFrames)(overlayProps.durationInFrames, {
113
- component: `of a <TransitionSeries.Overlay /> component`,
114
- allowFloats: false,
115
- });
116
- const overlayOffset = (_a = overlayProps.offset) !== null && _a !== void 0 ? _a : 0;
117
- if (Number.isNaN(overlayOffset)) {
118
- throw new TypeError(`The "offset" property of a <TransitionSeries.Overlay /> must not be NaN, but got NaN.`);
119
- }
120
- if (!Number.isFinite(overlayOffset)) {
121
- throw new TypeError(`The "offset" property of a <TransitionSeries.Overlay /> must be finite, but got ${overlayOffset}.`);
122
- }
123
- if (overlayOffset % 1 !== 0) {
124
- throw new TypeError(`The "offset" property of a <TransitionSeries.Overlay /> must be an integer, but got ${overlayOffset}.`);
125
- }
126
- // Find the previous sequence (the cut point is at startFrame + transitionOffsets)
127
- const cutPoint = startFrame + transitionOffsets;
128
- const halfDuration = overlayProps.durationInFrames / 2;
129
- const overlayFrom = cutPoint - halfDuration + overlayOffset;
130
- if (overlayFrom < 0) {
131
- throw new TypeError(`A <TransitionSeries.Overlay /> extends before frame 0. The overlay starts at frame ${overlayFrom}. Reduce the duration or adjust the offset.`);
132
- }
133
- // Validate: overlay must not exceed the previous sequence duration
134
- const prevSeqIdx = sequenceDurations.length - 1;
135
- if (prevSeqIdx >= 0) {
136
- const overlayStartInPrev = halfDuration - overlayOffset;
137
- if (overlayStartInPrev > sequenceDurations[prevSeqIdx]) {
138
- throw new TypeError(`A <TransitionSeries.Overlay /> extends beyond the previous sequence. The overlay needs ${overlayStartInPrev} frames before the cut, but the previous sequence is only ${sequenceDurations[prevSeqIdx]} frames long.`);
139
- }
140
- }
141
- // We'll validate the next sequence side after we process it
142
- pendingOverlayValidation = true;
143
- // Store overlay info for deferred rendering
144
- overlayRenders.push({
145
- cutPoint,
146
- overlayFrom,
147
- durationInFrames: overlayProps.durationInFrames,
148
- overlayOffset,
149
- halfDuration,
150
- children: overlayProps.children,
151
- index: i,
192
+ const castedOverlay = current;
193
+ return react_1.default.cloneElement(castedOverlay, {
194
+ _remotionInternalRender: (overlayProps) => {
195
+ var _a;
196
+ (0, validate_js_1.validateDurationInFrames)(overlayProps.durationInFrames, {
197
+ component: `of a <TransitionSeries.Overlay /> component`,
198
+ allowFloats: false,
199
+ });
200
+ const overlayOffset = (_a = overlayProps.offset) !== null && _a !== void 0 ? _a : 0;
201
+ if (Number.isNaN(overlayOffset)) {
202
+ throw new TypeError(`The "offset" property of a <TransitionSeries.Overlay /> must not be NaN, but got NaN.`);
203
+ }
204
+ if (!Number.isFinite(overlayOffset)) {
205
+ throw new TypeError(`The "offset" property of a <TransitionSeries.Overlay /> must be finite, but got ${overlayOffset}.`);
206
+ }
207
+ if (overlayOffset % 1 !== 0) {
208
+ throw new TypeError(`The "offset" property of a <TransitionSeries.Overlay /> must be an integer, but got ${overlayOffset}.`);
209
+ }
210
+ // Find the previous sequence (the cut point is at startFrame + transitionOffsets)
211
+ const cutPoint = startFrame + transitionOffsets;
212
+ const halfDuration = overlayProps.durationInFrames / 2;
213
+ const overlayFrom = cutPoint - halfDuration + overlayOffset;
214
+ if (overlayFrom < 0) {
215
+ throw new TypeError(`A <TransitionSeries.Overlay /> extends before frame 0. The overlay starts at frame ${overlayFrom}. Reduce the duration or adjust the offset.`);
216
+ }
217
+ // Validate: overlay must not exceed the previous sequence duration
218
+ const prevSeqIdx = sequenceDurations.length - 1;
219
+ if (prevSeqIdx >= 0) {
220
+ const overlayStartInPrev = halfDuration - overlayOffset;
221
+ if (overlayStartInPrev > sequenceDurations[prevSeqIdx]) {
222
+ throw new TypeError(`A <TransitionSeries.Overlay /> extends beyond the previous sequence. The overlay needs ${overlayStartInPrev} frames before the cut, but the previous sequence is only ${sequenceDurations[prevSeqIdx]} frames long.`);
223
+ }
224
+ }
225
+ // Store overlay info for deferred rendering and validate the other
226
+ // side once the next sequence has resolved its interactive props.
227
+ const overlayRender = {
228
+ cutPoint,
229
+ overlayFrom,
230
+ durationInFrames: overlayProps.durationInFrames,
231
+ overlayOffset,
232
+ halfDuration,
233
+ children: overlayProps.children,
234
+ index: i,
235
+ controls: overlayProps.controls,
236
+ stack: overlayProps.stack,
237
+ };
238
+ return renderNext({
239
+ overlayRenders: [...overlayRenders, overlayRender],
240
+ pendingOverlayValidation: true,
241
+ });
242
+ },
152
243
  });
153
- return null;
154
244
  }
155
245
  if (current.type === TransitionSeriesTransition) {
156
246
  if (prevIsTransition) {
@@ -159,7 +249,15 @@ const TransitionSeriesChildren = ({ children, }) => {
159
249
  if (prevIsOverlay) {
160
250
  throw new TypeError(`A <TransitionSeries.Overlay /> component must not be followed by a <TransitionSeries.Transition /> component (nth children = ${i - 1} and ${i})`);
161
251
  }
162
- return null;
252
+ const castedTransition = current;
253
+ return react_1.default.cloneElement(castedTransition, {
254
+ _remotionInternalRender: (transitionProps) => {
255
+ var _a, _b;
256
+ const transitionDuration = transitionProps.timing.getDurationInFrames({ fps });
257
+ const transitionFrom = startFrame + transitionOffsets - transitionDuration;
258
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [transitionDuration > 0 ? (jsx_runtime_1.jsx(SequenceWithoutSchema, { from: transitionFrom, durationInFrames: transitionDuration, name: "<TS.Transition>", _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/transitions/transitionseries", _remotionInternalStack: (_a = transitionProps.stack) !== null && _a !== void 0 ? _a : undefined, controls: (_b = transitionProps.controls) !== null && _b !== void 0 ? _b : undefined, layout: "none" })) : null, renderNext()] }));
259
+ },
260
+ });
163
261
  }
164
262
  if (current.type !== SeriesSequence) {
165
263
  throw new TypeError(`The <TransitionSeries /> component only accepts a list of <TransitionSeries.Sequence />, <TransitionSeries.Transition />, and <TransitionSeries.Overlay /> components as its children, but got ${current} instead`);
@@ -175,127 +273,144 @@ const TransitionSeriesChildren = ({ children, }) => {
175
273
  ? nextPrev
176
274
  : null;
177
275
  const castedChildAgain = current;
178
- const debugInfo = `index = ${i}, duration = ${castedChildAgain.props.durationInFrames}`;
179
- const durationInFramesProp = castedChildAgain.props.durationInFrames;
180
- const { durationInFrames, children: _children, from: _from, ...passedProps } = castedChildAgain.props;
181
- (0, validate_js_1.validateDurationInFrames)(durationInFramesProp, {
182
- component: `of a <TransitionSeries.Sequence /> component`,
183
- allowFloats: true,
184
- });
185
- const offset = (_b = castedChildAgain.props.offset) !== null && _b !== void 0 ? _b : 0;
186
- if (Number.isNaN(offset)) {
187
- throw new TypeError(`The "offset" property of a <TransitionSeries.Sequence /> must not be NaN, but got NaN (${debugInfo}).`);
188
- }
189
- if (!Number.isFinite(offset)) {
190
- throw new TypeError(`The "offset" property of a <TransitionSeries.Sequence /> must be finite, but got ${offset} (${debugInfo}).`);
191
- }
192
- if (offset % 1 !== 0) {
193
- throw new TypeError(`The "offset" property of a <TransitionSeries.Sequence /> must be finite, but got ${offset} (${debugInfo}).`);
194
- }
195
- const currentStartFrame = startFrame + offset;
196
- let duration = 0;
197
- if (prev) {
198
- duration = prev.props.timing.getDurationInFrames({
199
- fps,
200
- });
201
- transitionOffsets -= duration;
202
- }
203
- let actualStartFrame = currentStartFrame + transitionOffsets;
204
- startFrame += durationInFramesProp + offset;
205
- // Handle the case where the first item is a transition
206
- if (actualStartFrame < 0) {
207
- startFrame -= actualStartFrame;
208
- actualStartFrame = 0;
209
- }
210
- // Track sequence durations for overlay validation
211
- sequenceDurations.push(durationInFramesProp);
212
- // Validate: check if a preceding overlay extends beyond this sequence
213
- if (pendingOverlayValidation) {
214
- pendingOverlayValidation = false;
215
- const lastOverlay = overlayRenders[overlayRenders.length - 1];
216
- const framesAfterCut = lastOverlay.halfDuration + lastOverlay.overlayOffset;
217
- if (framesAfterCut > durationInFramesProp) {
218
- throw new TypeError(`A <TransitionSeries.Overlay /> extends beyond the next sequence. The overlay needs ${framesAfterCut} frames after the cut, but the next sequence is only ${durationInFramesProp} frames long.`);
219
- }
220
- }
221
- const nextProgress = next
222
- ? next.props.timing.getProgress({
223
- frame: frame -
224
- actualStartFrame -
225
- durationInFrames +
226
- next.props.timing.getDurationInFrames({ fps }),
227
- fps,
228
- })
229
- : null;
230
- const prevProgress = prev
231
- ? prev.props.timing.getProgress({
232
- frame: frame - actualStartFrame,
233
- fps,
234
- })
235
- : null;
236
- if (next &&
237
- durationInFramesProp < next.props.timing.getDurationInFrames({ fps })) {
238
- throw new Error(`The duration of a <TransitionSeries.Sequence /> must not be shorter than the duration of the next <TransitionSeries.Transition />. The transition is ${next.props.timing.getDurationInFrames({ fps })} frames long, but the sequence is only ${durationInFramesProp} frames long (${debugInfo})`);
239
- }
240
- if (prev &&
241
- durationInFramesProp < prev.props.timing.getDurationInFrames({ fps })) {
242
- throw new Error(`The duration of a <TransitionSeries.Sequence /> must not be shorter than the duration of the previous <TransitionSeries.Transition />. The transition is ${prev.props.timing.getDurationInFrames({ fps })} frames long, but the sequence is only ${durationInFramesProp} frames long (${debugInfo})`);
243
- }
244
- if (next && prev && nextProgress !== null && prevProgress !== null) {
245
- const nextPresentation = (_c = next.props.presentation) !== null && _c !== void 0 ? _c : (0, slide_js_1.slide)();
246
- const prevPresentation = (_d = prev.props.presentation) !== null && _d !== void 0 ? _d : (0, slide_js_1.slide)();
247
- const UppercaseNextPresentation = nextPresentation.component;
248
- const UppercasePrevPresentation = prevPresentation.component;
249
- return (jsx_runtime_1.jsx(SequenceWithoutSchema
250
- // eslint-disable-next-line react/no-array-index-key
251
- , { from: actualStartFrame, durationInFrames: durationInFramesProp, ...passedProps, name: passedProps.name || '<TS.Sequence>', _remotionInternalDocumentationLink: passedProps.name
252
- ? undefined
253
- : 'https://www.remotion.dev/docs/transitions/transitionseries', children: jsx_runtime_1.jsx(UppercaseNextPresentation, { passedProps: (_e = nextPresentation.props) !== null && _e !== void 0 ? _e : {}, presentationDirection: "exiting", presentationProgress: nextProgress, presentationDurationInFrames: next.props.timing.getDurationInFrames({ fps }), onElementImage: () => {
254
- throw new Error('Should not call when exiting');
255
- }, onUnmount: () => {
256
- throw new Error('Should not call when exiting');
257
- }, bothEnteringAndExiting: true, children: jsx_runtime_1.jsx(context_js_1.WrapInExitingProgressContext, { presentationProgress: nextProgress, children: jsx_runtime_1.jsx(UppercasePrevPresentation, { passedProps: (_f = prevPresentation.props) !== null && _f !== void 0 ? _f : {}, presentationDirection: "entering", presentationProgress: prevProgress, presentationDurationInFrames: prev.props.timing.getDurationInFrames({ fps }), onElementImage: (elementImage, draw) => {
258
- onPrevElementImage(elementImage, nextProgress, draw, i + 1);
259
- onNextElementImage(elementImage, prevProgress, draw, i - 1);
276
+ return react_1.default.cloneElement(castedChildAgain, {
277
+ _remotionInternalRender: (resolvedProps) => {
278
+ var _a, _b, _c, _d, _e, _f, _g, _h;
279
+ const durationInFramesProp = resolvedProps.durationInFrames;
280
+ const debugInfo = `index = ${i}, duration = ${durationInFramesProp}`;
281
+ const { durationInFrames, children: sequenceChildren, offset: offsetProp, controls, stack, from: _from, ...passedProps } = resolvedProps;
282
+ (0, validate_js_1.validateDurationInFrames)(durationInFramesProp, {
283
+ component: `of a <TransitionSeries.Sequence /> component`,
284
+ allowFloats: true,
285
+ });
286
+ const offset = offsetProp !== null && offsetProp !== void 0 ? offsetProp : 0;
287
+ if (Number.isNaN(offset)) {
288
+ throw new TypeError(`The "offset" property of a <TransitionSeries.Sequence /> must not be NaN, but got NaN (${debugInfo}).`);
289
+ }
290
+ if (!Number.isFinite(offset)) {
291
+ throw new TypeError(`The "offset" property of a <TransitionSeries.Sequence /> must be finite, but got ${offset} (${debugInfo}).`);
292
+ }
293
+ if (offset % 1 !== 0) {
294
+ throw new TypeError(`The "offset" property of a <TransitionSeries.Sequence /> must be finite, but got ${offset} (${debugInfo}).`);
295
+ }
296
+ let resolvedTransitionOffsets = transitionOffsets;
297
+ let resolvedStartFrame = startFrame;
298
+ let resolvedPendingOverlayValidation = pendingOverlayValidation;
299
+ const currentStartFrame = resolvedStartFrame + offset;
300
+ let duration = 0;
301
+ if (prev) {
302
+ duration = prev.props.timing.getDurationInFrames({
303
+ fps,
304
+ });
305
+ resolvedTransitionOffsets -= duration;
306
+ }
307
+ let actualStartFrame = currentStartFrame + resolvedTransitionOffsets;
308
+ resolvedStartFrame += durationInFramesProp + offset;
309
+ // Handle the case where the first item is a transition
310
+ if (actualStartFrame < 0) {
311
+ resolvedStartFrame -= actualStartFrame;
312
+ actualStartFrame = 0;
313
+ }
314
+ // Track resolved durations so later sequences and overlay validation use
315
+ // the live Studio override instead of the original JSX value.
316
+ const nextSequenceDurations = [
317
+ ...sequenceDurations,
318
+ durationInFramesProp,
319
+ ];
320
+ // Validate: check if a preceding overlay extends beyond this sequence
321
+ if (resolvedPendingOverlayValidation) {
322
+ resolvedPendingOverlayValidation = false;
323
+ const lastOverlay = overlayRenders[overlayRenders.length - 1];
324
+ if (!lastOverlay) {
325
+ throw new Error('Expected an overlay to validate');
326
+ }
327
+ const framesAfterCut = lastOverlay.halfDuration + lastOverlay.overlayOffset;
328
+ if (framesAfterCut > durationInFramesProp) {
329
+ throw new TypeError(`A <TransitionSeries.Overlay /> extends beyond the next sequence. The overlay needs ${framesAfterCut} frames after the cut, but the next sequence is only ${durationInFramesProp} frames long.`);
330
+ }
331
+ }
332
+ const renderSequenceAndRest = (sequence) => {
333
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [sequence, renderNext({
334
+ transitionOffsets: resolvedTransitionOffsets,
335
+ startFrame: resolvedStartFrame,
336
+ sequenceDurations: nextSequenceDurations,
337
+ pendingOverlayValidation: resolvedPendingOverlayValidation,
338
+ })] }));
339
+ };
340
+ const nextProgress = next
341
+ ? next.props.timing.getProgress({
342
+ frame: frame -
343
+ actualStartFrame -
344
+ durationInFrames +
345
+ next.props.timing.getDurationInFrames({ fps }),
346
+ fps,
347
+ })
348
+ : null;
349
+ const prevProgress = prev
350
+ ? prev.props.timing.getProgress({
351
+ frame: frame - actualStartFrame,
352
+ fps,
353
+ })
354
+ : null;
355
+ if (next &&
356
+ durationInFramesProp < next.props.timing.getDurationInFrames({ fps })) {
357
+ throw new Error(`The duration of a <TransitionSeries.Sequence /> must not be shorter than the duration of the next <TransitionSeries.Transition />. The transition is ${next.props.timing.getDurationInFrames({ fps })} frames long, but the sequence is only ${durationInFramesProp} frames long (${debugInfo})`);
358
+ }
359
+ if (prev &&
360
+ durationInFramesProp < prev.props.timing.getDurationInFrames({ fps })) {
361
+ throw new Error(`The duration of a <TransitionSeries.Sequence /> must not be shorter than the duration of the previous <TransitionSeries.Transition />. The transition is ${prev.props.timing.getDurationInFrames({ fps })} frames long, but the sequence is only ${durationInFramesProp} frames long (${debugInfo})`);
362
+ }
363
+ if (next && prev && nextProgress !== null && prevProgress !== null) {
364
+ const nextPresentation = (_a = next.props.presentation) !== null && _a !== void 0 ? _a : (0, slide_js_1.slide)();
365
+ const prevPresentation = (_b = prev.props.presentation) !== null && _b !== void 0 ? _b : (0, slide_js_1.slide)();
366
+ const UppercaseNextPresentation = nextPresentation.component;
367
+ const UppercasePrevPresentation = prevPresentation.component;
368
+ return renderSequenceAndRest(jsx_runtime_1.jsx(SequenceWithoutSchema, { from: actualStartFrame, durationInFrames: durationInFramesProp, ...passedProps, name: passedProps.name || '<TS.Sequence>', _remotionInternalDocumentationLink: passedProps.name
369
+ ? undefined
370
+ : 'https://www.remotion.dev/docs/transitions/transitionseries', _remotionInternalStack: stack !== null && stack !== void 0 ? stack : undefined, controls: controls !== null && controls !== void 0 ? controls : undefined, children: jsx_runtime_1.jsx(UppercaseNextPresentation, { passedProps: (_c = nextPresentation.props) !== null && _c !== void 0 ? _c : {}, presentationDirection: "exiting", presentationProgress: nextProgress, presentationDurationInFrames: next.props.timing.getDurationInFrames({ fps }), onElementImage: () => {
371
+ throw new Error('Should not call when exiting');
260
372
  }, onUnmount: () => {
261
- onPrevElementImage(null, null, null, i + 1);
373
+ throw new Error('Should not call when exiting');
374
+ }, bothEnteringAndExiting: true, children: jsx_runtime_1.jsx(context_js_1.WrapInExitingProgressContext, { presentationProgress: nextProgress, children: jsx_runtime_1.jsx(UppercasePrevPresentation, { passedProps: (_d = prevPresentation.props) !== null && _d !== void 0 ? _d : {}, presentationDirection: "entering", presentationProgress: prevProgress, presentationDurationInFrames: prev.props.timing.getDurationInFrames({ fps }), onElementImage: (elementImage, draw) => {
375
+ onPrevElementImage(elementImage, nextProgress, draw, i + 1);
376
+ onNextElementImage(elementImage, prevProgress, draw, i - 1);
377
+ }, onUnmount: () => {
378
+ onPrevElementImage(null, null, null, i + 1);
379
+ onNextElementImage(null, null, null, i - 1);
380
+ }, bothEnteringAndExiting: true, children: jsx_runtime_1.jsx(context_js_1.WrapInEnteringProgressContext, { presentationProgress: prevProgress, children: sequenceChildren }) }) }) }) }, i));
381
+ }
382
+ if (prevProgress !== null && prev) {
383
+ const prevPresentation = (_e = prev.props.presentation) !== null && _e !== void 0 ? _e : (0, slide_js_1.slide)();
384
+ const UppercasePrevPresentation = prevPresentation.component;
385
+ return renderSequenceAndRest(jsx_runtime_1.jsx(SequenceWithoutSchema, { from: actualStartFrame, durationInFrames: durationInFramesProp, ...passedProps, name: passedProps.name || '<TS.Sequence>', _remotionInternalDocumentationLink: passedProps.name
386
+ ? undefined
387
+ : 'https://www.remotion.dev/docs/transitions/transitionseries', _remotionInternalStack: stack !== null && stack !== void 0 ? stack : undefined, controls: controls !== null && controls !== void 0 ? controls : undefined, children: jsx_runtime_1.jsx(UppercasePrevPresentation, { passedProps: (_f = prevPresentation.props) !== null && _f !== void 0 ? _f : {}, presentationDirection: "entering", presentationProgress: prevProgress, presentationDurationInFrames: prev.props.timing.getDurationInFrames({ fps }), onElementImage: (elementImage, draw) => onNextElementImage(elementImage, prevProgress, draw, i - 1), onUnmount: () => {
262
388
  onNextElementImage(null, null, null, i - 1);
263
- }, bothEnteringAndExiting: true, children: jsx_runtime_1.jsx(context_js_1.WrapInEnteringProgressContext, { presentationProgress: prevProgress, children: child }) }) }) }) }, i));
264
- }
265
- if (prevProgress !== null && prev) {
266
- const prevPresentation = (_g = prev.props.presentation) !== null && _g !== void 0 ? _g : (0, slide_js_1.slide)();
267
- const UppercasePrevPresentation = prevPresentation.component;
268
- return (jsx_runtime_1.jsx(SequenceWithoutSchema
269
- // eslint-disable-next-line react/no-array-index-key
270
- , { from: actualStartFrame, durationInFrames: durationInFramesProp, ...passedProps, name: passedProps.name || '<TS.Sequence>', _remotionInternalDocumentationLink: passedProps.name
271
- ? undefined
272
- : 'https://www.remotion.dev/docs/transitions/transitionseries', children: jsx_runtime_1.jsx(UppercasePrevPresentation, { passedProps: (_h = prevPresentation.props) !== null && _h !== void 0 ? _h : {}, presentationDirection: "entering", presentationProgress: prevProgress, presentationDurationInFrames: prev.props.timing.getDurationInFrames({ fps }), onElementImage: (elementImage, draw) => onNextElementImage(elementImage, prevProgress, draw, i - 1), onUnmount: () => {
273
- onNextElementImage(null, null, null, i - 1);
274
- }, bothEnteringAndExiting: false, children: jsx_runtime_1.jsx(context_js_1.WrapInEnteringProgressContext, { presentationProgress: prevProgress, children: child }) }) }, i));
275
- }
276
- if (nextProgress !== null && next) {
277
- const nextPresentation = (_j = next.props.presentation) !== null && _j !== void 0 ? _j : (0, slide_js_1.slide)();
278
- const UppercaseNextPresentation = nextPresentation.component;
279
- return (jsx_runtime_1.jsx(SequenceWithoutSchema
280
- // eslint-disable-next-line react/no-array-index-key
281
- , { from: actualStartFrame, durationInFrames: durationInFramesProp, ...passedProps, name: passedProps.name || '<TS.Sequence>', _remotionInternalDocumentationLink: passedProps.name
282
- ? undefined
283
- : 'https://www.remotion.dev/docs/transitions/transitionseries', children: jsx_runtime_1.jsx(UppercaseNextPresentation, { passedProps: (_k = nextPresentation.props) !== null && _k !== void 0 ? _k : {}, presentationDirection: "exiting", presentationProgress: nextProgress, presentationDurationInFrames: next.props.timing.getDurationInFrames({ fps }), onElementImage: (elementImage, draw) => onPrevElementImage(elementImage, nextProgress, draw, i + 1), onUnmount: () => {
284
- onPrevElementImage(null, null, null, i + 1);
285
- }, bothEnteringAndExiting: false, children: jsx_runtime_1.jsx(context_js_1.WrapInExitingProgressContext, { presentationProgress: nextProgress, children: child }) }) }, i));
286
- }
287
- return (jsx_runtime_1.jsx(SequenceWithoutSchema
288
- // eslint-disable-next-line react/no-array-index-key
289
- , { from: actualStartFrame, durationInFrames: durationInFramesProp, ...passedProps, name: passedProps.name || '<TS.Sequence>', _remotionInternalDocumentationLink: passedProps.name
290
- ? undefined
291
- : 'https://www.remotion.dev/docs/transitions/transitionseries', children: child }, i));
292
- });
293
- // Now render overlay sequences
294
- const overlayElements = overlayRenders.map((overlayInfo) => {
295
- const info = overlayInfo;
296
- return (jsx_runtime_1.jsx(SequenceWithoutSchema, { from: Math.round(info.overlayFrom), durationInFrames: info.durationInFrames, name: "<TS.Overlay>", _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/transitions/transitionseries", layout: "absolute-fill", children: info.children }, `overlay-${info.index}`));
389
+ }, bothEnteringAndExiting: false, children: jsx_runtime_1.jsx(context_js_1.WrapInEnteringProgressContext, { presentationProgress: prevProgress, children: sequenceChildren }) }) }, i));
390
+ }
391
+ if (nextProgress !== null && next) {
392
+ const nextPresentation = (_g = next.props.presentation) !== null && _g !== void 0 ? _g : (0, slide_js_1.slide)();
393
+ const UppercaseNextPresentation = nextPresentation.component;
394
+ return renderSequenceAndRest(jsx_runtime_1.jsx(SequenceWithoutSchema, { from: actualStartFrame, durationInFrames: durationInFramesProp, ...passedProps, name: passedProps.name || '<TS.Sequence>', _remotionInternalDocumentationLink: passedProps.name
395
+ ? undefined
396
+ : 'https://www.remotion.dev/docs/transitions/transitionseries', _remotionInternalStack: stack !== null && stack !== void 0 ? stack : undefined, controls: controls !== null && controls !== void 0 ? controls : undefined, children: jsx_runtime_1.jsx(UppercaseNextPresentation, { passedProps: (_h = nextPresentation.props) !== null && _h !== void 0 ? _h : {}, presentationDirection: "exiting", presentationProgress: nextProgress, presentationDurationInFrames: next.props.timing.getDurationInFrames({ fps }), onElementImage: (elementImage, draw) => onPrevElementImage(elementImage, nextProgress, draw, i + 1), onUnmount: () => {
397
+ onPrevElementImage(null, null, null, i + 1);
398
+ }, bothEnteringAndExiting: false, children: jsx_runtime_1.jsx(context_js_1.WrapInExitingProgressContext, { presentationProgress: nextProgress, children: sequenceChildren }) }) }, i));
399
+ }
400
+ return renderSequenceAndRest(jsx_runtime_1.jsx(SequenceWithoutSchema, { from: actualStartFrame, durationInFrames: durationInFramesProp, ...passedProps, name: passedProps.name || '<TS.Sequence>', _remotionInternalDocumentationLink: passedProps.name
401
+ ? undefined
402
+ : 'https://www.remotion.dev/docs/transitions/transitionseries', _remotionInternalStack: stack !== null && stack !== void 0 ? stack : undefined, controls: controls !== null && controls !== void 0 ? controls : undefined, children: sequenceChildren }, i));
403
+ },
404
+ });
405
+ };
406
+ return renderChildren({
407
+ index: 0,
408
+ transitionOffsets: 0,
409
+ startFrame: 0,
410
+ overlayRenders: [],
411
+ sequenceDurations: [],
412
+ pendingOverlayValidation: false,
297
413
  });
298
- return [...(mainChildren || []), ...overlayElements];
299
414
  }, [flattedChildren, fps, frame, onPrevElementImage, onNextElementImage]);
300
415
  // eslint-disable-next-line react/jsx-no-useless-fragment
301
416
  return jsx_runtime_1.jsx(jsx_runtime_1.Fragment, { children: childrenValue });
@@ -328,4 +443,3 @@ exports.TransitionSeries = TransitionSeries;
328
443
  TransitionSeries.Sequence = SeriesSequence;
329
444
  TransitionSeries.Transition = TransitionSeriesTransition;
330
445
  TransitionSeries.Overlay = SeriesOverlay;
331
- remotion_1.Internals.addSequenceStackTraces(TransitionSeries);