remotion 4.0.472 → 4.0.473

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/cjs/Img.d.ts CHANGED
@@ -26,7 +26,6 @@ export declare const imgSchema: {
26
26
  };
27
27
  readonly 'style.scale': {
28
28
  readonly type: "scale";
29
- readonly min: 0.05;
30
29
  readonly max: 100;
31
30
  readonly step: 0.01;
32
31
  readonly default: 1;
@@ -70,4 +70,6 @@ export type SequencePropsWithoutDuration = {
70
70
  export type SequenceProps = {
71
71
  readonly durationInFrames?: number;
72
72
  } & SequencePropsWithoutDuration;
73
+ export declare const SequenceWithoutSchema: React.ForwardRefExoticComponent<SequenceProps & React.RefAttributes<HTMLDivElement>>;
73
74
  export declare const Sequence: React.ComponentType<SequenceProps & React.RefAttributes<HTMLDivElement>>;
75
+ export declare const SequenceWithoutFrom: React.ComponentType<SequenceProps & React.RefAttributes<HTMLDivElement>>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Sequence = void 0;
3
+ exports.SequenceWithoutFrom = exports.Sequence = exports.SequenceWithoutSchema = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  /* eslint-disable @typescript-eslint/no-use-before-define */
6
6
  const react_1 = require("react");
@@ -316,6 +316,7 @@ const SequenceRefForwardingFunction = (props, ref) => {
316
316
  return jsx_runtime_1.jsx(RegularSequence, { ...props, ref: ref });
317
317
  };
318
318
  const SequenceInner = (0, react_1.forwardRef)(SequenceRefForwardingFunction);
319
+ exports.SequenceWithoutSchema = SequenceInner;
319
320
  /*
320
321
  * @description A component that time-shifts its children and wraps them in an absolutely positioned <div>.
321
322
  * @see [Documentation](https://www.remotion.dev/docs/sequence)
@@ -325,3 +326,8 @@ exports.Sequence = (0, wrap_in_schema_js_1.wrapInSchema)({
325
326
  schema: sequence_field_schema_js_1.sequenceSchema,
326
327
  supportsEffects: false,
327
328
  });
329
+ exports.SequenceWithoutFrom = (0, wrap_in_schema_js_1.wrapInSchema)({
330
+ Component: SequenceInner,
331
+ schema: sequence_field_schema_js_1.sequenceSchemaWithoutFrom,
332
+ supportsEffects: false,
333
+ });
@@ -10,7 +10,6 @@ export declare const canvasImageSchema: {
10
10
  };
11
11
  readonly 'style.scale': {
12
12
  readonly type: "scale";
13
- readonly min: 0.05;
14
13
  readonly max: 100;
15
14
  readonly step: 0.01;
16
15
  readonly default: 1;
@@ -111,7 +111,6 @@ export declare const Internals: {
111
111
  };
112
112
  readonly 'style.scale': {
113
113
  readonly type: "scale";
114
- readonly min: 0.05;
115
114
  readonly max: 100;
116
115
  readonly step: 0.01;
117
116
  readonly default: 1;
@@ -158,6 +157,7 @@ export declare const Internals: {
158
157
  };
159
158
  };
160
159
  };
160
+ readonly SequenceWithoutSchema: import("react").ForwardRefExoticComponent<import("./Sequence.js").SequenceProps & import("react").RefAttributes<HTMLDivElement>>;
161
161
  readonly sequenceStyleSchema: {
162
162
  readonly 'style.translate': {
163
163
  readonly type: "translate";
@@ -167,7 +167,6 @@ export declare const Internals: {
167
167
  };
168
168
  readonly 'style.scale': {
169
169
  readonly type: "scale";
170
- readonly min: 0.05;
171
170
  readonly max: 100;
172
171
  readonly step: 0.01;
173
172
  readonly default: 1;
@@ -219,7 +218,6 @@ export declare const Internals: {
219
218
  };
220
219
  readonly 'style.scale': {
221
220
  readonly type: "scale";
222
- readonly min: 0.05;
223
221
  readonly max: 100;
224
222
  readonly step: 0.01;
225
223
  readonly default: 1;
@@ -675,7 +673,7 @@ export declare const Internals: {
675
673
  readonly interpolateKeyframedStatus: ({ frame, status, }: {
676
674
  frame: number;
677
675
  status: CanUpdateSequencePropStatusKeyframed;
678
- }) => string | number | null;
676
+ }) => string | number | readonly number[] | null;
679
677
  readonly makeStaticDragOverride: (value: unknown) => DragOverrideValue;
680
678
  readonly makeKeyframedDragOverride: ({ status, frame, value, }: {
681
679
  status: CanUpdateSequencePropStatusKeyframed;
@@ -82,6 +82,7 @@ const ResolveCompositionConfig_js_1 = require("./ResolveCompositionConfig.js");
82
82
  const sequence_field_schema_js_1 = require("./sequence-field-schema.js");
83
83
  const sequence_node_path_js_1 = require("./sequence-node-path.js");
84
84
  const sequence_stack_traces_js_1 = require("./sequence-stack-traces.js");
85
+ const Sequence_js_1 = require("./Sequence.js");
85
86
  const SequenceContext_js_1 = require("./SequenceContext.js");
86
87
  const SequenceManager_js_1 = require("./SequenceManager.js");
87
88
  const setup_env_variables_js_1 = require("./setup-env-variables.js");
@@ -140,6 +141,7 @@ exports.Internals = {
140
141
  SequenceStackTracesUpdateContext: sequence_stack_traces_js_1.SequenceStackTracesUpdateContext,
141
142
  wrapInSchema: wrap_in_schema_js_1.wrapInSchema,
142
143
  sequenceSchema: sequence_field_schema_js_1.sequenceSchema,
144
+ SequenceWithoutSchema: Sequence_js_1.SequenceWithoutSchema,
143
145
  sequenceStyleSchema: sequence_field_schema_js_1.sequenceStyleSchema,
144
146
  sequenceVisualStyleSchema: sequence_field_schema_js_1.sequenceVisualStyleSchema,
145
147
  sequencePremountSchema: sequence_field_schema_js_1.sequencePremountSchema,
@@ -1,5 +1,7 @@
1
1
  import type { CanUpdateSequencePropStatusKeyframed } from './use-schema.js';
2
+ type InterpolateKeyframedStatusResult = number | string | readonly number[] | null;
2
3
  export declare const interpolateKeyframedStatus: ({ frame, status, }: {
3
4
  frame: number;
4
5
  status: CanUpdateSequencePropStatusKeyframed;
5
- }) => string | number | null;
6
+ }) => InterpolateKeyframedStatusResult;
7
+ export {};
@@ -16,8 +16,9 @@ const interpolateKeyframedStatus = ({ frame, status, }) => {
16
16
  if (keyframes.length === 0) {
17
17
  return null;
18
18
  }
19
- const inputRange = keyframes.map((k) => k.frame);
20
- const outputs = keyframes.map((k) => k.value);
19
+ const sortedKeyframes = [...keyframes].sort((a, b) => a.frame - b.frame);
20
+ const inputRange = sortedKeyframes.map((k) => k.frame);
21
+ const outputs = sortedKeyframes.map((k) => k.value);
21
22
  if (interpolationFunction === 'interpolateColors') {
22
23
  if (!outputs.every((v) => typeof v === 'string')) {
23
24
  return null;
@@ -10,8 +10,15 @@ export type InterpolateOptions = Partial<{
10
10
  extrapolateRight: ExtrapolateType;
11
11
  posterize: number;
12
12
  }>;
13
+ type NumericTuple = readonly [number, ...number[]];
14
+ type WidenNumericTuple<T extends readonly number[]> = {
15
+ readonly [Key in keyof T]: number;
16
+ };
13
17
  export declare function assertValidInterpolateEasingOption(easing: EasingFunction | readonly EasingFunction[] | undefined, inputRangeLength: number): void;
14
18
  export declare function assertValidInterpolatePosterizeOption(posterize: number | undefined): void;
15
19
  export declare function interpolate(input: number, inputRange: readonly number[], outputRange: readonly number[], options?: InterpolateOptions): number;
16
20
  export declare function interpolate(input: number, inputRange: readonly number[], outputRange: readonly string[], options?: InterpolateOptions): string;
17
- export declare function interpolate(input: number, inputRange: readonly number[], outputRange: readonly (number | string)[], options?: InterpolateOptions): number | string;
21
+ export declare function interpolate<const Tuple extends NumericTuple>(input: number, inputRange: readonly number[], outputRange: readonly Tuple[], options?: InterpolateOptions): WidenNumericTuple<Tuple>;
22
+ export declare function interpolate(input: number, inputRange: readonly number[], outputRange: readonly (readonly number[])[], options?: InterpolateOptions): number[];
23
+ export declare function interpolate(input: number, inputRange: readonly number[], outputRange: readonly (number | string | readonly number[])[], options?: InterpolateOptions): number | string | readonly number[];
24
+ export {};
@@ -261,6 +261,36 @@ const interpolateString = ({ input, inputRange, outputRange, options, }) => {
261
261
  dimensions,
262
262
  });
263
263
  };
264
+ const validateTupleOutputRange = (outputRange) => {
265
+ var _a;
266
+ const dimensions = (_a = outputRange[0]) === null || _a === void 0 ? void 0 : _a.length;
267
+ if (dimensions === undefined) {
268
+ throw new Error('outputRange must have at least 1 element');
269
+ }
270
+ if (dimensions === 0) {
271
+ throw new TypeError('outputRange tuples must contain at least 1 number');
272
+ }
273
+ for (const output of outputRange) {
274
+ if (output.length !== dimensions) {
275
+ throw new TypeError(`outputRange tuples must all have the same length, but got ${dimensions} and ${output.length}`);
276
+ }
277
+ for (const value of output) {
278
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
279
+ throw new TypeError(`outputRange tuples must contain only finite numbers, but got [${output.join(',')}]`);
280
+ }
281
+ }
282
+ }
283
+ return dimensions;
284
+ };
285
+ const interpolateTuple = ({ input, inputRange, outputRange, options, }) => {
286
+ const dimensions = validateTupleOutputRange(outputRange);
287
+ return new Array(dimensions).fill(true).map((_, axis) => interpolateNumber({
288
+ input,
289
+ inputRange,
290
+ outputRange: outputRange.map((output) => output[axis]),
291
+ options,
292
+ }));
293
+ };
264
294
  function checkValidInputRange(arr) {
265
295
  for (let i = 1; i < arr.length; ++i) {
266
296
  if (!(arr[i] > arr[i - 1])) {
@@ -342,8 +372,11 @@ function interpolate(input, inputRange, outputRange, options) {
342
372
  }
343
373
  return interpolateString({ input, inputRange, outputRange, options });
344
374
  }
375
+ if (outputRange.every((output) => Array.isArray(output))) {
376
+ return interpolateTuple({ input, inputRange, outputRange, options });
377
+ }
345
378
  if (!outputRange.every((output) => typeof output === 'number')) {
346
- throw new TypeError('outputRange must contain only numbers, or supported scale, translate, and rotate strings');
379
+ throw new TypeError('outputRange must contain only numbers, numeric tuples, or supported scale, translate, and rotate strings');
347
380
  }
348
381
  checkInfiniteRange('outputRange', outputRange);
349
382
  return interpolateNumber({ input, inputRange, outputRange, options });
@@ -90,7 +90,6 @@ export declare const NoReactInternals: {
90
90
  };
91
91
  readonly 'style.scale': {
92
92
  readonly type: "scale";
93
- readonly min: 0.05;
94
93
  readonly max: 100;
95
94
  readonly step: 0.01;
96
95
  readonly default: 1;
@@ -55,6 +55,7 @@ export type UvCoordinateFieldSchema = {
55
55
  min?: number;
56
56
  max?: number;
57
57
  step?: number;
58
+ lineTo?: string;
58
59
  default: readonly [number, number] | undefined;
59
60
  description?: string;
60
61
  keyframable?: boolean;
@@ -109,7 +110,6 @@ export declare const sequenceVisualStyleSchema: {
109
110
  };
110
111
  readonly 'style.scale': {
111
112
  readonly type: "scale";
112
- readonly min: 0.05;
113
113
  readonly max: 100;
114
114
  readonly step: 0.01;
115
115
  readonly default: 1;
@@ -163,7 +163,6 @@ export declare const sequenceStyleSchema: {
163
163
  };
164
164
  readonly 'style.scale': {
165
165
  readonly type: "scale";
166
- readonly min: 0.05;
167
166
  readonly max: 100;
168
167
  readonly step: 0.01;
169
168
  readonly default: 1;
@@ -249,7 +248,75 @@ export declare const sequenceSchema: {
249
248
  };
250
249
  readonly 'style.scale': {
251
250
  readonly type: "scale";
252
- readonly min: 0.05;
251
+ readonly max: 100;
252
+ readonly step: 0.01;
253
+ readonly default: 1;
254
+ readonly description: "Scale";
255
+ };
256
+ readonly 'style.rotate': {
257
+ readonly type: "rotation-css";
258
+ readonly step: 1;
259
+ readonly default: "0deg";
260
+ readonly description: "Rotation";
261
+ };
262
+ readonly 'style.opacity': {
263
+ readonly type: "number";
264
+ readonly min: 0;
265
+ readonly max: 1;
266
+ readonly step: 0.01;
267
+ readonly default: 1;
268
+ readonly description: "Opacity";
269
+ readonly hiddenFromList: false;
270
+ };
271
+ readonly premountFor: {
272
+ readonly type: "number";
273
+ readonly default: 0;
274
+ readonly description: "Premount For";
275
+ readonly min: 0;
276
+ readonly step: 1;
277
+ readonly hiddenFromList: false;
278
+ };
279
+ readonly postmountFor: {
280
+ readonly type: "number";
281
+ readonly default: 0;
282
+ readonly min: 0;
283
+ readonly step: 1;
284
+ readonly hiddenFromList: true;
285
+ };
286
+ readonly styleWhilePremounted: {
287
+ readonly type: "hidden";
288
+ };
289
+ readonly styleWhilePostmounted: {
290
+ readonly type: "hidden";
291
+ };
292
+ };
293
+ readonly none: {};
294
+ };
295
+ };
296
+ };
297
+ export declare const sequenceSchemaWithoutFrom: {
298
+ readonly hidden: BooleanFieldSchema;
299
+ readonly durationInFrames: {
300
+ readonly type: "number";
301
+ readonly default: undefined;
302
+ readonly min: 1;
303
+ readonly step: 1;
304
+ readonly hiddenFromList: true;
305
+ };
306
+ readonly layout: {
307
+ readonly type: "enum";
308
+ readonly default: "absolute-fill";
309
+ readonly description: "Layout";
310
+ readonly variants: {
311
+ readonly 'absolute-fill': {
312
+ readonly 'style.translate': {
313
+ readonly type: "translate";
314
+ readonly step: 1;
315
+ readonly default: "0px 0px";
316
+ readonly description: "Offset";
317
+ };
318
+ readonly 'style.scale': {
319
+ readonly type: "scale";
253
320
  readonly max: 100;
254
321
  readonly step: 0.01;
255
322
  readonly default: 1;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sequenceSchemaDefaultLayoutNone = exports.sequenceSchema = exports.fromField = exports.durationInFramesField = exports.hiddenField = exports.sequenceStyleSchema = exports.sequencePremountSchema = exports.sequenceVisualStyleSchema = void 0;
3
+ exports.sequenceSchemaDefaultLayoutNone = exports.sequenceSchemaWithoutFrom = exports.sequenceSchema = exports.fromField = exports.durationInFramesField = exports.hiddenField = exports.sequenceStyleSchema = exports.sequencePremountSchema = exports.sequenceVisualStyleSchema = void 0;
4
4
  exports.sequenceVisualStyleSchema = {
5
5
  'style.translate': {
6
6
  type: 'translate',
@@ -10,7 +10,6 @@ exports.sequenceVisualStyleSchema = {
10
10
  },
11
11
  'style.scale': {
12
12
  type: 'scale',
13
- min: 0.05,
14
13
  max: 100,
15
14
  step: 0.01,
16
15
  default: 1,
@@ -91,6 +90,11 @@ exports.sequenceSchema = {
91
90
  },
92
91
  },
93
92
  };
93
+ exports.sequenceSchemaWithoutFrom = {
94
+ hidden: exports.hiddenField,
95
+ durationInFrames: exports.durationInFramesField,
96
+ layout: exports.sequenceSchema.layout,
97
+ };
94
98
  exports.sequenceSchemaDefaultLayoutNone = {
95
99
  ...exports.sequenceSchema,
96
100
  layout: {
@@ -16,6 +16,7 @@ const SeriesSequenceRefForwardingFunction = ({ children }, _ref) => {
16
16
  return jsx_runtime_1.jsx(is_inside_series_js_1.IsNotInsideSeriesProvider, { children: children });
17
17
  };
18
18
  const SeriesSequence = (0, react_1.forwardRef)(SeriesSequenceRefForwardingFunction);
19
+ const SequenceWithoutSchemaWithRef = Sequence_js_1.SequenceWithoutSchema;
19
20
  const SeriesInner = (props) => {
20
21
  const childrenValue = (0, react_1.useMemo)(() => {
21
22
  let startFrame = 0;
@@ -55,7 +56,7 @@ const SeriesInner = (props) => {
55
56
  }
56
57
  const currentStartFrame = startFrame + offset;
57
58
  startFrame += durationInFramesProp + offset;
58
- return (jsx_runtime_1.jsx(Sequence_js_1.Sequence, { name: name || '<Series.Sequence>', _remotionInternalDocumentationLink: name ? undefined : 'https://www.remotion.dev/docs/series', from: currentStartFrame, durationInFrames: durationInFramesProp, ...passedProps, ref: castedChild.ref, children: child }));
59
+ return (jsx_runtime_1.jsx(SequenceWithoutSchemaWithRef, { ref: castedChild.ref, name: name || '<Series.Sequence>', _remotionInternalDocumentationLink: name ? undefined : 'https://www.remotion.dev/docs/series', from: currentStartFrame, durationInFrames: durationInFramesProp, ...passedProps, children: child }));
59
60
  });
60
61
  }, [props.children]);
61
62
  return (jsx_runtime_1.jsx(is_inside_series_js_1.IsInsideSeriesContainer, { children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", name: "<Series>", _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/series", ...props, children: childrenValue }) }));
@@ -73,4 +74,3 @@ const Series = Object.assign((0, wrap_in_schema_js_1.wrapInSchema)({
73
74
  });
74
75
  exports.Series = Series;
75
76
  (0, enable_sequence_stack_traces_js_1.addSequenceStackTraces)(Series);
76
- (0, enable_sequence_stack_traces_js_1.addSequenceStackTraces)(SeriesSequence);
@@ -8,6 +8,7 @@ type CurrentTimePerComposition = Record<string, number>;
8
8
  export declare const persistCurrentFrame: (time: CurrentTimePerComposition) => void;
9
9
  export declare const getInitialFrameState: () => CurrentTimePerComposition;
10
10
  export declare const getFrameForComposition: (composition: string) => number;
11
+ export declare const clampFrameToCompositionRange: (frame: number, durationInFrames: number) => number;
11
12
  export declare const useTimelineContext: () => TimelineContextValue;
12
13
  export declare const usePlaybackRate: () => PlaybackRateContextValue;
13
14
  export declare const useTimelinePosition: () => number;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.usePlayingState = exports.useTimelineSetFrame = exports.useAbsoluteTimelinePosition = exports.useTimelinePosition = exports.usePlaybackRate = exports.useTimelineContext = exports.getFrameForComposition = exports.getInitialFrameState = exports.persistCurrentFrame = void 0;
3
+ exports.usePlayingState = exports.useTimelineSetFrame = exports.useAbsoluteTimelinePosition = exports.useTimelinePosition = exports.usePlaybackRate = exports.useTimelineContext = exports.clampFrameToCompositionRange = exports.getFrameForComposition = exports.getInitialFrameState = exports.persistCurrentFrame = void 0;
4
4
  const react_1 = require("react");
5
5
  const TimelineContext_js_1 = require("./TimelineContext.js");
6
6
  const use_remotion_environment_js_1 = require("./use-remotion-environment.js");
@@ -32,6 +32,10 @@ const getFrameForComposition = (composition) => {
32
32
  return (_b = window.remotion_initialFrame) !== null && _b !== void 0 ? _b : 0;
33
33
  };
34
34
  exports.getFrameForComposition = getFrameForComposition;
35
+ const clampFrameToCompositionRange = (frame, durationInFrames) => {
36
+ return Math.max(0, Math.min(Math.max(0, durationInFrames - 1), frame));
37
+ };
38
+ exports.clampFrameToCompositionRange = clampFrameToCompositionRange;
35
39
  const useTimelinePositionFromContext = (state) => {
36
40
  var _a, _b;
37
41
  const videoConfig = (0, use_video_js_1.useVideo)();
@@ -42,7 +46,7 @@ const useTimelinePositionFromContext = (state) => {
42
46
  : ((_a = window.remotion_initialFrame) !== null && _a !== void 0 ? _a : 0);
43
47
  }
44
48
  const unclamped = (_b = state.frame[videoConfig.id]) !== null && _b !== void 0 ? _b : (env.isPlayer ? 0 : (0, exports.getFrameForComposition)(videoConfig.id));
45
- return Math.min(videoConfig.durationInFrames - 1, unclamped);
49
+ return (0, exports.clampFrameToCompositionRange)(unclamped, videoConfig.durationInFrames);
46
50
  };
47
51
  const useTimelineContext = () => {
48
52
  const state = (0, react_1.useContext)(TimelineContext_js_1.TimelineContext);
@@ -3,4 +3,4 @@
3
3
  * @see [Documentation](https://remotion.dev/docs/version)
4
4
  * @returns {string} The current version of the remotion package
5
5
  */
6
- export declare const VERSION = "4.0.472";
6
+ export declare const VERSION = "4.0.473";
@@ -7,4 +7,4 @@ exports.VERSION = void 0;
7
7
  * @see [Documentation](https://remotion.dev/docs/version)
8
8
  * @returns {string} The current version of the remotion package
9
9
  */
10
- exports.VERSION = '4.0.472';
10
+ exports.VERSION = '4.0.473';
@@ -1291,7 +1291,7 @@ var addSequenceStackTraces = (component) => {
1291
1291
  };
1292
1292
 
1293
1293
  // src/version.ts
1294
- var VERSION = "4.0.472";
1294
+ var VERSION = "4.0.473";
1295
1295
 
1296
1296
  // src/multiple-versions-warning.ts
1297
1297
  var checkMultipleRemotionVersions = () => {
@@ -1355,7 +1355,8 @@ __export(exports_timeline_position_state, {
1355
1355
  useAbsoluteTimelinePosition: () => useAbsoluteTimelinePosition,
1356
1356
  persistCurrentFrame: () => persistCurrentFrame,
1357
1357
  getInitialFrameState: () => getInitialFrameState,
1358
- getFrameForComposition: () => getFrameForComposition
1358
+ getFrameForComposition: () => getFrameForComposition,
1359
+ clampFrameToCompositionRange: () => clampFrameToCompositionRange
1359
1360
  });
1360
1361
  import { useContext as useContext10, useMemo as useMemo9 } from "react";
1361
1362
 
@@ -1509,6 +1510,9 @@ var getFrameForComposition = (composition) => {
1509
1510
  }
1510
1511
  return window.remotion_initialFrame ?? 0;
1511
1512
  };
1513
+ var clampFrameToCompositionRange = (frame, durationInFrames) => {
1514
+ return Math.max(0, Math.min(Math.max(0, durationInFrames - 1), frame));
1515
+ };
1512
1516
  var useTimelinePositionFromContext = (state) => {
1513
1517
  const videoConfig = useVideo();
1514
1518
  const env = useRemotionEnvironment();
@@ -1516,7 +1520,7 @@ var useTimelinePositionFromContext = (state) => {
1516
1520
  return typeof window === "undefined" ? 0 : window.remotion_initialFrame ?? 0;
1517
1521
  }
1518
1522
  const unclamped = state.frame[videoConfig.id] ?? (env.isPlayer ? 0 : getFrameForComposition(videoConfig.id));
1519
- return Math.min(videoConfig.durationInFrames - 1, unclamped);
1523
+ return clampFrameToCompositionRange(unclamped, videoConfig.durationInFrames);
1520
1524
  };
1521
1525
  var useTimelineContext = () => {
1522
1526
  const state = useContext10(TimelineContext);
@@ -1723,7 +1727,6 @@ var sequenceVisualStyleSchema = {
1723
1727
  },
1724
1728
  "style.scale": {
1725
1729
  type: "scale",
1726
- min: 0.05,
1727
1730
  max: 100,
1728
1731
  step: 0.01,
1729
1732
  default: 1,
@@ -1804,6 +1807,11 @@ var sequenceSchema = {
1804
1807
  }
1805
1808
  }
1806
1809
  };
1810
+ var sequenceSchemaWithoutFrom = {
1811
+ hidden: hiddenField,
1812
+ durationInFrames: durationInFramesField,
1813
+ layout: sequenceSchema.layout
1814
+ };
1807
1815
  var sequenceSchemaDefaultLayoutNone = {
1808
1816
  ...sequenceSchema,
1809
1817
  layout: {
@@ -2483,6 +2491,40 @@ var interpolateString = ({
2483
2491
  dimensions
2484
2492
  });
2485
2493
  };
2494
+ var validateTupleOutputRange = (outputRange) => {
2495
+ const dimensions = outputRange[0]?.length;
2496
+ if (dimensions === undefined) {
2497
+ throw new Error("outputRange must have at least 1 element");
2498
+ }
2499
+ if (dimensions === 0) {
2500
+ throw new TypeError("outputRange tuples must contain at least 1 number");
2501
+ }
2502
+ for (const output of outputRange) {
2503
+ if (output.length !== dimensions) {
2504
+ throw new TypeError(`outputRange tuples must all have the same length, but got ${dimensions} and ${output.length}`);
2505
+ }
2506
+ for (const value of output) {
2507
+ if (typeof value !== "number" || !Number.isFinite(value)) {
2508
+ throw new TypeError(`outputRange tuples must contain only finite numbers, but got [${output.join(",")}]`);
2509
+ }
2510
+ }
2511
+ }
2512
+ return dimensions;
2513
+ };
2514
+ var interpolateTuple = ({
2515
+ input,
2516
+ inputRange,
2517
+ outputRange,
2518
+ options
2519
+ }) => {
2520
+ const dimensions = validateTupleOutputRange(outputRange);
2521
+ return new Array(dimensions).fill(true).map((_, axis) => interpolateNumber({
2522
+ input,
2523
+ inputRange,
2524
+ outputRange: outputRange.map((output) => output[axis]),
2525
+ options
2526
+ }));
2527
+ };
2486
2528
  function checkValidInputRange(arr) {
2487
2529
  for (let i = 1;i < arr.length; ++i) {
2488
2530
  if (!(arr[i] > arr[i - 1])) {
@@ -2558,8 +2600,11 @@ function interpolate(input, inputRange, outputRange, options) {
2558
2600
  }
2559
2601
  return interpolateString({ input, inputRange, outputRange, options });
2560
2602
  }
2603
+ if (outputRange.every((output) => Array.isArray(output))) {
2604
+ return interpolateTuple({ input, inputRange, outputRange, options });
2605
+ }
2561
2606
  if (!outputRange.every((output) => typeof output === "number")) {
2562
- throw new TypeError("outputRange must contain only numbers, or supported scale, translate, and rotate strings");
2607
+ throw new TypeError("outputRange must contain only numbers, numeric tuples, or supported scale, translate, and rotate strings");
2563
2608
  }
2564
2609
  checkInfiniteRange("outputRange", outputRange);
2565
2610
  return interpolateNumber({ input, inputRange, outputRange, options });
@@ -3076,8 +3121,9 @@ var interpolateKeyframedStatus = ({
3076
3121
  if (keyframes.length === 0) {
3077
3122
  return null;
3078
3123
  }
3079
- const inputRange = keyframes.map((k) => k.frame);
3080
- const outputs = keyframes.map((k) => k.value);
3124
+ const sortedKeyframes = [...keyframes].sort((a2, b2) => a2.frame - b2.frame);
3125
+ const inputRange = sortedKeyframes.map((k) => k.frame);
3126
+ const outputs = sortedKeyframes.map((k) => k.value);
3081
3127
  if (interpolationFunction === "interpolateColors") {
3082
3128
  if (!outputs.every((v) => typeof v === "string")) {
3083
3129
  return null;
@@ -3945,11 +3991,17 @@ var SequenceRefForwardingFunction = (props, ref) => {
3945
3991
  });
3946
3992
  };
3947
3993
  var SequenceInner = forwardRef3(SequenceRefForwardingFunction);
3994
+ var SequenceWithoutSchema = SequenceInner;
3948
3995
  var Sequence = wrapInSchema({
3949
3996
  Component: SequenceInner,
3950
3997
  schema: sequenceSchema,
3951
3998
  supportsEffects: false
3952
3999
  });
4000
+ var SequenceWithoutFrom = wrapInSchema({
4001
+ Component: SequenceInner,
4002
+ schema: sequenceSchemaWithoutFrom,
4003
+ supportsEffects: false
4004
+ });
3953
4005
  // src/animated-image/AnimatedImage.tsx
3954
4006
  import {
3955
4007
  forwardRef as forwardRef4,
@@ -10568,6 +10620,7 @@ var Internals = {
10568
10620
  SequenceStackTracesUpdateContext,
10569
10621
  wrapInSchema,
10570
10622
  sequenceSchema,
10623
+ SequenceWithoutSchema,
10571
10624
  sequenceStyleSchema,
10572
10625
  sequenceVisualStyleSchema,
10573
10626
  sequencePremountSchema,
@@ -10742,6 +10795,7 @@ var SeriesSequenceRefForwardingFunction = ({ children }, _ref) => {
10742
10795
  });
10743
10796
  };
10744
10797
  var SeriesSequence = forwardRef13(SeriesSequenceRefForwardingFunction);
10798
+ var SequenceWithoutSchemaWithRef = SequenceWithoutSchema;
10745
10799
  var SeriesInner = (props2) => {
10746
10800
  const childrenValue = useMemo38(() => {
10747
10801
  let startFrame = 0;
@@ -10784,13 +10838,13 @@ var SeriesInner = (props2) => {
10784
10838
  }
10785
10839
  const currentStartFrame = startFrame + offset;
10786
10840
  startFrame += durationInFramesProp + offset;
10787
- return /* @__PURE__ */ jsx36(Sequence, {
10841
+ return /* @__PURE__ */ jsx36(SequenceWithoutSchemaWithRef, {
10842
+ ref: castedChild.ref,
10788
10843
  name: name || "<Series.Sequence>",
10789
10844
  _remotionInternalDocumentationLink: name ? undefined : "https://www.remotion.dev/docs/series",
10790
10845
  from: currentStartFrame,
10791
10846
  durationInFrames: durationInFramesProp,
10792
10847
  ...passedProps,
10793
- ref: castedChild.ref,
10794
10848
  children: child
10795
10849
  });
10796
10850
  });
@@ -10813,7 +10867,6 @@ var Series = Object.assign(wrapInSchema({
10813
10867
  Sequence: SeriesSequence
10814
10868
  });
10815
10869
  addSequenceStackTraces(Series);
10816
- addSequenceStackTraces(SeriesSequence);
10817
10870
  // src/validation/validation-spring-duration.ts
10818
10871
  var validateSpringDuration = (dur) => {
10819
10872
  if (typeof dur === "undefined") {
@@ -252,6 +252,40 @@ var interpolateString = ({
252
252
  dimensions
253
253
  });
254
254
  };
255
+ var validateTupleOutputRange = (outputRange) => {
256
+ const dimensions = outputRange[0]?.length;
257
+ if (dimensions === undefined) {
258
+ throw new Error("outputRange must have at least 1 element");
259
+ }
260
+ if (dimensions === 0) {
261
+ throw new TypeError("outputRange tuples must contain at least 1 number");
262
+ }
263
+ for (const output of outputRange) {
264
+ if (output.length !== dimensions) {
265
+ throw new TypeError(`outputRange tuples must all have the same length, but got ${dimensions} and ${output.length}`);
266
+ }
267
+ for (const value of output) {
268
+ if (typeof value !== "number" || !Number.isFinite(value)) {
269
+ throw new TypeError(`outputRange tuples must contain only finite numbers, but got [${output.join(",")}]`);
270
+ }
271
+ }
272
+ }
273
+ return dimensions;
274
+ };
275
+ var interpolateTuple = ({
276
+ input,
277
+ inputRange,
278
+ outputRange,
279
+ options
280
+ }) => {
281
+ const dimensions = validateTupleOutputRange(outputRange);
282
+ return new Array(dimensions).fill(true).map((_, axis) => interpolateNumber({
283
+ input,
284
+ inputRange,
285
+ outputRange: outputRange.map((output) => output[axis]),
286
+ options
287
+ }));
288
+ };
255
289
  function checkValidInputRange(arr) {
256
290
  for (let i = 1;i < arr.length; ++i) {
257
291
  if (!(arr[i] > arr[i - 1])) {
@@ -327,8 +361,11 @@ function interpolate(input, inputRange, outputRange, options) {
327
361
  }
328
362
  return interpolateString({ input, inputRange, outputRange, options });
329
363
  }
364
+ if (outputRange.every((output) => Array.isArray(output))) {
365
+ return interpolateTuple({ input, inputRange, outputRange, options });
366
+ }
330
367
  if (!outputRange.every((output) => typeof output === "number")) {
331
- throw new TypeError("outputRange must contain only numbers, or supported scale, translate, and rotate strings");
368
+ throw new TypeError("outputRange must contain only numbers, numeric tuples, or supported scale, translate, and rotate strings");
332
369
  }
333
370
  checkInfiniteRange("outputRange", outputRange);
334
371
  return interpolateNumber({ input, inputRange, outputRange, options });
@@ -978,7 +1015,6 @@ var sequenceVisualStyleSchema = {
978
1015
  },
979
1016
  "style.scale": {
980
1017
  type: "scale",
981
- min: 0.05,
982
1018
  max: 100,
983
1019
  step: 0.01,
984
1020
  default: 1,
@@ -1059,6 +1095,11 @@ var sequenceSchema = {
1059
1095
  }
1060
1096
  }
1061
1097
  };
1098
+ var sequenceSchemaWithoutFrom = {
1099
+ hidden: hiddenField,
1100
+ durationInFrames: durationInFramesField,
1101
+ layout: sequenceSchema.layout
1102
+ };
1062
1103
  var sequenceSchemaDefaultLayoutNone = {
1063
1104
  ...sequenceSchema,
1064
1105
  layout: {
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = "4.0.472";
2
+ var VERSION = "4.0.473";
3
3
  export {
4
4
  VERSION
5
5
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/core"
4
4
  },
5
5
  "name": "remotion",
6
- "version": "4.0.472",
6
+ "version": "4.0.473",
7
7
  "description": "Make videos programmatically",
8
8
  "main": "dist/cjs/index.js",
9
9
  "types": "dist/cjs/index.d.ts",
@@ -35,7 +35,7 @@
35
35
  "react-dom": "19.2.3",
36
36
  "webpack": "5.105.0",
37
37
  "zod": "4.3.6",
38
- "@remotion/eslint-config-internal": "4.0.472",
38
+ "@remotion/eslint-config-internal": "4.0.473",
39
39
  "eslint": "9.19.0",
40
40
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
41
41
  },