remotion 4.0.528 → 4.0.529

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.
@@ -63,6 +63,7 @@ export type HtmlInCanvasProps = Omit<InteractiveBaseProps, 'children'> & Interac
63
63
  readonly onPaint?: HtmlInCanvasOnPaint;
64
64
  readonly onInit?: HtmlInCanvasOnInit;
65
65
  readonly pixelDensity?: HtmlInCanvasPixelDensity;
66
+ readonly _remotionInternalCanvasSiblings?: React.ReactNode;
66
67
  };
67
68
  export declare const htmlInCanvasSchema: {
68
69
  readonly 'style.transformOrigin': {
@@ -290,6 +291,7 @@ export declare const HtmlInCanvas: React.ForwardRefExoticComponent<Omit<Interact
290
291
  readonly onPaint?: HtmlInCanvasOnPaint | undefined;
291
292
  readonly onInit?: HtmlInCanvasOnInit | undefined;
292
293
  readonly pixelDensity?: number | undefined;
294
+ readonly _remotionInternalCanvasSiblings?: React.ReactNode;
293
295
  } & React.RefAttributes<HTMLCanvasElement>> & {
294
296
  readonly isSupported: () => boolean;
295
297
  };
@@ -100,7 +100,7 @@ const defaultOnPaint = ({ canvas, element, elementImage, }) => {
100
100
  };
101
101
  /* eslint-enable react/require-default-props */
102
102
  const HtmlInCanvasAncestorContext = (0, react_1.createContext)(false);
103
- const HtmlInCanvasContent = (0, react_1.forwardRef)(({ width, height, effects, children, onPaint, onInit, pixelDensity, controls, style, }, ref) => {
103
+ const HtmlInCanvasContent = (0, react_1.forwardRef)(({ width, height, effects, children, canvasSiblings, onPaint, onInit, pixelDensity, controls, style, }, ref) => {
104
104
  var _a;
105
105
  const isInsideAncestorHtmlInCanvas = (0, react_1.useContext)(HtmlInCanvasAncestorContext);
106
106
  assertHtmlInCanvasDimensions(width, height);
@@ -360,10 +360,11 @@ const HtmlInCanvasContent = (0, react_1.forwardRef)(({ width, height, effects, c
360
360
  ...(style !== null && style !== void 0 ? style : {}),
361
361
  };
362
362
  }, [height, style, width]);
363
- return (jsx_runtime_1.jsx(HtmlInCanvasAncestorContext.Provider, { value: true, children: jsx_runtime_1.jsx("canvas", { ref: setLayoutCanvasRef, width: canvasWidth, height: canvasHeight, style: canvasStyle, children: jsx_runtime_1.jsx("div", { ref: divRef, style: innerStyle, children: children }) }, canvasSizeKey) }));
363
+ return (jsx_runtime_1.jsx(HtmlInCanvasAncestorContext.Provider, { value: true, children: jsx_runtime_1.jsxs("canvas", { ref: setLayoutCanvasRef, width: canvasWidth, height: canvasHeight, style: canvasStyle, children: [
364
+ jsx_runtime_1.jsx("div", { ref: divRef, style: innerStyle, children: children }), canvasSiblings] }, canvasSizeKey) }));
364
365
  });
365
366
  HtmlInCanvasContent.displayName = 'HtmlInCanvasContent';
366
- const HtmlInCanvasInner = (0, react_1.forwardRef)(({ width, height, effects = [], children, onPaint, onInit, pixelDensity, controls, style, cropLeft, cropRight, cropTop, cropBottom, durationInFrames, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, name, ...sequenceProps }, ref) => {
367
+ const HtmlInCanvasInner = (0, react_1.forwardRef)(({ width, height, effects = [], children, onPaint, onInit, pixelDensity, _remotionInternalCanvasSiblings, controls, style, cropLeft, cropRight, cropTop, cropBottom, durationInFrames, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, name, ...sequenceProps }, ref) => {
367
368
  var _a;
368
369
  const memoizedEffectDefinitions = (0, use_memoized_effects_js_1.useMemoizedEffectDefinitions)(effects);
369
370
  const actualRef = (0, react_1.useRef)(null);
@@ -394,7 +395,7 @@ const HtmlInCanvasInner = (0, react_1.forwardRef)(({ width, height, effects = []
394
395
  style: premountingStyle,
395
396
  componentName: '<HtmlInCanvas />',
396
397
  });
397
- return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", durationInFrames: durationInFrames, name: name !== null && name !== void 0 ? name : '<HtmlInCanvas>', _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/remotion/html-in-canvas", controls: controls, _remotionInternalEffects: memoizedEffectDefinitions, outlineRef: actualRef, ...sequenceProps, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, children: jsx_runtime_1.jsx(HtmlInCanvasContent, { ref: setCanvasRef, width: width, height: height, effects: effects, onPaint: onPaint, onInit: onInit, pixelDensity: pixelDensity, controls: controls, style: croppedStyle !== null && croppedStyle !== void 0 ? croppedStyle : undefined, children: children }) }) }));
398
+ return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", durationInFrames: durationInFrames, name: name !== null && name !== void 0 ? name : '<HtmlInCanvas>', _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/remotion/html-in-canvas", controls: controls, _remotionInternalEffects: memoizedEffectDefinitions, outlineRef: actualRef, ...sequenceProps, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, children: jsx_runtime_1.jsx(HtmlInCanvasContent, { ref: setCanvasRef, width: width, height: height, effects: effects, onPaint: onPaint, onInit: onInit, pixelDensity: pixelDensity, canvasSiblings: _remotionInternalCanvasSiblings !== null && _remotionInternalCanvasSiblings !== void 0 ? _remotionInternalCanvasSiblings : null, controls: controls, style: croppedStyle !== null && croppedStyle !== void 0 ? croppedStyle : undefined, children: children }) }) }));
398
399
  });
