remotion 4.0.526 → 4.0.528

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/cjs/AbsoluteFill.d.ts +29 -3
  2. package/dist/cjs/AbsoluteFill.js +19 -2
  3. package/dist/cjs/CompositionManager.d.ts +2 -0
  4. package/dist/cjs/HtmlInCanvas.d.ts +28 -2
  5. package/dist/cjs/HtmlInCanvas.js +17 -3
  6. package/dist/cjs/Img.d.ts +2 -2
  7. package/dist/cjs/Img.js +1 -1
  8. package/dist/cjs/Interactive.d.ts +20 -2
  9. package/dist/cjs/Interactive.js +30 -8
  10. package/dist/cjs/Sequence.d.ts +1 -0
  11. package/dist/cjs/Sequence.js +49 -18
  12. package/dist/cjs/SequenceContext.d.ts +5 -0
  13. package/dist/cjs/TimelineContext.d.ts +2 -0
  14. package/dist/cjs/TimelineContext.js +8 -1
  15. package/dist/cjs/animated-image/AnimatedImage.d.ts +9 -10
  16. package/dist/cjs/animated-image/AnimatedImage.js +1 -12
  17. package/dist/cjs/audio/AudioForPreview.js +1 -0
  18. package/dist/cjs/audio/AudioForRendering.js +11 -7
  19. package/dist/cjs/audio/html5-audio.js +14 -7
  20. package/dist/cjs/audio/use-audio-frame.d.ts +1 -0
  21. package/dist/cjs/audio/use-audio-frame.js +14 -2
  22. package/dist/cjs/calculate-media-duration.js +1 -2
  23. package/dist/cjs/canvas-image/CanvasImage.d.ts +1 -1
  24. package/dist/cjs/canvas-image/CanvasImage.js +1 -1
  25. package/dist/cjs/canvas-image/props.d.ts +1 -1
  26. package/dist/cjs/effects/Solid.d.ts +28 -2
  27. package/dist/cjs/effects/Solid.js +16 -3
  28. package/dist/cjs/freeze.js +11 -3
  29. package/dist/cjs/get-asset-file-name.js +7 -1
  30. package/dist/cjs/get-sequence-boundary-tolerance.d.ts +7 -0
  31. package/dist/cjs/get-sequence-boundary-tolerance.js +10 -0
  32. package/dist/cjs/index.d.ts +3 -3
  33. package/dist/cjs/interactivity-schema.d.ts +75 -1
  34. package/dist/cjs/interactivity-schema.js +21 -1
  35. package/dist/cjs/internals.d.ts +23 -2
  36. package/dist/cjs/internals.js +2 -0
  37. package/dist/cjs/interpolate.d.ts +5 -0
  38. package/dist/cjs/interpolate.js +85 -5
  39. package/dist/cjs/loop/index.d.ts +7 -1
  40. package/dist/cjs/loop/index.js +35 -9
  41. package/dist/cjs/no-react.d.ts +10 -1
  42. package/dist/cjs/series/index.d.ts +1 -1
  43. package/dist/cjs/series/index.js +1 -0
  44. package/dist/cjs/spring/spring-utils.js +15 -12
  45. package/dist/cjs/timeline-position-state.d.ts +1 -0
  46. package/dist/cjs/timeline-position-state.js +8 -1
  47. package/dist/cjs/use-current-frame.js +2 -1
  48. package/dist/cjs/use-media-in-timeline.d.ts +5 -2
  49. package/dist/cjs/use-media-in-timeline.js +78 -13
  50. package/dist/cjs/use-media-playback.js +8 -3
  51. package/dist/cjs/use-premounting.js +19 -5
  52. package/dist/cjs/use-timeline-seek.d.ts +6 -0
  53. package/dist/cjs/use-timeline-seek.js +18 -0
  54. package/dist/cjs/version.d.ts +1 -1
  55. package/dist/cjs/version.js +1 -1
  56. package/dist/cjs/video/OffthreadVideo.js +7 -1
  57. package/dist/cjs/video/OffthreadVideoForRendering.js +11 -8
  58. package/dist/cjs/video/VideoForPreview.js +1 -0
  59. package/dist/cjs/video/VideoForRendering.js +12 -10
  60. package/dist/cjs/video/html5-video.js +12 -7
  61. package/dist/esm/index.mjs +927 -477
  62. package/dist/esm/no-react.mjs +103 -17
  63. package/dist/esm/version.mjs +1 -1
  64. package/package.json +2 -2
  65. package/dist/cjs/nonce.d.ts +0 -11
  66. package/dist/cjs/nonce.js +0 -42
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { type AbsoluteFillElementProps } from './AbsoluteFillElement.js';
3
- import type { InteractiveBaseProps } from './Interactive.js';
4
- export type AbsoluteFillProps = Omit<AbsoluteFillElementProps, keyof InteractiveBaseProps> & InteractiveBaseProps & {
3
+ import type { InteractiveBaseProps, InteractivePremountProps } from './Interactive.js';
4
+ export type AbsoluteFillProps = Omit<AbsoluteFillElementProps, keyof InteractiveBaseProps> & InteractiveBaseProps & InteractivePremountProps & {
5
5
  /**
6
6
  * @deprecated For internal use only
7
7
  */
@@ -187,6 +187,23 @@ export declare const absoluteFillSchema: {
187
187
  readonly description: "Text";
188
188
  readonly keyframable: false;
189
189
  };
190
+ readonly premountFor: {
191
+ readonly type: "number";
192
+ readonly default: 0;
193
+ readonly description: "Premount For";
194
+ readonly min: 0;
195
+ readonly step: 1;
196
+ readonly hiddenFromList: false;
197
+ readonly keyframable: false;
198
+ };
199
+ readonly postmountFor: {
200
+ readonly type: "number";
201
+ readonly default: 0;
202
+ readonly min: 0;
203
+ readonly step: 1;
204
+ readonly hiddenFromList: true;
205
+ readonly keyframable: false;
206
+ };
190
207
  readonly durationInFrames: {
191
208
  readonly type: "number";
192
209
  readonly default: undefined;
@@ -207,6 +224,15 @@ export declare const absoluteFillSchema: {
207
224
  readonly step: 1;
208
225
  readonly hiddenFromList: true;
209
226
  };
227
+ readonly playbackRate: {
228
+ readonly type: "number";
229
+ readonly default: 1;
230
+ readonly min: 0.01;
231
+ readonly step: 0.1;
232
+ readonly description: "Playback rate";
233
+ readonly hiddenFromList: false;
234
+ readonly keyframable: false;
235
+ };
210
236
  readonly freeze: {
211
237
  readonly type: "number";
212
238
  readonly default: null;
@@ -217,7 +243,7 @@ export declare const absoluteFillSchema: {
217
243
  readonly name: import("./interactivity-schema.js").HiddenFieldSchema;
218
244
  readonly showInTimeline: import("./interactivity-schema.js").HiddenFieldSchema;
219
245
  };
220
- export declare const AbsoluteFill: React.ComponentType<Omit<AbsoluteFillElementProps, "durationInFrames" | "freeze" | "from" | "hidden" | "name" | "showInTimeline" | "trimBefore"> & InteractiveBaseProps & {
246
+ export declare const AbsoluteFill: React.ComponentType<Omit<AbsoluteFillElementProps, "durationInFrames" | "freeze" | "from" | "hidden" | "name" | "playbackRate" | "showInTimeline" | "trimBefore"> & InteractiveBaseProps & InteractivePremountProps & {
221
247
  /**
222
248
  * @deprecated For internal use only
223
249
  */
@@ -5,12 +5,15 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const AbsoluteFillElement_js_1 = require("./AbsoluteFillElement.js");
7
7
  const enable_sequence_stack_traces_js_1 = require("./enable-sequence-stack-traces.js");
8
+ const freeze_js_1 = require("./freeze.js");
8
9
  const interactivity_schema_js_1 = require("./interactivity-schema.js");
9
10
  const Sequence_js_1 = require("./Sequence.js");
11
+ const use_premounting_js_1 = require("./use-premounting.js");
10
12
  const use_unsafe_video_config_js_1 = require("./use-unsafe-video-config.js");
11
13
  const with_interactivity_schema_js_1 = require("./with-interactivity-schema.js");
12
14
  exports.absoluteFillSchema = {
13
15
  ...interactivity_schema_js_1.baseSchema,
16
+ ...interactivity_schema_js_1.premountSchema,
14
17
  ...interactivity_schema_js_1.transformSchema,
15
18
  ...interactivity_schema_js_1.backgroundSchema,
16
19
  ...interactivity_schema_js_1.borderSchema,
@@ -26,7 +29,21 @@ const setRef = (ref, value) => {
26
29
  ref.current = value;
27
30
  }
28
31
  };
29
- const AbsoluteFillInner = ({ ref, from, trimBefore, freeze, durationInFrames, hidden, name, showInTimeline, stack, controls, children, ...divProps }) => {
32
+ const AbsoluteFillWithTiming = ({ ref: callbackRef, outlineRef: refForOutline, from, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, trimBefore, playbackRate, freeze, durationInFrames, hidden, name, showInTimeline, stack, controls, children, ...divProps }) => {
33
+ var _a;
34
+ const { effectivePremountFor, effectivePostmountFor, freezeFrame, isPremountingOrPostmounting, premountingActive, postmountingActive, premountingStyle, } = (0, use_premounting_js_1.usePremounting)({
35
+ from: from !== null && from !== void 0 ? from : 0,
36
+ durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : Infinity,
37
+ premountFor: premountFor !== null && premountFor !== void 0 ? premountFor : null,
38
+ postmountFor: postmountFor !== null && postmountFor !== void 0 ? postmountFor : null,
39
+ style: (_a = divProps.style) !== null && _a !== void 0 ? _a : null,
40
+ styleWhilePremounted: styleWhilePremounted !== null && styleWhilePremounted !== void 0 ? styleWhilePremounted : null,
41
+ styleWhilePostmounted: styleWhilePostmounted !== null && styleWhilePostmounted !== void 0 ? styleWhilePostmounted : null,
42
+ hideWhilePremounted: 'opacity',
43
+ });
44
+ return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from !== null && from !== void 0 ? from : 0, trimBefore: trimBefore, playbackRate: playbackRate, freeze: freeze, durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : Infinity, hidden: hidden, name: name !== null && name !== void 0 ? name : '<AbsoluteFill>', showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, controls: controls, _remotionInternalStack: stack, _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/absolute-fill", outlineRef: refForOutline, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, children: jsx_runtime_1.jsx(AbsoluteFillElement_js_1.AbsoluteFillElement, { ref: callbackRef, ...divProps, style: premountingStyle !== null && premountingStyle !== void 0 ? premountingStyle : undefined, children: children }) }) }));
45
+ };
46
+ const AbsoluteFillInner = ({ ref, from, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, trimBefore, playbackRate, freeze, durationInFrames, hidden, name, showInTimeline, stack, controls, children, ...divProps }) => {
30
47
  const videoConfig = (0, use_unsafe_video_config_js_1.useUnsafeVideoConfig)();
31
48
  const refForOutline = (0, react_1.useRef)(null);
32
49
  const callbackRef = (0, react_1.useCallback)((element) => {
@@ -36,7 +53,7 @@ const AbsoluteFillInner = ({ ref, from, trimBefore, freeze, durationInFrames, hi
36
53
  if (videoConfig === null) {
37
54
  return hidden ? null : (jsx_runtime_1.jsx(AbsoluteFillElement_js_1.AbsoluteFillElement, { ref: callbackRef, ...divProps, children: children }));
38
55
  }
39
- return (jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from !== null && from !== void 0 ? from : 0, trimBefore: trimBefore, freeze: freeze, durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : Infinity, hidden: hidden, name: name !== null && name !== void 0 ? name : '<AbsoluteFill>', showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, controls: controls, _remotionInternalStack: stack, _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/absolute-fill", outlineRef: refForOutline, children: jsx_runtime_1.jsx(AbsoluteFillElement_js_1.AbsoluteFillElement, { ref: callbackRef, ...divProps, children: children }) }));
56
+ return (jsx_runtime_1.jsx(AbsoluteFillWithTiming, { ...divProps, ref: callbackRef, outlineRef: refForOutline, from: from, premountFor: premountFor, postmountFor: postmountFor, styleWhilePremounted: styleWhilePremounted, styleWhilePostmounted: styleWhilePostmounted, trimBefore: trimBefore, playbackRate: playbackRate, freeze: freeze, durationInFrames: durationInFrames, hidden: hidden, name: name, showInTimeline: showInTimeline, stack: stack, controls: controls, children: children }));
40
57
  };
41
58
  /*
42
59
  * @description A helper component which renders an absolutely positioned <div> element with full width, height, and flex display suited for content layering.
@@ -72,6 +72,8 @@ export type SequenceControls = SequenceRegistrationControls & {
72
72
  currentRuntimeValueDotNotation: RuntimeValueSnapshot;
73
73
  };
74
74
  export type TSequence = {
75
+ /** This sequence's clock multiplier; ancestor rates are applied by the timeline. */
76
+ sequencePlaybackRate: number;
75
77
  from: number;
76
78
  trimBefore: number | null;
77
79
  duration: number;
@@ -54,7 +54,7 @@ export type HtmlInCanvasOnPaint = (params: HtmlInCanvasOnPaintParams) => void |
54
54
  export type HtmlInCanvasOnInitCleanup = () => void;
55
55
  export type HtmlInCanvasOnInit = (params: HtmlInCanvasOnPaintParams) => HtmlInCanvasOnInitCleanup | Promise<HtmlInCanvasOnInitCleanup>;
56
56
  export type HtmlInCanvasPixelDensity = number;
57
- export type HtmlInCanvasProps = Omit<InteractiveBaseProps, 'children'> & InteractiveCropProps & Omit<AbsoluteFillLayout, 'layout' | 'styleWhilePostmounted' | 'postmountFor' | 'premountFor' | 'styleWhilePremounted'> & {
57
+ export type HtmlInCanvasProps = Omit<InteractiveBaseProps, 'children'> & InteractiveCropProps & Omit<AbsoluteFillLayout, 'layout'> & {
58
58
  readonly durationInFrames?: number;
59
59
  readonly width: number;
60
60
  readonly height: number;
@@ -176,6 +176,23 @@ export declare const htmlInCanvasSchema: {
176
176
  readonly default: "transparent";
177
177
  readonly description: "Color";
178
178
  };
179
+ readonly premountFor: {
180
+ readonly type: "number";
181
+ readonly default: 0;
182
+ readonly description: "Premount For";
183
+ readonly min: 0;
184
+ readonly step: 1;
185
+ readonly hiddenFromList: false;
186
+ readonly keyframable: false;
187
+ };
188
+ readonly postmountFor: {
189
+ readonly type: "number";
190
+ readonly default: 0;
191
+ readonly min: 0;
192
+ readonly step: 1;
193
+ readonly hiddenFromList: true;
194
+ readonly keyframable: false;
195
+ };
179
196
  readonly cropLeft: {
180
197
  readonly type: "number";
181
198
  readonly default: 0;
@@ -236,6 +253,15 @@ export declare const htmlInCanvasSchema: {
236
253
  readonly step: 1;
237
254
  readonly hiddenFromList: true;
238
255
  };
256
+ readonly playbackRate: {
257
+ readonly type: "number";
258
+ readonly default: 1;
259
+ readonly min: 0.01;
260
+ readonly step: 0.1;
261
+ readonly description: "Playback rate";
262
+ readonly hiddenFromList: false;
263
+ readonly keyframable: false;
264
+ };
239
265
  readonly freeze: {
240
266
  readonly type: "number";
241
267
  readonly default: null;
@@ -255,7 +281,7 @@ export declare const htmlInCanvasSchema: {
255
281
  readonly hiddenFromList: false;
256
282
  };
257
283
  };
258
- export declare const HtmlInCanvas: React.ForwardRefExoticComponent<Omit<InteractiveBaseProps, "children"> & InteractiveCropProps & Omit<AbsoluteFillLayout, "layout" | "postmountFor" | "premountFor" | "styleWhilePostmounted" | "styleWhilePremounted"> & {
284
+ export declare const HtmlInCanvas: React.ForwardRefExoticComponent<Omit<InteractiveBaseProps, "children"> & InteractiveCropProps & Omit<AbsoluteFillLayout, "layout"> & {
259
285
  readonly durationInFrames?: number | undefined;
260
286
  readonly width: number;
261
287
  readonly height: number;
@@ -7,10 +7,12 @@ const run_effect_chain_js_1 = require("./effects/run-effect-chain.js");
7
7
  const use_effect_chain_state_js_1 = require("./effects/use-effect-chain-state.js");
8
8
  const use_memoized_effects_js_1 = require("./effects/use-memoized-effects.js");
9
9
  const enable_sequence_stack_traces_js_1 = require("./enable-sequence-stack-traces.js");
10
+ const freeze_js_1 = require("./freeze.js");
10
11
  const interactivity_schema_js_1 = require("./interactivity-schema.js");
11
12
  const Sequence_js_1 = require("./Sequence.js");
12
13
  const use_crop_style_js_1 = require("./use-crop-style.js");
13
14
  const use_delay_render_js_1 = require("./use-delay-render.js");
15
+ const use_premounting_js_1 = require("./use-premounting.js");
14
16
  const use_remotion_environment_js_1 = require("./use-remotion-environment.js");
15
17
  const with_interactivity_schema_js_1 = require("./with-interactivity-schema.js");
16
18
  // `transferControlToOffscreen()` may only be called once per canvas — a second
@@ -361,7 +363,8 @@ const HtmlInCanvasContent = (0, react_1.forwardRef)(({ width, height, effects, c
361
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) }));
362
364
  });
363
365
  HtmlInCanvasContent.displayName = 'HtmlInCanvasContent';
364
- const HtmlInCanvasInner = (0, react_1.forwardRef)(({ width, height, effects = [], children, onPaint, onInit, pixelDensity, controls, style, cropLeft, cropRight, cropTop, cropBottom, durationInFrames, name, ...sequenceProps }, ref) => {
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
+ var _a;
365
368
  const memoizedEffectDefinitions = (0, use_memoized_effects_js_1.useMemoizedEffectDefinitions)(effects);
366
369
  const actualRef = (0, react_1.useRef)(null);
367
370
  const setCanvasRef = (0, react_1.useCallback)((node) => {
@@ -373,19 +376,30 @@ const HtmlInCanvasInner = (0, react_1.forwardRef)(({ width, height, effects = []
373
376
  ref.current = node;
374
377
  }
375
378
  }, [ref]);
379
+ const { effectivePremountFor, effectivePostmountFor, freezeFrame, isPremountingOrPostmounting, premountingActive, postmountingActive, premountingStyle, } = (0, use_premounting_js_1.usePremounting)({
380
+ from: (_a = sequenceProps.from) !== null && _a !== void 0 ? _a : 0,
381
+ durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : Infinity,
382
+ premountFor: premountFor !== null && premountFor !== void 0 ? premountFor : null,
383
+ postmountFor: postmountFor !== null && postmountFor !== void 0 ? postmountFor : null,
384
+ style: style !== null && style !== void 0 ? style : null,
385
+ styleWhilePremounted: styleWhilePremounted !== null && styleWhilePremounted !== void 0 ? styleWhilePremounted : null,
386
+ styleWhilePostmounted: styleWhilePostmounted !== null && styleWhilePostmounted !== void 0 ? styleWhilePostmounted : null,
387
+ hideWhilePremounted: 'opacity',
388
+ });
376
389
  const croppedStyle = (0, use_crop_style_js_1.useCropStyle)({
377
390
  cropLeft,
378
391
  cropRight,
379
392
  cropTop,
380
393
  cropBottom,
381
- style: style !== null && style !== void 0 ? style : null,
394
+ style: premountingStyle,
382
395
  componentName: '<HtmlInCanvas />',
383
396
  });
384
- return (jsx_runtime_1.jsx(Sequence_js_1.Sequence, { 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, layout: "none", ...sequenceProps, 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 }) }));
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 }) }) }));
385
398
  });
386
399
  HtmlInCanvasInner.displayName = 'HtmlInCanvas';
387
400
  exports.htmlInCanvasSchema = {
388
401
  ...interactivity_schema_js_1.baseSchema,
402
+ ...interactivity_schema_js_1.premountSchema,
389
403
  pixelDensity: {
390
404
  type: 'number',
391
405
  min: 1,
package/dist/cjs/Img.d.ts CHANGED
@@ -13,7 +13,7 @@ export type ImgProps = NativeImgProps & {
13
13
  readonly effects?: EffectsProp;
14
14
  readonly showInTimeline?: boolean;
15
15
  readonly name?: string;
16
- } & InteractiveBaseProps & InteractiveCropProps & InteractivePremountProps;
16
+ } & Omit<InteractiveBaseProps, 'playbackRate'> & InteractiveCropProps & InteractivePremountProps;
17
17
  export declare const imgSchema: {
18
18
  readonly 'style.transformOrigin': {
19
19
  readonly type: "transform-origin";
@@ -231,5 +231,5 @@ export declare const Img: React.ComponentType<NativeImgProps & {
231
231
  readonly effects?: EffectsProp | undefined;
232
232
  readonly showInTimeline?: boolean | undefined;
233
233
  readonly name?: string | undefined;
234
- } & InteractiveBaseProps & InteractiveCropProps & InteractivePremountProps>;
234
+ } & Omit<InteractiveBaseProps, "playbackRate"> & InteractiveCropProps & InteractivePremountProps>;
235
235
  export {};
package/dist/cjs/Img.js CHANGED
@@ -235,7 +235,7 @@ exports.imgSchema = {
235
235
  description: 'Source',
236
236
  keyframable: false,
237
237
  },
238
- ...interactivity_schema_js_1.baseSchema,
238
+ ...interactivity_schema_js_1.baseSchemaWithoutPlaybackRate,
239
239
  ...interactivity_schema_js_1.cropSchema,
240
240
  ...interactivity_schema_js_1.premountSchema,
241
241
  ...interactivity_schema_js_1.transformSchema,
@@ -6,11 +6,11 @@ type InteractiveHtmlTag = 'a' | 'article' | 'aside' | 'button' | 'code' | 'div'
6
6
  type InteractiveSvgTag = 'circle' | 'ellipse' | 'g' | 'line' | 'path' | 'rect' | 'svg' | 'text';
7
7
  type InteractiveTag = InteractiveHtmlTag | InteractiveSvgTag;
8
8
  type ElementForTag<Tag extends InteractiveTag> = Tag extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[Tag] : Tag extends keyof SVGElementTagNameMap ? SVGElementTagNameMap[Tag] : Element;
9
- export type InteractiveBaseProps = Pick<SequenceProps, 'durationInFrames' | 'from' | 'trimBefore' | 'freeze' | 'hidden' | 'name' | 'showInTimeline'>;
9
+ export type InteractiveBaseProps = Pick<SequenceProps, 'durationInFrames' | 'from' | 'trimBefore' | 'playbackRate' | 'freeze' | 'hidden' | 'name' | 'showInTimeline'>;
10
10
  export type InteractiveTransformProps = Pick<AbsoluteFillLayout, 'style'>;
11
11
  export type InteractiveCropProps = Pick<SequenceProps, 'cropLeft' | 'cropRight' | 'cropTop' | 'cropBottom'>;
12
12
  export type InteractivePremountProps = Pick<AbsoluteFillLayout, 'premountFor' | 'postmountFor' | 'styleWhilePremounted' | 'styleWhilePostmounted'>;
13
- type InteractiveManagedProps = InteractiveBaseProps & InteractiveCropProps;
13
+ type InteractiveManagedProps = InteractiveBaseProps & InteractiveCropProps & InteractivePremountProps;
14
14
  type InteractiveElementProps<Tag extends InteractiveTag> = Omit<React.ComponentPropsWithoutRef<Tag>, keyof InteractiveManagedProps> & InteractiveManagedProps;
15
15
  type InteractiveElementComponent<Tag extends InteractiveTag> = React.ComponentType<InteractiveElementProps<Tag> & React.RefAttributes<ElementForTag<Tag>>>;
16
16
  type RemotionComponentIdentityPackage = 'remotion' | `@remotion/${string}`;
@@ -39,6 +39,15 @@ export declare const Interactive: {
39
39
  readonly step: 1;
40
40
  readonly hiddenFromList: true;
41
41
  };
42
+ readonly playbackRate: {
43
+ readonly type: "number";
44
+ readonly default: 1;
45
+ readonly min: 0.01;
46
+ readonly step: 0.1;
47
+ readonly description: "Playback rate";
48
+ readonly hiddenFromList: false;
49
+ readonly keyframable: false;
50
+ };
42
51
  readonly freeze: {
43
52
  readonly type: "number";
44
53
  readonly default: null;
@@ -367,6 +376,15 @@ export declare const Interactive: {
367
376
  readonly step: 1;
368
377
  readonly hiddenFromList: true;
369
378
  };
379
+ readonly playbackRate: {
380
+ readonly type: "number";
381
+ readonly default: 1;
382
+ readonly min: 0.01;
383
+ readonly step: 0.1;
384
+ readonly description: "Playback rate";
385
+ readonly hiddenFromList: false;
386
+ readonly keyframable: false;
387
+ };
370
388
  readonly freeze: {
371
389
  readonly type: "number";
372
390
  readonly default: null;
@@ -37,9 +37,11 @@ exports.Interactive = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const react_1 = __importStar(require("react"));
39
39
  const enable_sequence_stack_traces_js_1 = require("./enable-sequence-stack-traces.js");
40
+ const freeze_js_1 = require("./freeze.js");
40
41
  const interactivity_schema_js_1 = require("./interactivity-schema.js");
41
42
  const Sequence_js_1 = require("./Sequence.js");
42
43
  const use_crop_style_js_1 = require("./use-crop-style.js");
44
+ const use_premounting_js_1 = require("./use-premounting.js");
43
45
  const with_interactivity_schema_js_1 = require("./with-interactivity-schema.js");
44
46
  const sourcePathToIdentityPrefix = (packageName) => {
45
47
  if (packageName === 'remotion') {
@@ -58,6 +60,7 @@ const makeRemotionComponentIdentity = ({ packageName, componentName, }) => {
58
60
  };
59
61
  const interactiveElementSchema = {
60
62
  ...interactivity_schema_js_1.baseSchema,
63
+ ...interactivity_schema_js_1.premountSchema,
61
64
  ...interactivity_schema_js_1.transformSchema,
62
65
  ...interactivity_schema_js_1.cropSchema,
63
66
  };
@@ -85,6 +88,15 @@ const interactiveSvgElementSchema = {
85
88
  ...interactiveElementSchema,
86
89
  ...interactivity_schema_js_1.svgPaintSchema,
87
90
  };
91
+ const interactiveSvgPathElementSchema = {
92
+ ...interactiveSvgElementSchema,
93
+ d: {
94
+ type: 'svg-path',
95
+ default: undefined,
96
+ description: 'Path',
97
+ keyframable: false,
98
+ },
99
+ };
88
100
  const interactiveSvgStrokeElementSchema = {
89
101
  ...interactiveElementSchema,
90
102
  ...interactivity_schema_js_1.svgStrokeSchema,
@@ -108,13 +120,23 @@ const withSchema = (options) => {
108
120
  };
109
121
  const makeInteractiveElement = (tag, displayName, schema) => {
110
122
  const Inner = (0, react_1.forwardRef)((propsWithControls, ref) => {
111
- const { durationInFrames, from, trimBefore, freeze, hidden, name, showInTimeline, controls, cropLeft, cropRight, cropTop, cropBottom, style, ...props } = propsWithControls;
123
+ const { durationInFrames, from, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, trimBefore, playbackRate, freeze, hidden, name, showInTimeline, controls, cropLeft, cropRight, cropTop, cropBottom, style, ...props } = propsWithControls;
124
+ const { effectivePremountFor, effectivePostmountFor, freezeFrame, isPremountingOrPostmounting, premountingActive, postmountingActive, premountingStyle, } = (0, use_premounting_js_1.usePremounting)({
125
+ from: from !== null && from !== void 0 ? from : 0,
126
+ durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : Infinity,
127
+ premountFor: premountFor !== null && premountFor !== void 0 ? premountFor : null,
128
+ postmountFor: postmountFor !== null && postmountFor !== void 0 ? postmountFor : null,
129
+ style: style !== null && style !== void 0 ? style : null,
130
+ styleWhilePremounted: styleWhilePremounted !== null && styleWhilePremounted !== void 0 ? styleWhilePremounted : null,
131
+ styleWhilePostmounted: styleWhilePostmounted !== null && styleWhilePostmounted !== void 0 ? styleWhilePostmounted : null,
132
+ hideWhilePremounted: 'opacity',
133
+ });
112
134
  const croppedStyle = (0, use_crop_style_js_1.useCropStyle)({
113
135
  cropLeft,
114
136
  cropRight,
115
137
  cropTop,
116
138
  cropBottom,
117
- style: style !== null && style !== void 0 ? style : null,
139
+ style: premountingStyle,
118
140
  componentName: displayName,
119
141
  });
120
142
  const refForOutline = (0, react_1.useRef)(null);
@@ -122,11 +144,11 @@ const makeInteractiveElement = (tag, displayName, schema) => {
122
144
  refForOutline.current = element;
123
145
  setRef(ref, element);
124
146
  }, [ref]);
125
- return (jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from !== null && from !== void 0 ? from : 0, trimBefore: trimBefore, durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : Infinity, freeze: freeze, hidden: hidden, name: name !== null && name !== void 0 ? name : displayName, showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, controls: controls, _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/interactive", outlineRef: refForOutline, children: react_1.default.createElement(tag, {
126
- ...props,
127
- style: croppedStyle !== null && croppedStyle !== void 0 ? croppedStyle : undefined,
128
- ref: callbackRef,
129
- }) }));
147
+ return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from !== null && from !== void 0 ? from : 0, trimBefore: trimBefore, playbackRate: playbackRate, durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : Infinity, freeze: freeze, hidden: hidden, name: name !== null && name !== void 0 ? name : displayName, showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, controls: controls, _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/interactive", outlineRef: refForOutline, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, children: react_1.default.createElement(tag, {
148
+ ...props,
149
+ style: croppedStyle !== null && croppedStyle !== void 0 ? croppedStyle : undefined,
150
+ ref: callbackRef,
151
+ }) }) }));
130
152
  });
131
153
  Inner.displayName = displayName;
132
154
  const Wrapped = withSchema({
@@ -194,7 +216,7 @@ exports.Interactive = {
194
216
  Nav: makeInteractiveTextElement('nav', '<Interactive.Nav>'),
195
217
  Ol: makeInteractiveTextElement('ol', '<Interactive.Ol>'),
196
218
  P: makeInteractiveTextElement('p', '<Interactive.P>'),
197
- Path: makeInteractiveSvgElement('path', '<Interactive.Path>'),
219
+ Path: makeInteractiveElement('path', '<Interactive.Path>', interactiveSvgPathElementSchema),
198
220
  Pre: makeInteractiveTextElement('pre', '<Interactive.Pre>'),
199
221
  Rect: makeInteractiveSvgElement('rect', '<Interactive.Rect>'),
200
222
  Section: makeInteractiveTextElement('section', '<Interactive.Section>'),
@@ -24,6 +24,7 @@ export type SequencePropsWithoutDuration = {
24
24
  readonly cropBottom?: number;
25
25
  readonly from?: number;
26
26
  readonly trimBefore?: number;
27
+ readonly playbackRate?: number;
27
28
  readonly freeze?: number | null;
28
29
  readonly name?: string;
29
30
  readonly showInTimeline?: boolean;
@@ -7,6 +7,7 @@ const react_1 = require("react");
7
7
  const AbsoluteFillElement_js_1 = require("./AbsoluteFillElement.js");
8
8
  const enable_sequence_stack_traces_js_1 = require("./enable-sequence-stack-traces.js");
9
9
  const freeze_js_1 = require("./freeze.js");
10
+ const get_sequence_boundary_tolerance_js_1 = require("./get-sequence-boundary-tolerance.js");
10
11
  const interactivity_schema_js_1 = require("./interactivity-schema.js");
11
12
  const sequence_crop_js_1 = require("./sequence-crop.js");
12
13
  const sequence_order_marker_js_1 = require("./sequence-order-marker.js");
@@ -21,11 +22,13 @@ const use_video_config_js_1 = require("./use-video-config.js");
21
22
  const v5_flag_js_1 = require("./v5-flag.js");
22
23
  const with_interactivity_schema_js_1 = require("./with-interactivity-schema.js");
23
24
  const EMPTY_EFFECTS = [];
24
- const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, freeze, durationInFrames = Infinity, children, name, height, width, showInTimeline = true, hidden = false, controls, _remotionInternalEffects, _remotionInternalLoopDisplay: loopDisplay, _remotionInternalStack: stack, _remotionInternalDocumentationLink: documentationLink, _remotionInternalSingleChildComponent: singleChildComponent, _remotionInternalPremountDisplay: premountDisplay, _remotionInternalPostmountDisplay: postmountDisplay, _remotionInternalIsMedia: isMedia, outlineRef: passedRefForOutline, cropLeft, cropRight, cropTop, cropBottom, ...other }, ref) => {
25
- var _a, _b, _c, _d;
25
+ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, playbackRate = 1, freeze, durationInFrames = Infinity, children, name, height, width, showInTimeline = true, hidden = false, controls, _remotionInternalEffects, _remotionInternalLoopDisplay: loopDisplay, _remotionInternalStack: stack, _remotionInternalDocumentationLink: documentationLink, _remotionInternalSingleChildComponent: singleChildComponent, _remotionInternalPremountDisplay: premountDisplay, _remotionInternalPostmountDisplay: postmountDisplay, _remotionInternalIsMedia: isMedia, outlineRef: passedRefForOutline, cropLeft, cropRight, cropTop, cropBottom, ...other }, ref) => {
26
+ var _a, _b, _c, _d, _e;
26
27
  const { layout = 'absolute-fill' } = other;
27
28
  const [id] = (0, react_1.useState)(() => String(Math.random()));
28
29
  const parentSequence = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext);
30
+ const parentPlaybackRate = (_a = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.playbackRate) !== null && _a !== void 0 ? _a : 1;
31
+ const cumulativePlaybackRate = parentPlaybackRate * playbackRate;
29
32
  const cumulatedFrom = parentSequence
30
33
  ? parentSequence.cumulatedFrom + parentSequence.relativeFrom
31
34
  : 0;
@@ -81,9 +84,21 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, freeze
81
84
  }
82
85
  }
83
86
  const absoluteFrame = (0, timeline_position_state_js_1.useTimelinePosition)();
87
+ const lastPlaybackRate = (0, react_1.useRef)({ playbackRate, frame: absoluteFrame });
88
+ if (typeof playbackRate !== 'number' ||
89
+ !Number.isFinite(playbackRate) ||
90
+ playbackRate <= 0) {
91
+ throw new TypeError(`The "playbackRate" prop of <Sequence /> must be a positive finite number, but got ${playbackRate}.`);
92
+ }
93
+ if (lastPlaybackRate.current.frame !== absoluteFrame &&
94
+ lastPlaybackRate.current.playbackRate !== playbackRate) {
95
+ throw new Error('The "playbackRate" prop of <Sequence /> must be constant. Animating playbackRate is not supported.');
96
+ }
97
+ lastPlaybackRate.current = { playbackRate, frame: absoluteFrame };
84
98
  const videoConfig = (0, use_video_config_js_1.useVideoConfig)();
85
- const effectiveRelativeFrom = from - trimBefore;
86
- const absoluteFrom = ((_a = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.absoluteFrom) !== null && _a !== void 0 ? _a : 0) + effectiveRelativeFrom;
99
+ const effectiveRelativeFrom = from - trimBefore / playbackRate;
100
+ const relativeFrom = effectiveRelativeFrom / parentPlaybackRate;
101
+ const absoluteFrom = ((_b = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.absoluteFrom) !== null && _b !== void 0 ? _b : 0) + relativeFrom;
87
102
  const parentSequenceDuration = parentSequence
88
103
  ? Math.min(parentSequence.durationInFrames - effectiveRelativeFrom, durationInFrames)
89
104
  : durationInFrames;
@@ -116,23 +131,25 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, freeze
116
131
  // 10-frame pre-roll, because the positive child offset cancels part of the
117
132
  // negative parent offset. But <Sequence from={10}><Sequence from={-5}>
118
133
  // should still trim 5 frames from the media once the parent starts.
119
- const currentSequenceStart = cumulatedFrom + effectiveRelativeFrom;
134
+ const currentSequenceStart = cumulatedFrom + relativeFrom;
120
135
  const parentSequenceStart = parentSequence
121
136
  ? parentSequence.cumulatedFrom + parentSequence.relativeFrom
122
137
  : 0;
123
138
  const parentFirstFrame = parentSequence
124
- ? parentSequenceStart - parentSequence.cumulatedNegativeFrom
139
+ ? parentSequenceStart -
140
+ parentSequence.cumulatedNegativeFrom / parentPlaybackRate
125
141
  : 0;
126
- const firstFrame = Math.max(0, parentFirstFrame, currentSequenceStart);
127
- const cumulatedNegativeFrom = currentSequenceStart - firstFrame;
142
+ const firstFrame = Math.max(0, parentFirstFrame, cumulatedFrom + from / parentPlaybackRate);
143
+ const cumulatedNegativeFrom = (currentSequenceStart - firstFrame) * cumulativePlaybackRate;
128
144
  const contextValue = (0, react_1.useMemo)(() => {
129
145
  var _a, _b, _c;
130
146
  return {
147
+ playbackRate: cumulativePlaybackRate,
131
148
  absoluteFrom,
132
149
  cumulatedFrom,
133
- relativeFrom: effectiveRelativeFrom,
150
+ relativeFrom,
134
151
  cumulatedNegativeFrom,
135
- durationInFrames: actualDurationInFrames,
152
+ durationInFrames: actualDurationInFrames * playbackRate + trimBefore,
136
153
  parentFrom: (_a = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.relativeFrom) !== null && _a !== void 0 ? _a : 0,
137
154
  id,
138
155
  height: (_b = height !== null && height !== void 0 ? height : parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.height) !== null && _b !== void 0 ? _b : null,
@@ -145,7 +162,10 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, freeze
145
162
  }, [
146
163
  cumulatedFrom,
147
164
  absoluteFrom,
148
- effectiveRelativeFrom,
165
+ relativeFrom,
166
+ cumulativePlaybackRate,
167
+ playbackRate,
168
+ trimBefore,
149
169
  actualDurationInFrames,
150
170
  parentSequence,
151
171
  id,
@@ -167,11 +187,11 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, freeze
167
187
  // and if it changes, it would lead to-remounting of the sequence.
168
188
  const stackRef = (0, react_1.useRef)(null);
169
189
  stackRef.current = controls
170
- ? ((_c = (_b = (0, enable_sequence_stack_traces_js_1.getStackForControls)(controls)) !== null && _b !== void 0 ? _b : stack) !== null && _c !== void 0 ? _c : null)
190
+ ? ((_d = (_c = (0, enable_sequence_stack_traces_js_1.getStackForControls)(controls)) !== null && _c !== void 0 ? _c : stack) !== null && _d !== void 0 ? _d : null)
171
191
  : (stack !== null && stack !== void 0 ? stack : null);
172
192
  const registeredFrozenFrame = typeof freeze === 'number' ? freeze : null;
173
193
  const registeredTrimBefore = trimBefore === 0 ? null : trimBefore;
174
- const parentCumulatedNegativeFrom = (_d = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.cumulatedNegativeFrom) !== null && _d !== void 0 ? _d : 0;
194
+ const parentCumulatedNegativeFrom = (_e = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.cumulatedNegativeFrom) !== null && _e !== void 0 ? _e : 0;
175
195
  const startMediaFrom = isMedia && isMedia.type !== 'image'
176
196
  ? isMedia.data.startMediaFrom +
177
197
  parentCumulatedNegativeFrom -
@@ -233,6 +253,7 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, freeze
233
253
  if (isMedia) {
234
254
  if (isMedia.type === 'image') {
235
255
  return {
256
+ sequencePlaybackRate: playbackRate,
236
257
  type: 'image',
237
258
  controls: registrationControls,
238
259
  effects: _remotionInternalEffects !== null && _remotionInternalEffects !== void 0 ? _remotionInternalEffects : EMPTY_EFFECTS,
@@ -259,6 +280,7 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, freeze
259
280
  }
260
281
  return {
261
282
  type: isMedia.type,
283
+ sequencePlaybackRate: playbackRate,
262
284
  controls: registrationControls,
263
285
  effects: _remotionInternalEffects !== null && _remotionInternalEffects !== void 0 ? _remotionInternalEffects : EMPTY_EFFECTS,
264
286
  effectRuntimeValues,
@@ -291,6 +313,7 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, freeze
291
313
  }
292
314
  return {
293
315
  from,
316
+ sequencePlaybackRate: playbackRate,
294
317
  trimBefore: registeredTrimBefore,
295
318
  duration: actualDurationInFrames,
296
319
  id,
@@ -315,6 +338,7 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, freeze
315
338
  }, [
316
339
  id,
317
340
  timelineClipName,
341
+ playbackRate,
318
342
  parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.id,
319
343
  actualDurationInFrames,
320
344
  from,
@@ -342,12 +366,19 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, trimBefore = 0, freeze
342
366
  : null,
343
367
  id,
344
368
  });
345
- // Ceil to support floats
346
- // https://github.com/remotion-dev/remotion/issues/2958
347
- const endThreshold = Math.ceil(cumulatedFrom + from + durationInFrames - 1);
348
- const content = absoluteFrame < cumulatedFrom + from
369
+ // Use an exclusive end so fractional clocks and frozen subframes remain visible.
370
+ const frameInParent = (absoluteFrame - cumulatedFrom) * parentPlaybackRate;
371
+ const endThreshold = from + durationInFrames;
372
+ const boundaryTolerance = (0, get_sequence_boundary_tolerance_js_1.getSequenceBoundaryTolerance)({
373
+ absoluteFrame,
374
+ cumulatedFrom,
375
+ from,
376
+ parentPlaybackRate,
377
+ durationInFrames,
378
+ });
379
+ const content = frameInParent - from < -boundaryTolerance
349
380
  ? null
350
- : absoluteFrame > endThreshold
381
+ : frameInParent - endThreshold >= -boundaryTolerance
351
382
  ? null
352
383
  : children;
353
384
  const frozenContent = content === null || typeof freeze === 'undefined' || freeze === null ? (content) : (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freeze, children: content }));
@@ -1,10 +1,15 @@
1
1
  export declare const SequenceContext: import("react").Context<SequenceContextType | null>;
2
2
  export type SequenceContextType = {
3
+ /** Local frames elapsed per composition frame, including all ancestors. */
4
+ playbackRate: number;
5
+ /** Clock origins are expressed in composition frames. */
3
6
  absoluteFrom: number;
4
7
  cumulatedFrom: number;
8
+ /** Negative elapsed local frames at the first visible frame. */
5
9
  cumulatedNegativeFrom: number;
6
10
  relativeFrom: number;
7
11
  parentFrom: number;
12
+ /** Exclusive end of the local clock, including trimBefore. */
8
13
  durationInFrames: number;
9
14
  id: string;
10
15
  width: number | null;
@@ -1,6 +1,7 @@
1
1
  import type { RefObject } from 'react';
2
2
  import React from 'react';
3
3
  import { type PlayableMediaTag } from './timeline-position-state';
4
+ import { type TimelineSeek } from './use-timeline-seek';
4
5
  export type TimelineContextValue = {
5
6
  frame: Record<string, number>;
6
7
  isPlaying: () => boolean;
@@ -18,6 +19,7 @@ export type BufferingState = Readonly<{
18
19
  buffering: boolean;
19
20
  }>;
20
21
  export type SetTimelineContextValue = {
22
+ seek: TimelineSeek | null;
21
23
  setFrame: (u: React.SetStateAction<Record<string, number>>) => void;
22
24
  setPlaying: (u: React.SetStateAction<boolean>) => void;
23
25
  setBuffering: (buffering: boolean) => void;