399
400
  HtmlInCanvasInner.displayName = 'HtmlInCanvas';
400
401
  exports.htmlInCanvasSchema = {
@@ -94,7 +94,7 @@ const interactiveSvgPathElementSchema = {
94
94
  type: 'svg-path',
95
95
  default: undefined,
96
96
  description: 'Path',
97
- keyframable: false,
97
+ keyframable: true,
98
98
  },
99
99
  };
100
100
  const interactiveSvgStrokeElementSchema = {
@@ -20,7 +20,7 @@ export type BufferingState = Readonly<{
20
20
  }>;
21
21
  export type SetTimelineContextValue = {
22
22
  seek: TimelineSeek | null;
23
- setFrame: (u: React.SetStateAction<Record<string, number>>) => void;
23
+ setFrameWithoutSeek: (u: React.SetStateAction<Record<string, number>>) => void;
24
24
  setPlaying: (u: React.SetStateAction<boolean>) => void;
25
25
  setBuffering: (buffering: boolean) => void;
26
26
  subscribePlaying: (listener: (state: PlayingState) => void) => () => void;
@@ -13,7 +13,7 @@ const missingSetTimelineContext = () => {
13
13
  };
14
14
  exports.SetTimelineContext = (0, react_1.createContext)({
15
15
  seek: null,
16
- setFrame: missingSetTimelineContext,
16
+ setFrameWithoutSeek: missingSetTimelineContext,
17
17
  setPlaying: missingSetTimelineContext,
18
18
  setBuffering: missingSetTimelineContext,
19
19
  subscribePlaying: () => () => undefined,
@@ -88,7 +88,7 @@ const TimelineContextProvider = ({ children, frameState }) => {
88
88
  }, [playbackRate]);
89
89
  const setTimelineContextValue = (0, react_1.useMemo)(() => {
90
90
  return {
91
- setFrame,
91
+ setFrameWithoutSeek: setFrame,
92
92
  seek,
93
93
  setPlaying: (updater) => {
94
94
  const current = playingStore.store.getSnapshot().playing;
@@ -96,7 +96,7 @@ export type SvgPathFieldSchema = {
96
96
  type: 'svg-path';
97
97
  default: string | undefined;
98
98
  description?: string;
99
- keyframable?: false;
99
+ keyframable?: boolean;
100
100
  };
101
101
  export type FontFamilyFieldSchema = {
102
102
  type: 'font-family';
@@ -1027,7 +1027,7 @@ export declare const Internals: {
1027
1027
  }) => void;
1028
1028
  readonly usePlaybackRate: () => PlaybackRateContextValue;
1029
1029
  readonly useTimelineContext: () => TimelineContextValue;
1030
- readonly useTimelineSetFrame: () => (u: import("react").SetStateAction<Record<string, number>>) => void;
1030
+ readonly useTimelineSetFrameWithoutSeek: () => (u: import("react").SetStateAction<Record<string, number>>) => void;
1031
1031
  readonly isIosSafari: () => boolean;
1032
1032
  readonly WATCH_REMOTION_STATIC_FILES: "remotion_staticFilesChanged";
1033
1033
  readonly addSequenceStackTraces: (component: unknown) => void;
@@ -1239,6 +1239,17 @@ export declare const Internals: {
1239
1239
  forceSpringAllowTail: boolean | null;
1240
1240
  status: CanUpdateSequencePropStatusKeyframed;
1241
1241
  }) => string | number | readonly number[] | null;
1242
+ readonly setInterpolatePaths: (interpolator: (input: number, inputRange: readonly number[], outputRange: readonly string[], options: Pick<Partial<{
1243
+ easing: readonly import("./interpolate.js").EasingFunction[] | import("./interpolate.js").EasingFunction;
1244
+ extrapolateLeft: import("./interpolate.js").ExtrapolateType;
1245
+ extrapolateRight: import("./interpolate.js").ExtrapolateType;
1246
+ output: import("./interpolate.js").InterpolateOutputOption;
1247
+ outputType: import("./interpolate.js").InterpolateOutputType;
1248
+ posterize: number;
1249
+ }>, "easing" | "posterize"> & {
1250
+ extrapolateLeft: "clamp" | "extend" | "wrap";
1251
+ extrapolateRight: "clamp" | "extend" | "wrap";
1252
+ }) => string) => void;
1242
1253
  readonly makeStaticDragOverride: (value: unknown) => DragOverrideValue;
1243
1254
  readonly makeKeyframedDragOverride: ({ status, frame, value, defaultEasing, }: {
1244
1255
  status: CanUpdateSequencePropStatusKeyframed;
@@ -235,7 +235,7 @@ exports.Internals = {
235
235
  persistCurrentFrame: timeline_position_state_js_1.persistCurrentFrame,
236
236
  usePlaybackRate: timeline_position_state_js_1.usePlaybackRate,
237
237
  useTimelineContext: timeline_position_state_js_1.useTimelineContext,
238
- useTimelineSetFrame: timeline_position_state_js_1.useTimelineSetFrame,
238
+ useTimelineSetFrameWithoutSeek: timeline_position_state_js_1.useTimelineSetFrameWithoutSeek,
239
239
  isIosSafari: video_fragment_js_1.isIosSafari,
240
240
  WATCH_REMOTION_STATIC_FILES: watch_static_file_js_1.WATCH_REMOTION_STATIC_FILES,
241
241
  addSequenceStackTraces: enable_sequence_stack_traces_js_1.addSequenceStackTraces,
@@ -291,6 +291,7 @@ exports.Internals = {
291
291
  createWebGL2ContextError: webgl2_context_error_js_1.createWebGL2ContextError,
292
292
  computeEffectiveSchemaValuesDotNotation: use_schema_js_1.computeEffectiveSchemaValuesDotNotation,
293
293
  interpolateKeyframedStatus: interpolate_keyframed_status_js_1.interpolateKeyframedStatus,
294
+ setInterpolatePaths: interpolate_keyframed_status_js_1.setInterpolatePaths,
294
295
  makeStaticDragOverride: use_schema_js_1.makeStaticDragOverride,
295
296
  makeKeyframedDragOverride: use_schema_js_1.makeKeyframedDragOverride,
296
297
  resolveDragOverrideValue: get_effective_visual_mode_value_js_1.resolveDragOverrideValue,
@@ -1,5 +1,11 @@
1
+ import type { ExtrapolateType, InterpolateOptions } from './interpolate.js';
1
2
  import type { CanUpdateSequencePropStatusKeyframed } from './use-schema.js';
2
3
  type InterpolateKeyframedStatusResult = number | string | readonly number[] | null;
4
+ type PathInterpolator = (input: number, inputRange: readonly number[], outputRange: readonly string[], options: Pick<InterpolateOptions, 'easing' | 'posterize'> & {
5
+ extrapolateLeft: Exclude<ExtrapolateType, 'identity'>;
6
+ extrapolateRight: Exclude<ExtrapolateType, 'identity'>;
7
+ }) => string;
8
+ export declare const setInterpolatePaths: (interpolator: PathInterpolator) => void;
3
9
  export declare const interpolateKeyframedStatus: ({ frame, forceSpringAllowTail, status, }: {
4
10
  frame: number;
5
11
  forceSpringAllowTail: boolean | null;
@@ -1,10 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.interpolateKeyframedStatus = void 0;
3
+ exports.interpolateKeyframedStatus = exports.setInterpolatePaths = void 0;
4
4
  const bezier_js_1 = require("./bezier.js");
5
5
  const easing_js_1 = require("./easing.js");
6
6
  const interpolate_colors_js_1 = require("./interpolate-colors.js");
7
7
  const interpolate_js_1 = require("./interpolate.js");
8
+ // Studio supplies the path interpolator to avoid a dependency from remotion
9
+ // to @remotion/paths, which itself uses remotion's interpolation timing.
10
+ let interpolatePaths = null;
11
+ const setInterpolatePaths = (interpolator) => {
12
+ interpolatePaths = interpolator;
13
+ };
14
+ exports.setInterpolatePaths = setInterpolatePaths;
8
15
  const easingToFn = ({ easing, forceSpringAllowTail, }) => {
9
16
  var _a, _b;
10
17
  switch (easing.type) {
@@ -35,6 +42,30 @@ const interpolateKeyframedStatus = ({ frame, forceSpringAllowTail, status, }) =>
35
42
  const sortedKeyframes = [...keyframes].sort((a, b) => a.frame - b.frame);
36
43
  const inputRange = sortedKeyframes.map((k) => k.frame);
37
44
  const outputs = sortedKeyframes.map((k) => k.value);
45
+ if (interpolationFunction === 'interpolatePaths') {
46
+ if (!outputs.every((v) => typeof v === 'string')) {
47
+ return null;
48
+ }
49
+ if (keyframes.length === 1) {
50
+ return outputs[0];
51
+ }
52
+ if (!interpolatePaths ||
53
+ clamping.left === 'identity' ||
54
+ clamping.right === 'identity') {
55
+ return null;
56
+ }
57
+ try {
58
+ return interpolatePaths(frame, inputRange, outputs, {
59
+ easing: easing.map((e) => easingToFn({ easing: e, forceSpringAllowTail })),
60
+ extrapolateLeft: clamping.left,
61
+ extrapolateRight: clamping.right,
62
+ posterize: status.posterize,
63
+ });
64
+ }
65
+ catch (_a) {
66
+ return null;
67
+ }
68
+ }
38
69
  if (interpolationFunction === 'interpolateColors') {
39
70
  if (!outputs.every((v) => typeof v === 'string')) {
40
71
  return null;
@@ -48,7 +79,7 @@ const interpolateKeyframedStatus = ({ frame, forceSpringAllowTail, status, }) =>
48
79
  posterize: status.posterize,
49
80
  });
50
81
  }
51
- catch (_a) {
82
+ catch (_b) {
52
83
  return null;
53
84
  }
54
85
  }
@@ -64,7 +95,7 @@ const interpolateKeyframedStatus = ({ frame, forceSpringAllowTail, status, }) =>
64
95
  posterize: status.posterize,
65
96
  });
66
97
  }
67
- catch (_b) {
98
+ catch (_c) {
68
99
  return null;
69
100
  }
70
101
  };
@@ -13,7 +13,7 @@ export declare const usePlaybackRate: () => PlaybackRateContextValue;
13
13
  export declare const useTimelinePosition: () => number;
14
14
  export declare const useIsInsideFreeze: () => boolean;
15
15
  export declare const useAbsoluteTimelinePosition: () => number;
16
- export declare const useTimelineSetFrame: () => (u: import("react").SetStateAction<Record<string, number>>) => void;
16
+ export declare const useTimelineSetFrameWithoutSeek: () => (u: import("react").SetStateAction<Record<string, number>>) => void;
17
17
  export declare const useTimelineSeekFrame: () => (frame: import("react").SetStateAction<Record<string, number>>) => void;
18
18
  export { usePlaying } from './use-playing.js';
19
19
  export { useBuffering } from './use-buffering.js';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useBuffering = exports.usePlaying = exports.useTimelineSeekFrame = exports.useTimelineSetFrame = exports.useAbsoluteTimelinePosition = exports.useIsInsideFreeze = exports.useTimelinePosition = exports.usePlaybackRate = exports.useTimelineContext = exports.clampFrameToCompositionRange = exports.getFrameForComposition = exports.getInitialFrameState = exports.persistCurrentFrame = void 0;
3
+ exports.useBuffering = exports.usePlaying = exports.useTimelineSeekFrame = exports.useTimelineSetFrameWithoutSeek = exports.useAbsoluteTimelinePosition = exports.useIsInsideFreeze = 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");
@@ -81,16 +81,17 @@ const useAbsoluteTimelinePosition = () => {
81
81
  return useTimelinePositionFromContext(state);
82
82
  };
83
83
  exports.useAbsoluteTimelinePosition = useAbsoluteTimelinePosition;
84
- const useTimelineSetFrame = () => {
85
- const { setFrame } = (0, react_1.useContext)(TimelineContext_js_1.SetTimelineContext);
86
- return setFrame;
84
+ // Playback and frame persistence only. Navigation must use useTimelineSeekFrame.
85
+ const useTimelineSetFrameWithoutSeek = () => {
86
+ const { setFrameWithoutSeek } = (0, react_1.useContext)(TimelineContext_js_1.SetTimelineContext);
87
+ return setFrameWithoutSeek;
87
88
  };
88
- exports.useTimelineSetFrame = useTimelineSetFrame;
89
- // Explicit navigation only. Playback and frame persistence must use setFrame.
89
+ exports.useTimelineSetFrameWithoutSeek = useTimelineSetFrameWithoutSeek;
90
+ // Explicit navigation only. Rendering and thumbnails have no seek revision.
90
91
  const useTimelineSeekFrame = () => {
91
92
  var _a;
92
- const { seek, setFrame } = (0, react_1.useContext)(TimelineContext_js_1.SetTimelineContext);
93
- return (_a = seek === null || seek === void 0 ? void 0 : seek.setFrame) !== null && _a !== void 0 ? _a : setFrame;
93
+ const { seek, setFrameWithoutSeek } = (0, react_1.useContext)(TimelineContext_js_1.SetTimelineContext);
94
+ return (_a = seek === null || seek === void 0 ? void 0 : seek.seekFrame) !== null && _a !== void 0 ? _a : setFrameWithoutSeek;
94
95
  };
95
96
  exports.useTimelineSeekFrame = useTimelineSeekFrame;
96
97
  const use_playing_js_1 = require("./use-playing.js");
@@ -61,7 +61,7 @@ export type CanUpdateSequencePropStatusClamping = {
61
61
  left: ExtrapolateType;
62
62
  right: ExtrapolateType;
63
63
  };
64
- export type CanUpdateSequencePropStatusInterpolationFunction = 'interpolate' | 'interpolateColors';
64
+ export type CanUpdateSequencePropStatusInterpolationFunction = 'interpolate' | 'interpolateColors' | 'interpolatePaths';
65
65
  export type CanUpdateSequencePropStatusComputed = {
66
66
  status: 'computed';
67
67
  };
@@ -1,6 +1,6 @@
1
1
  import type { RefObject, SetStateAction } from 'react';
2
2
  export type TimelineSeek = {
3
3
  readonly revision: RefObject<number>;
4
- readonly setFrame: (frame: SetStateAction<Record<string, number>>) => void;
4
+ readonly seekFrame: (frame: SetStateAction<Record<string, number>>) => void;
5
5
  };
6
6
  export declare const useTimelineSeek: (setFrame: (frame: SetStateAction<Record<string, number>>) => void) => TimelineSeek;
@@ -8,7 +8,7 @@ const useTimelineSeek = (setFrame) => {
8
8
  const revision = (0, react_1.useRef)(0);
9
9
  return (0, react_1.useMemo)(() => ({
10
10
  revision,
11
- setFrame: (frame) => {
11
+ seekFrame: (frame) => {
12
12
  // Even a same-frame seek is a boundary for the next media update.
13
13
  revision.current++;
14
14
  setFrame(frame);
@@ -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.528";
6
+ export declare const VERSION = "4.0.529";
@@ -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.528';
10
+ exports.VERSION = '4.0.529';
@@ -1537,7 +1537,7 @@ var Composition = (props) => {
1537
1537
  };
1538
1538
 
1539
1539
  // src/version.ts
1540
- var VERSION = "4.0.528";
1540
+ var VERSION = "4.0.529";
1541
1541
 
1542
1542
  // src/multiple-versions-warning.ts
1543
1543
  var checkMultipleRemotionVersions = () => {
@@ -1589,7 +1589,7 @@ import { useContext as useContext15, useMemo as useMemo10 } from "react";
1589
1589
  // src/timeline-position-state.ts
1590
1590
  var exports_timeline_position_state = {};
1591
1591
  __export(exports_timeline_position_state, {
1592
- useTimelineSetFrame: () => useTimelineSetFrame,
1592
+ useTimelineSetFrameWithoutSeek: () => useTimelineSetFrameWithoutSeek,
1593
1593
  useTimelineSeekFrame: () => useTimelineSeekFrame,
1594
1594
  useTimelinePosition: () => useTimelinePosition,
1595
1595
  useTimelineContext: () => useTimelineContext,
@@ -1648,7 +1648,7 @@ var useTimelineSeek = (setFrame) => {
1648
1648
  const revision = useRef2(0);
1649
1649
  return useMemo8(() => ({
1650
1650
  revision,
1651
- setFrame: (frame) => {
1651
+ seekFrame: (frame) => {
1652
1652
  revision.current++;
1653
1653
  setFrame(frame);
1654
1654
  }
@@ -1662,7 +1662,7 @@ var missingSetTimelineContext = () => {
1662
1662
  };
1663
1663
  var SetTimelineContext = createContext13({
1664
1664
  seek: null,
1665
- setFrame: missingSetTimelineContext,
1665
+ setFrameWithoutSeek: missingSetTimelineContext,
1666
1666
  setPlaying: missingSetTimelineContext,
1667
1667
  setBuffering: missingSetTimelineContext,
1668
1668
  subscribePlaying: () => () => {
@@ -1736,7 +1736,7 @@ var TimelineContextProvider = ({ children, frameState }) => {
1736
1736
  }, [playbackRate]);
1737
1737
  const setTimelineContextValue = useMemo9(() => {
1738
1738
  return {
1739
- setFrame,
1739
+ setFrameWithoutSeek: setFrame,
1740
1740
  seek,
1741
1741
  setPlaying: (updater) => {
1742
1742
  const current = playingStore.store.getSnapshot().playing;
@@ -1892,13 +1892,13 @@ var useAbsoluteTimelinePosition = () => {
1892
1892
  }
1893
1893
  return useTimelinePositionFromContext(state);
1894
1894
  };
1895
- var useTimelineSetFrame = () => {
1896
- const { setFrame } = useContext12(SetTimelineContext);
1897
- return setFrame;
1895
+ var useTimelineSetFrameWithoutSeek = () => {
1896
+ const { setFrameWithoutSeek } = useContext12(SetTimelineContext);
1897
+ return setFrameWithoutSeek;
1898
1898
  };
1899
1899
  var useTimelineSeekFrame = () => {
1900
- const { seek, setFrame } = useContext12(SetTimelineContext);
1901
- return seek?.setFrame ?? setFrame;
1900
+ const { seek, setFrameWithoutSeek } = useContext12(SetTimelineContext);
1901
+ return seek?.seekFrame ?? setFrameWithoutSeek;
1902
1902
  };
1903
1903
 
1904
1904
  // src/use-current-frame.ts
@@ -4765,6 +4765,10 @@ var interpolateColors = (input, inputRange, outputRange, options) => {
4765
4765
  };
4766
4766
 
4767
4767
  // src/interpolate-keyframed-status.ts
4768
+ var interpolatePaths = null;
4769
+ var setInterpolatePaths = (interpolator) => {
4770
+ interpolatePaths = interpolator;
4771
+ };
4768
4772
  var easingToFn = ({
4769
4773
  easing,
4770
4774
  forceSpringAllowTail
@@ -4801,6 +4805,27 @@ var interpolateKeyframedStatus = ({
4801
4805
  const sortedKeyframes = [...keyframes].sort((a2, b2) => a2.frame - b2.frame);
4802
4806
  const inputRange = sortedKeyframes.map((k) => k.frame);
4803
4807
  const outputs = sortedKeyframes.map((k) => k.value);
4808
+ if (interpolationFunction === "interpolatePaths") {
4809
+ if (!outputs.every((v) => typeof v === "string")) {
4810
+ return null;
4811
+ }
4812
+ if (keyframes.length === 1) {
4813
+ return outputs[0];
4814
+ }
4815
+ if (!interpolatePaths || clamping.left === "identity" || clamping.right === "identity") {
4816
+ return null;
4817
+ }
4818
+ try {
4819
+ return interpolatePaths(frame, inputRange, outputs, {
4820
+ easing: easing.map((e) => easingToFn({ easing: e, forceSpringAllowTail })),
4821
+ extrapolateLeft: clamping.left,
4822
+ extrapolateRight: clamping.right,
4823
+ posterize: status.posterize
4824
+ });
4825
+ } catch {
4826
+ return null;
4827
+ }
4828
+ }
4804
4829
  if (interpolationFunction === "interpolateColors") {
4805
4830
  if (!outputs.every((v) => typeof v === "string")) {
4806
4831
  return null;
@@ -10814,7 +10839,7 @@ import {
10814
10839
  useMemo as useMemo32,
10815
10840
  useRef as useRef24
10816
10841
  } from "react";
10817
- import { jsx as jsx27 } from "react/jsx-runtime";
10842
+ import { jsx as jsx27, jsxs as jsxs3 } from "react/jsx-runtime";
10818
10843
  var transferredOffscreenCanvases = new WeakMap;
10819
10844
  var getTransferredOffscreenCanvas = (canvas) => {
10820
10845
  const existing = transferredOffscreenCanvases.get(canvas);
@@ -10894,6 +10919,7 @@ var HtmlInCanvasContent = forwardRef9(({
10894
10919
  height,
10895
10920
  effects,
10896
10921
  children,
10922
+ canvasSiblings,
10897
10923
  onPaint,
10898
10924
  onInit,
10899
10925
  pixelDensity,
@@ -11135,16 +11161,19 @@ var HtmlInCanvasContent = forwardRef9(({
11135
11161
  }, [height, style, width]);
11136
11162
  return /* @__PURE__ */ jsx27(HtmlInCanvasAncestorContext.Provider, {
11137
11163
  value: true,
11138
- children: /* @__PURE__ */ jsx27("canvas", {
11164
+ children: /* @__PURE__ */ jsxs3("canvas", {
11139
11165
  ref: setLayoutCanvasRef,
11140
11166
  width: canvasWidth,
11141
11167
  height: canvasHeight,
11142
11168
  style: canvasStyle,
11143
- children: /* @__PURE__ */ jsx27("div", {
11144
- ref: divRef,
11145
- style: innerStyle,
11146
- children
11147
- })
11169
+ children: [
11170
+ /* @__PURE__ */ jsx27("div", {
11171
+ ref: divRef,
11172
+ style: innerStyle,
11173
+ children
11174
+ }),
11175
+ canvasSiblings
11176
+ ]
11148
11177
  }, canvasSizeKey)
11149
11178
  });
11150
11179
  });
@@ -11157,6 +11186,7 @@ var HtmlInCanvasInner = forwardRef9(({
11157
11186
  onPaint,
11158
11187
  onInit,
11159
11188
  pixelDensity,
11189
+ _remotionInternalCanvasSiblings,
11160
11190
  controls,
11161
11191
  style,
11162
11192
  cropLeft,
@@ -11231,6 +11261,7 @@ var HtmlInCanvasInner = forwardRef9(({
11231
11261
  onPaint,
11232
11262
  onInit,
11233
11263
  pixelDensity,
11264
+ canvasSiblings: _remotionInternalCanvasSiblings ?? null,
11234
11265
  controls,
11235
11266
  style: croppedStyle ?? undefined,
11236
11267
  children
@@ -12316,7 +12347,7 @@ var interactiveSvgPathElementSchema = {
12316
12347
  type: "svg-path",
12317
12348
  default: undefined,
12318
12349
  description: "Path",
12319
- keyframable: false
12350
+ keyframable: true
12320
12351
  }
12321
12352
  };
12322
12353
  var interactiveSvgStrokeElementSchema = {
@@ -14233,7 +14264,7 @@ var Internals = {
14233
14264
  persistCurrentFrame,
14234
14265
  usePlaybackRate,
14235
14266
  useTimelineContext,
14236
- useTimelineSetFrame,
14267
+ useTimelineSetFrameWithoutSeek,
14237
14268
  isIosSafari,
14238
14269
  WATCH_REMOTION_STATIC_FILES,
14239
14270
  addSequenceStackTraces,
@@ -14289,6 +14320,7 @@ var Internals = {
14289
14320
  createWebGL2ContextError,
14290
14321
  computeEffectiveSchemaValuesDotNotation,
14291
14322
  interpolateKeyframedStatus,
14323
+ setInterpolatePaths,
14292
14324
  makeStaticDragOverride,
14293
14325
  makeKeyframedDragOverride,
14294
14326
  resolveDragOverrideValue,
@@ -14329,7 +14361,7 @@ var flattenChildren = (children) => {
14329
14361
  };
14330
14362
 
14331
14363
  // src/series/index.tsx
14332
- import { jsx as jsx38, jsxs as jsxs3, Fragment } from "react/jsx-runtime";
14364
+ import { jsx as jsx38, jsxs as jsxs4, Fragment } from "react/jsx-runtime";
14333
14365
  var seriesSequenceSchema = {
14334
14366
  durationInFrames: Interactive.baseSchema.durationInFrames,
14335
14367
  name: Interactive.sequenceSchema.name,
@@ -14427,7 +14459,7 @@ var SeriesInner = (props2) => {
14427
14459
  });
14428
14460
  const currentStartFrame = startFrame + offset;
14429
14461
  const nextStartFrame = startFrame + durationInFramesProp + offset;
14430
- return /* @__PURE__ */ jsxs3(Fragment, {
14462
+ return /* @__PURE__ */ jsxs4(Fragment, {
14431
14463
  children: [
14432
14464
  /* @__PURE__ */ jsx38(SequenceWithoutSchemaWithRef, {
14433
14465
  ref,
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = "4.0.528";
2
+ var VERSION = "4.0.529";
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.528",
6
+ "version": "4.0.529",
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.5.4",
38
- "@remotion/eslint-config-internal": "4.0.528",
38
+ "@remotion/eslint-config-internal": "4.0.529",
39
39
  "eslint": "9.19.0",
40
40
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
41
41
  },