remotion 4.0.529 → 4.0.531

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 (73) hide show
  1. package/dist/cjs/AbsoluteFill.d.ts +1 -1
  2. package/dist/cjs/AbsoluteFill.js +10 -7
  3. package/dist/cjs/HtmlInCanvas.d.ts +36 -11
  4. package/dist/cjs/HtmlInCanvas.js +63 -17
  5. package/dist/cjs/Img.js +12 -9
  6. package/dist/cjs/Interactive.d.ts +21 -2
  7. package/dist/cjs/Interactive.js +68 -7
  8. package/dist/cjs/Sequence.d.ts +3 -2
  9. package/dist/cjs/Sequence.js +103 -32
  10. package/dist/cjs/SequenceManager.d.ts +4 -0
  11. package/dist/cjs/SequenceManager.js +6 -1
  12. package/dist/cjs/animated-image/AnimatedImage.d.ts +6 -0
  13. package/dist/cjs/animated-image/AnimatedImage.js +86 -16
  14. package/dist/cjs/audio/AudioForPreview.js +2 -3
  15. package/dist/cjs/audio/html5-audio.js +18 -6
  16. package/dist/cjs/audio/props.d.ts +5 -0
  17. package/dist/cjs/calculate-media-duration.d.ts +5 -0
  18. package/dist/cjs/calculate-media-duration.js +13 -1
  19. package/dist/cjs/canvas-image/CanvasImage.d.ts +0 -2
  20. package/dist/cjs/canvas-image/CanvasImage.js +10 -8
  21. package/dist/cjs/canvas-image/props.d.ts +0 -5
  22. package/dist/cjs/effects/Solid.js +8 -3
  23. package/dist/cjs/effects/canvas-pool.d.ts +5 -1
  24. package/dist/cjs/effects/canvas-pool.js +49 -1
  25. package/dist/cjs/effects/run-effect-chain.d.ts +1 -0
  26. package/dist/cjs/effects/run-effect-chain.js +40 -10
  27. package/dist/cjs/effects/use-effect-chain-state.js +12 -0
  28. package/dist/cjs/effects/use-memoized-effects.js +1 -1
  29. package/dist/cjs/enable-sequence-stack-traces.d.ts +11 -0
  30. package/dist/cjs/enable-sequence-stack-traces.js +24 -1
  31. package/dist/cjs/freeze.d.ts +2 -0
  32. package/dist/cjs/freeze.js +8 -3
  33. package/dist/cjs/get-effective-visual-mode-value.js +3 -2
  34. package/dist/cjs/index.d.ts +1 -1
  35. package/dist/cjs/index.js +2 -1
  36. package/dist/cjs/interactivity-schema.d.ts +13 -0
  37. package/dist/cjs/interactivity-schema.js +15 -1
  38. package/dist/cjs/internals.d.ts +39 -7
  39. package/dist/cjs/internals.js +15 -0
  40. package/dist/cjs/interpolate-keyframed-status.d.ts +1 -1
  41. package/dist/cjs/interpolate.d.ts +3 -1
  42. package/dist/cjs/interpolate.js +25 -5
  43. package/dist/cjs/loop/index.d.ts +1 -4
  44. package/dist/cjs/loop/index.js +16 -11
  45. package/dist/cjs/loop/loop-context.d.ts +5 -0
  46. package/dist/cjs/loop/loop-context.js +5 -0
  47. package/dist/cjs/nonce.d.ts +11 -0
  48. package/dist/cjs/nonce.js +42 -0
  49. package/dist/cjs/react-refresh-event.d.ts +2 -0
  50. package/dist/cjs/react-refresh-event.js +8 -0
  51. package/dist/cjs/resolve-sequence-duration.d.ts +8 -0
  52. package/dist/cjs/resolve-sequence-duration.js +18 -0
  53. package/dist/cjs/sequence-order-marker.d.ts +1 -0
  54. package/dist/cjs/sequence-outline.d.ts +11 -0
  55. package/dist/cjs/sequence-outline.js +35 -0
  56. package/dist/cjs/series/index.js +6 -1
  57. package/dist/cjs/use-media-in-timeline.d.ts +3 -5
  58. package/dist/cjs/use-media-in-timeline.js +11 -21
  59. package/dist/cjs/use-schema.d.ts +8 -2
  60. package/dist/cjs/use-schema.js +10 -1
  61. package/dist/cjs/use-sequence-registration.js +5 -3
  62. package/dist/cjs/version.d.ts +1 -1
  63. package/dist/cjs/version.js +1 -1
  64. package/dist/cjs/video/OffthreadVideo.js +21 -8
  65. package/dist/cjs/video/VideoForPreview.js +2 -3
  66. package/dist/cjs/video/html5-video.js +18 -6
  67. package/dist/cjs/video/props.d.ts +5 -0
  68. package/dist/cjs/with-interactivity-schema.d.ts +3 -0
  69. package/dist/cjs/with-interactivity-schema.js +10 -2
  70. package/dist/esm/index.mjs +991 -464
  71. package/dist/esm/no-react.mjs +19 -5
  72. package/dist/esm/version.mjs +1 -1
  73. package/package.json +2 -2
@@ -243,7 +243,7 @@ export declare const absoluteFillSchema: {
243
243
  readonly name: import("./interactivity-schema.js").HiddenFieldSchema;
244
244
  readonly showInTimeline: import("./interactivity-schema.js").HiddenFieldSchema;
245
245
  };
246
- export declare const AbsoluteFill: React.ComponentType<Omit<AbsoluteFillElementProps, "durationInFrames" | "freeze" | "from" | "hidden" | "name" | "playbackRate" | "showInTimeline" | "trimBefore"> & InteractiveBaseProps & InteractivePremountProps & {
246
+ export declare const AbsoluteFill: React.ComponentType<Omit<AbsoluteFillElementProps, "durationInFrames" | "freeze" | "from" | "hidden" | "loop" | "name" | "playbackRate" | "showInTimeline" | "trimBefore"> & InteractiveBaseProps & InteractivePremountProps & {
247
247
  /**
248
248
  * @deprecated For internal use only
249
249
  */
@@ -7,6 +7,7 @@ const AbsoluteFillElement_js_1 = require("./AbsoluteFillElement.js");
7
7
  const enable_sequence_stack_traces_js_1 = require("./enable-sequence-stack-traces.js");
8
8
  const freeze_js_1 = require("./freeze.js");
9
9
  const interactivity_schema_js_1 = require("./interactivity-schema.js");
10
+ const resolve_sequence_duration_js_1 = require("./resolve-sequence-duration.js");
10
11
  const Sequence_js_1 = require("./Sequence.js");
11
12
  const use_premounting_js_1 = require("./use-premounting.js");
12
13
  const use_unsafe_video_config_js_1 = require("./use-unsafe-video-config.js");
@@ -29,11 +30,15 @@ const setRef = (ref, value) => {
29
30
  ref.current = value;
30
31
  }
31
32
  };
32
- const AbsoluteFillWithTiming = ({ ref: callbackRef, outlineRef: refForOutline, from, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, trimBefore, playbackRate, freeze, durationInFrames, hidden, name, showInTimeline, stack, controls, children, ...divProps }) => {
33
+ const AbsoluteFillWithTiming = ({ ref: callbackRef, from, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, trimBefore, playbackRate, loop, freeze, durationInFrames, hidden, name, showInTimeline, stack, controls, children, ...divProps }) => {
33
34
  var _a;
34
35
  const { effectivePremountFor, effectivePostmountFor, freezeFrame, isPremountingOrPostmounting, premountingActive, postmountingActive, premountingStyle, } = (0, use_premounting_js_1.usePremounting)({
35
36
  from: from !== null && from !== void 0 ? from : 0,
36
- durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : Infinity,
37
+ durationInFrames: (0, resolve_sequence_duration_js_1.resolveSequenceDuration)({
38
+ durationInFrames,
39
+ playbackRate,
40
+ loop,
41
+ }),
37
42
  premountFor: premountFor !== null && premountFor !== void 0 ? premountFor : null,
38
43
  postmountFor: postmountFor !== null && postmountFor !== void 0 ? postmountFor : null,
39
44
  style: (_a = divProps.style) !== null && _a !== void 0 ? _a : null,
@@ -41,19 +46,17 @@ const AbsoluteFillWithTiming = ({ ref: callbackRef, outlineRef: refForOutline, f
41
46
  styleWhilePostmounted: styleWhilePostmounted !== null && styleWhilePostmounted !== void 0 ? styleWhilePostmounted : null,
42
47
  hideWhilePremounted: 'opacity',
43
48
  });
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 }) }) }));
49
+ return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, _remotionInternalIsPremounting: premountingActive, children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from !== null && from !== void 0 ? from : 0, trimBefore: trimBefore, playbackRate: playbackRate, loop: loop, freeze: freeze, durationInFrames: durationInFrames, 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", _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
50
  };
46
- const AbsoluteFillInner = ({ ref, from, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, trimBefore, playbackRate, freeze, durationInFrames, hidden, name, showInTimeline, stack, controls, children, ...divProps }) => {
51
+ const AbsoluteFillInner = ({ ref, from, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, trimBefore, playbackRate, loop, freeze, durationInFrames, hidden, name, showInTimeline, stack, controls, children, ...divProps }) => {
47
52
  const videoConfig = (0, use_unsafe_video_config_js_1.useUnsafeVideoConfig)();
48
- const refForOutline = (0, react_1.useRef)(null);
49
53
  const callbackRef = (0, react_1.useCallback)((element) => {
50
- refForOutline.current = element;
51
54
  setRef(ref, element);
52
55
  }, [ref]);
53
56
  if (videoConfig === null) {
54
57
  return hidden ? null : (jsx_runtime_1.jsx(AbsoluteFillElement_js_1.AbsoluteFillElement, { ref: callbackRef, ...divProps, children: children }));
55
58
  }
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 }));
59
+ return (jsx_runtime_1.jsx(AbsoluteFillWithTiming, { ...divProps, ref: callbackRef, from: from, premountFor: premountFor, postmountFor: postmountFor, styleWhilePremounted: styleWhilePremounted, styleWhilePostmounted: styleWhilePostmounted, trimBefore: trimBefore, playbackRate: playbackRate, loop: loop, freeze: freeze, durationInFrames: durationInFrames, hidden: hidden, name: name, showInTimeline: showInTimeline, stack: stack, controls: controls, children: children }));
57
60
  };
58
61
  /*
59
62
  * @description A helper component which renders an absolutely positioned <div> element with full width, height, and flex display suited for content layering.
@@ -3,24 +3,41 @@ import type { EffectsProp } from './effects/effect-types.js';
3
3
  import type { InteractiveBaseProps, InteractiveCropProps } from './Interactive.js';
4
4
  import type { AbsoluteFillLayout } from './Sequence.js';
5
5
  declare global {
6
+ interface DrawElementImageOptions {
7
+ preserveElementGeometry?: boolean;
8
+ }
9
+ interface WebGLCopyElementImageConfig {
10
+ sx?: GLfloat;
11
+ sy?: GLfloat;
12
+ swidth?: GLfloat;
13
+ sheight?: GLfloat;
14
+ width?: GLsizei;
15
+ height?: GLsizei;
16
+ }
17
+ interface UpdateElementGeometryOptions {
18
+ preserveHitTestOrder?: boolean;
19
+ clip?: DOMRectInit;
20
+ canvasTransform?: DOMMatrixInit;
21
+ }
6
22
  interface ElementImage {
7
23
  readonly width: number;
8
24
  readonly height: number;
9
25
  close(): void;
10
26
  }
11
27
  interface CanvasRenderingContext2D {
12
- drawElementImage(element: Element | ElementImage, dx: number, dy: number): DOMMatrix;
13
- drawElementImage(element: Element | ElementImage, dx: number, dy: number, dwidth: number, dheight: number): DOMMatrix;
14
- drawElementImage(element: Element | ElementImage, sx: number, sy: number, swidth: number, sheight: number, dx: number, dy: number): DOMMatrix;
15
- drawElementImage(element: Element | ElementImage, sx: number, sy: number, swidth: number, sheight: number, dx: number, dy: number, dwidth: number, dheight: number): DOMMatrix;
28
+ drawElementImage(element: Element | ElementImage, dx: number, dy: number, options?: DrawElementImageOptions): void;
29
+ drawElementImage(element: Element | ElementImage, dx: number, dy: number, dwidth: number, dheight: number, options?: DrawElementImageOptions): void;
30
+ drawElementImage(element: Element | ElementImage, sx: number, sy: number, swidth: number, sheight: number, dx: number, dy: number, options?: DrawElementImageOptions): void;
31
+ drawElementImage(element: Element | ElementImage, sx: number, sy: number, swidth: number, sheight: number, dx: number, dy: number, dwidth: number, dheight: number, options?: DrawElementImageOptions): void;
16
32
  }
17
33
  interface OffscreenCanvasRenderingContext2D {
18
- drawElementImage(element: Element | ElementImage, dx: number, dy: number): DOMMatrix;
19
- drawElementImage(element: Element | ElementImage, dx: number, dy: number, dwidth: number, dheight: number): DOMMatrix;
20
- drawElementImage(element: Element | ElementImage, sx: number, sy: number, swidth: number, sheight: number, dx: number, dy: number): DOMMatrix;
21
- drawElementImage(element: Element | ElementImage, sx: number, sy: number, swidth: number, sheight: number, dx: number, dy: number, dwidth: number, dheight: number): DOMMatrix;
34
+ drawElementImage(element: Element | ElementImage, dx: number, dy: number, options?: DrawElementImageOptions): void;
35
+ drawElementImage(element: Element | ElementImage, dx: number, dy: number, dwidth: number, dheight: number, options?: DrawElementImageOptions): void;
36
+ drawElementImage(element: Element | ElementImage, sx: number, sy: number, swidth: number, sheight: number, dx: number, dy: number, options?: DrawElementImageOptions): void;
37
+ drawElementImage(element: Element | ElementImage, sx: number, sy: number, swidth: number, sheight: number, dx: number, dy: number, dwidth: number, dheight: number, options?: DrawElementImageOptions): void;
22
38
  }
23
39
  interface WebGLRenderingContextBase {
40
+ texElementSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, element: Element | ElementImage, config?: WebGLCopyElementImageConfig): void;
24
41
  texElementImage2D(target: GLenum, level: GLint, internalformat: GLint, format: GLenum, type: GLenum, element: Element | ElementImage): void;
25
42
  texElementImage2D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, element: Element | ElementImage): void;
26
43
  texElementImage2D(target: GLenum, level: GLint, internalformat: GLint, sx: GLfloat, sy: GLfloat, swidth: GLfloat, sheight: GLfloat, format: GLenum, type: GLenum, element: Element | ElementImage): void;
@@ -30,11 +47,18 @@ declare global {
30
47
  paint: Event;
31
48
  }
32
49
  interface HTMLCanvasElement {
50
+ content: string;
33
51
  layoutSubtree?: boolean;
34
52
  onpaint: ((this: HTMLCanvasElement, ev: Event) => unknown) | null;
35
53
  requestPaint?(): void;
36
54
  captureElementImage(element: Element): ElementImage;
37
- getElementTransform(element: Element | ElementImage, drawTransform: DOMMatrix): DOMMatrix;
55
+ updateElementGeometry(element: Element | ElementImage, options?: UpdateElementGeometryOptions): void;
56
+ clearElementGeometry(element: Element | ElementImage): void;
57
+ getElementTransform(element: Element): DOMMatrix;
58
+ }
59
+ interface OffscreenCanvas {
60
+ updateElementGeometry(element: Element | ElementImage, options?: UpdateElementGeometryOptions): void;
61
+ clearElementGeometry(element: Element | ElementImage): void;
38
62
  }
39
63
  }
40
64
  export type HtmlInCanvasOnPaintParams = {
@@ -48,8 +72,9 @@ export type HtmlInCanvasOnPaintParams = {
48
72
  readonly pixelDensity: number;
49
73
  };
50
74
  export declare const isHtmlInCanvasSupported: () => boolean;
51
- /** Shown when {@link isHtmlInCanvasSupported} is false: APIs are absent (old Chrome and/or flag off). */
52
- export declare const HTML_IN_CANVAS_UNSUPPORTED_MESSAGE = "HTML in Canvas is not supported. Two common causes: Chrome is older than version 148 (update Chrome), or the HTML-in-Canvas flag is disabled at chrome://flags/#canvas-draw-element (enable it and restart Chrome).";
75
+ /** Generic fallback for consumers that cannot inspect the current browser. */
76
+ export declare const HTML_IN_CANVAS_UNSUPPORTED_MESSAGE = "HTML in Canvas requires Chrome 149 or newer with Canvas Draw Element enabled at chrome://flags/#canvas-draw-element.";
77
+ export declare const getHtmlInCanvasUnsupportedMessage: () => string;
53
78
  export type HtmlInCanvasOnPaint = (params: HtmlInCanvasOnPaintParams) => void | Promise<void>;
54
79
  export type HtmlInCanvasOnInitCleanup = () => void;
55
80
  export type HtmlInCanvasOnInit = (params: HtmlInCanvasOnPaintParams) => HtmlInCanvasOnInitCleanup | Promise<HtmlInCanvasOnInitCleanup>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HtmlInCanvas = exports.htmlInCanvasSchema = exports.HTML_IN_CANVAS_UNSUPPORTED_MESSAGE = exports.isHtmlInCanvasSupported = void 0;
3
+ exports.HtmlInCanvas = exports.htmlInCanvasSchema = exports.getHtmlInCanvasUnsupportedMessage = exports.HTML_IN_CANVAS_UNSUPPORTED_MESSAGE = exports.isHtmlInCanvasSupported = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const run_effect_chain_js_1 = require("./effects/run-effect-chain.js");
@@ -9,6 +9,7 @@ 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
10
  const freeze_js_1 = require("./freeze.js");
11
11
  const interactivity_schema_js_1 = require("./interactivity-schema.js");
12
+ const resolve_sequence_duration_js_1 = require("./resolve-sequence-duration.js");
12
13
  const Sequence_js_1 = require("./Sequence.js");
13
14
  const use_crop_style_js_1 = require("./use-crop-style.js");
14
15
  const use_delay_render_js_1 = require("./use-delay-render.js");
@@ -53,8 +54,43 @@ const isHtmlInCanvasSupported = () => {
53
54
  return cachedSupport;
54
55
  };
55
56
  exports.isHtmlInCanvasSupported = isHtmlInCanvasSupported;
56
- /** Shown when {@link isHtmlInCanvasSupported} is false: APIs are absent (old Chrome and/or flag off). */
57
- exports.HTML_IN_CANVAS_UNSUPPORTED_MESSAGE = 'HTML in Canvas is not supported. Two common causes: Chrome is older than version 148 (update Chrome), or the HTML-in-Canvas flag is disabled at chrome://flags/#canvas-draw-element (enable it and restart Chrome).';
57
+ /** Generic fallback for consumers that cannot inspect the current browser. */
58
+ exports.HTML_IN_CANVAS_UNSUPPORTED_MESSAGE = 'HTML in Canvas requires Chrome 149 or newer with Canvas Draw Element enabled at chrome://flags/#canvas-draw-element.';
59
+ const getHtmlInCanvasUnsupportedMessage = () => {
60
+ var _a;
61
+ if (typeof document === 'undefined') {
62
+ return `HTML in Canvas is unavailable because there is no browser document. ${exports.HTML_IN_CANVAS_UNSUPPORTED_MESSAGE}`;
63
+ }
64
+ const userAgent = typeof navigator === 'undefined' ? '' : navigator.userAgent;
65
+ const chromiumVersion = (_a = userAgent.match(/(?:Chrome|Chromium)\/(\d+)/)) === null || _a === void 0 ? void 0 : _a[1];
66
+ let browser = 'this browser';
67
+ if (userAgent.includes('Edg/')) {
68
+ browser = 'Microsoft Edge';
69
+ }
70
+ else if (userAgent.includes('Chromium/')) {
71
+ browser = 'Chromium';
72
+ }
73
+ else if (chromiumVersion) {
74
+ browser = 'Chrome';
75
+ }
76
+ else if (userAgent.includes('Firefox/')) {
77
+ browser = 'Firefox';
78
+ }
79
+ else if (userAgent.includes('Safari/')) {
80
+ browser = 'Safari';
81
+ }
82
+ if (chromiumVersion && Number(chromiumVersion) >= 149) {
83
+ const flagUrl = browser === 'Microsoft Edge'
84
+ ? 'edge://flags/#canvas-draw-element'
85
+ : 'chrome://flags/#canvas-draw-element';
86
+ return `HTML in Canvas is unavailable. Enable Canvas Draw Element at ${flagUrl} and fully restart ${browser}.`;
87
+ }
88
+ if (chromiumVersion) {
89
+ return `HTML in Canvas is not supported in ${browser} ${chromiumVersion}. Use a Chromium-based browser running version 149 or newer.`;
90
+ }
91
+ return `HTML in Canvas is not supported in ${browser}. Use Chrome 149 or newer.`;
92
+ };
93
+ exports.getHtmlInCanvasUnsupportedMessage = getHtmlInCanvasUnsupportedMessage;
58
94
  function assertHtmlInCanvasDimensions(width, height) {
59
95
  if (typeof width !== 'number' || typeof height !== 'number') {
60
96
  throw new Error(`HtmlInCanvas: \`width\` and \`height\` must be numbers. Received width=${String(width)}, height=${String(height)}.`);
@@ -89,14 +125,13 @@ const resizePaintTarget = ({ target, width, height, }) => {
89
125
  target.height = height;
90
126
  }
91
127
  };
92
- const defaultOnPaint = ({ canvas, element, elementImage, }) => {
128
+ const defaultOnPaint = ({ canvas, elementImage, }) => {
93
129
  const ctx = canvas.getContext('2d');
94
130
  if (!ctx) {
95
131
  throw new Error('Failed to acquire 2D context for <HtmlInCanvas> canvas');
96
132
  }
97
133
  ctx.reset();
98
- const transform = ctx.drawElementImage(elementImage, 0, 0);
99
- element.style.transform = transform.toString();
134
+ ctx.drawElementImage(elementImage, 0, 0);
100
135
  };
101
136
  /* eslint-enable react/require-default-props */
102
137
  const HtmlInCanvasAncestorContext = (0, react_1.createContext)(false);
@@ -115,7 +150,7 @@ const HtmlInCanvasContent = (0, react_1.forwardRef)(({ width, height, effects, c
115
150
  const canRetryMissingPaintRecord = !isRendering || isClientSideRendering;
116
151
  const usesDirectLayoutCanvas = onPaint === undefined && onInit === undefined;
117
152
  if (!(0, exports.isHtmlInCanvasSupported)()) {
118
- cancelRender(new Error(exports.HTML_IN_CANVAS_UNSUPPORTED_MESSAGE));
153
+ cancelRender(new Error((0, exports.getHtmlInCanvasUnsupportedMessage)()));
119
154
  }
120
155
  const canvas2dRef = (0, react_1.useRef)(null);
121
156
  const paintTargetRef = (0, react_1.useRef)(null);
@@ -258,14 +293,18 @@ const HtmlInCanvasContent = (0, react_1.forwardRef)(({ width, height, effects, c
258
293
  pixelDensity: resolvedPixelDensity,
259
294
  });
260
295
  }
261
- await (0, run_effect_chain_js_1.runEffectChain)({
262
- state: chainState.get(canvasWidth, canvasHeight),
263
- source: paintTarget,
264
- effects: effectsRef.current,
265
- output: paintTarget,
266
- width: canvasWidth,
267
- height: canvasHeight,
268
- });
296
+ // `null` once unmounted, e.g. when an async `onPaint` resolves late.
297
+ const state = chainState.get(canvasWidth, canvasHeight);
298
+ if (state) {
299
+ await (0, run_effect_chain_js_1.runEffectChain)({
300
+ state,
301
+ source: paintTarget,
302
+ effects: effectsRef.current,
303
+ output: paintTarget,
304
+ width: canvasWidth,
305
+ height: canvasHeight,
306
+ });
307
+ }
269
308
  }
270
309
  finally {
271
310
  elImage.close();
@@ -288,11 +327,14 @@ const HtmlInCanvasContent = (0, react_1.forwardRef)(({ width, height, effects, c
288
327
  // Default paint handlers draw synchronously on the layout canvas itself.
289
328
  // Custom handlers retain the transferred OffscreenCanvas API.
290
329
  (0, react_1.useLayoutEffect)(() => {
330
+ var _a;
291
331
  const placeholder = canvas2dRef.current;
292
332
  if (!placeholder) {
293
333
  throw new Error('Canvas not found');
294
334
  }
335
+ placeholder.setAttribute('content', 'drawable');
295
336
  placeholder.layoutSubtree = true;
337
+ (_a = divRef.current) === null || _a === void 0 ? void 0 : _a.setAttribute('drawable', '');
296
338
  const paintTarget = usesDirectLayoutCanvas
297
339
  ? placeholder
298
340
  : getTransferredOffscreenCanvas(placeholder);
@@ -379,7 +421,11 @@ const HtmlInCanvasInner = (0, react_1.forwardRef)(({ width, height, effects = []
379
421
  }, [ref]);
380
422
  const { effectivePremountFor, effectivePostmountFor, freezeFrame, isPremountingOrPostmounting, premountingActive, postmountingActive, premountingStyle, } = (0, use_premounting_js_1.usePremounting)({
381
423
  from: (_a = sequenceProps.from) !== null && _a !== void 0 ? _a : 0,
382
- durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : Infinity,
424
+ durationInFrames: (0, resolve_sequence_duration_js_1.resolveSequenceDuration)({
425
+ durationInFrames,
426
+ playbackRate: sequenceProps.playbackRate,
427
+ loop: sequenceProps.loop,
428
+ }),
383
429
  premountFor: premountFor !== null && premountFor !== void 0 ? premountFor : null,
384
430
  postmountFor: postmountFor !== null && postmountFor !== void 0 ? postmountFor : null,
385
431
  style: style !== null && style !== void 0 ? style : null,
@@ -395,7 +441,7 @@ const HtmlInCanvasInner = (0, react_1.forwardRef)(({ width, height, effects = []
395
441
  style: premountingStyle,
396
442
  componentName: '<HtmlInCanvas />',
397
443
  });
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 }) }) }));
444
+ return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, _remotionInternalIsPremounting: premountingActive, 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, ...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 }) }) }));
399
445
  });
400
446
  HtmlInCanvasInner.displayName = 'HtmlInCanvas';
401
447
  exports.htmlInCanvasSchema = {
package/dist/cjs/Img.js CHANGED
@@ -9,6 +9,7 @@ const freeze_js_1 = require("./freeze.js");
9
9
  const get_cross_origin_value_js_1 = require("./get-cross-origin-value.js");
10
10
  const interactivity_schema_js_1 = require("./interactivity-schema.js");
11
11
  const prefetch_js_1 = require("./prefetch.js");
12
+ const resolve_sequence_duration_js_1 = require("./resolve-sequence-duration.js");
12
13
  const Sequence_js_1 = require("./Sequence.js");
13
14
  const SequenceContext_js_1 = require("./SequenceContext.js");
14
15
  const truncate_src_for_label_js_1 = require("./truncate-src-for-label.js");
@@ -22,7 +23,7 @@ const with_interactivity_schema_js_1 = require("./with-interactivity-schema.js")
22
23
  function exponentialBackoff(errorCount) {
23
24
  return 1000 * 2 ** (errorCount - 1);
24
25
  }
25
- const ImgContent = ({ onError, onImageError, maxRetries = 2, src, pauseWhenLoading, delayRenderRetries, delayRenderTimeoutInMilliseconds, onImageFrame, crossOrigin, decoding, ref, refForOutline, ...props }) => {
26
+ const ImgContent = ({ onError, onImageError, maxRetries = 2, src, pauseWhenLoading, delayRenderRetries, delayRenderTimeoutInMilliseconds, onImageFrame, crossOrigin, decoding, ref, ...props }) => {
26
27
  const imageRef = (0, react_1.useRef)(null);
27
28
  const errors = (0, react_1.useRef)({});
28
29
  const { delayPlayback } = (0, use_buffer_state_js_1.useBufferState)();
@@ -34,14 +35,13 @@ const ImgContent = ({ onError, onImageError, maxRetries = 2, src, pauseWhenLoadi
34
35
  }
35
36
  const imageCallbackRef = (0, react_1.useCallback)((img) => {
36
37
  imageRef.current = img;
37
- refForOutline.current = img;
38
38
  if (typeof ref === 'function') {
39
39
  ref(img);
40
40
  }
41
41
  else if (ref) {
42
42
  ref.current = img;
43
43
  }
44
- }, [ref, refForOutline]);
44
+ }, [ref]);
45
45
  const actualSrc = (0, prefetch_js_1.usePreload)(src);
46
46
  const retryIn = (0, react_1.useCallback)((timeout) => {
47
47
  if (!imageRef.current) {
@@ -198,7 +198,7 @@ const ImgContent = ({ onError, onImageError, maxRetries = 2, src, pauseWhenLoadi
198
198
  // blocks frame rendering.
199
199
  return (jsx_runtime_1.jsx("img", { ...props, ref: imageCallbackRef, crossOrigin: crossOriginValue, onError: didGetError, decoding: isRendering ? 'sync' : decoding }));
200
200
  };
201
- const NativeImgInner = ({ hidden, name, showInTimeline, src, from, trimBefore, durationInFrames, freeze, premountFor, postmountFor, style, styleWhilePremounted, styleWhilePostmounted, cropLeft, cropRight, cropTop, cropBottom, controls, outlineRef: refForOutline, ...props }) => {
201
+ const NativeImgInner = ({ hidden, name, showInTimeline, src, from, trimBefore, loop, durationInFrames, freeze, premountFor, postmountFor, style, styleWhilePremounted, styleWhilePostmounted, cropLeft, cropRight, cropTop, cropBottom, controls, ...props }) => {
202
202
  if (!src) {
203
203
  throw new Error('No "src" prop was passed to <Img>.');
204
204
  }
@@ -208,7 +208,11 @@ const NativeImgInner = ({ hidden, name, showInTimeline, src, from, trimBefore, d
208
208
  }), [src]);
209
209
  const { effectivePostmountFor, effectivePremountFor, freezeFrame, isPremountingOrPostmounting, postmountingActive, premountingActive, premountingStyle, } = (0, use_premounting_js_1.usePremounting)({
210
210
  from: from !== null && from !== void 0 ? from : 0,
211
- durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : Infinity,
211
+ durationInFrames: (0, resolve_sequence_duration_js_1.resolveSequenceDuration)({
212
+ durationInFrames,
213
+ playbackRate: undefined,
214
+ loop,
215
+ }),
212
216
  premountFor: premountFor !== null && premountFor !== void 0 ? premountFor : null,
213
217
  postmountFor: postmountFor !== null && postmountFor !== void 0 ? postmountFor : null,
214
218
  style: style !== null && style !== void 0 ? style : null,
@@ -224,7 +228,7 @@ const NativeImgInner = ({ hidden, name, showInTimeline, src, from, trimBefore, d
224
228
  style: premountingStyle,
225
229
  componentName: '<Img />',
226
230
  });
227
- 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, durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : Infinity, freeze: freeze, _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/img", _remotionInternalIsMedia: isMedia, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, name: name !== null && name !== void 0 ? name : '<Img>', controls: controls, showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, hidden: hidden, outlineRef: refForOutline, children: jsx_runtime_1.jsx(ImgContent, { src: src, refForOutline: refForOutline, style: croppedStyle !== null && croppedStyle !== void 0 ? croppedStyle : undefined, ...props }) }) }));
231
+ return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, _remotionInternalIsPremounting: premountingActive, children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from !== null && from !== void 0 ? from : 0, trimBefore: trimBefore, loop: loop, durationInFrames: durationInFrames, freeze: freeze, _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/img", _remotionInternalIsMedia: isMedia, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, name: name !== null && name !== void 0 ? name : '<Img>', controls: controls, showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, hidden: hidden, children: jsx_runtime_1.jsx(ImgContent, { src: src, style: croppedStyle !== null && croppedStyle !== void 0 ? croppedStyle : undefined, ...props }) }) }));
228
232
  };
229
233
  const CanvasImageWithPrivateProps = index_js_1.CanvasImage;
230
234
  exports.imgSchema = {
@@ -283,10 +287,9 @@ const getFitFromObjectFit = (style) => {
283
287
  };
284
288
  const ImgInner = ({ effects = [], ref, hidden, name, showInTimeline, src, from, trimBefore, durationInFrames, freeze, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, controls, width, height, className, style, cropLeft, cropRight, cropTop, cropBottom, id, pauseWhenLoading, maxRetries, delayRenderRetries, delayRenderTimeoutInMilliseconds, onImageError, ...props }) => {
285
289
  var _a;
286
- const refForOutline = (0, react_1.useRef)(null);
287
290
  const shouldPauseWhenLoading = (0, v5_flag_js_1.resolveV5Default)(pauseWhenLoading);
288
291
  if (effects.length === 0) {
289
- return (jsx_runtime_1.jsx(NativeImgInner, { ...props, ref: ref, hidden: hidden, name: name, showInTimeline: showInTimeline, src: src, from: from, trimBefore: trimBefore, durationInFrames: durationInFrames, freeze: freeze, premountFor: premountFor, postmountFor: postmountFor, styleWhilePremounted: styleWhilePremounted, styleWhilePostmounted: styleWhilePostmounted, controls: controls, width: width, height: height, className: className, style: style, cropLeft: cropLeft, cropRight: cropRight, cropTop: cropTop, cropBottom: cropBottom, id: id, pauseWhenLoading: shouldPauseWhenLoading, maxRetries: maxRetries, delayRenderRetries: delayRenderRetries, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds, onImageError: onImageError, outlineRef: refForOutline }));
292
+ return (jsx_runtime_1.jsx(NativeImgInner, { ...props, ref: ref, hidden: hidden, name: name, showInTimeline: showInTimeline, src: src, from: from, trimBefore: trimBefore, durationInFrames: durationInFrames, freeze: freeze, premountFor: premountFor, postmountFor: postmountFor, styleWhilePremounted: styleWhilePremounted, styleWhilePostmounted: styleWhilePostmounted, controls: controls, width: width, height: height, className: className, style: style, cropLeft: cropLeft, cropRight: cropRight, cropTop: cropTop, cropBottom: cropBottom, id: id, pauseWhenLoading: shouldPauseWhenLoading, maxRetries: maxRetries, delayRenderRetries: delayRenderRetries, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds, onImageError: onImageError }));
290
293
  }
291
294
  if (!src) {
292
295
  throw new Error('No "src" prop was passed to <Img>.');
@@ -301,7 +304,7 @@ const ImgInner = ({ effects = [], ref, hidden, name, showInTimeline, src, from,
301
304
  const canvasHeight = typeof height === 'number' ? height : undefined;
302
305
  const canvasProps = props;
303
306
  const canvasFit = (_a = getFitFromObjectFit(style)) !== null && _a !== void 0 ? _a : 'fill';
304
- return (jsx_runtime_1.jsx(CanvasImageWithPrivateProps, { src: src, width: canvasWidth, height: canvasHeight, fit: canvasFit, effects: effects, className: className, style: style, cropLeft: cropLeft, cropRight: cropRight, cropTop: cropTop, cropBottom: cropBottom, id: id, onError: onImageError, pauseWhenLoading: shouldPauseWhenLoading, maxRetries: maxRetries, delayRenderRetries: delayRenderRetries, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds, from: from, trimBefore: trimBefore, durationInFrames: durationInFrames, freeze: freeze, premountFor: premountFor, postmountFor: postmountFor, styleWhilePremounted: styleWhilePremounted, styleWhilePostmounted: styleWhilePostmounted, hidden: hidden, name: name !== null && name !== void 0 ? name : '<Img>', showInTimeline: showInTimeline, _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/img", _remotionInternalCropComponentName: "<Img />", controls: controls, outlineRef: refForOutline, ...canvasProps }));
307
+ return (jsx_runtime_1.jsx(CanvasImageWithPrivateProps, { src: src, width: canvasWidth, height: canvasHeight, fit: canvasFit, effects: effects, className: className, style: style, cropLeft: cropLeft, cropRight: cropRight, cropTop: cropTop, cropBottom: cropBottom, id: id, onError: onImageError, pauseWhenLoading: shouldPauseWhenLoading, maxRetries: maxRetries, delayRenderRetries: delayRenderRetries, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds, from: from, trimBefore: trimBefore, durationInFrames: durationInFrames, freeze: freeze, premountFor: premountFor, postmountFor: postmountFor, styleWhilePremounted: styleWhilePremounted, styleWhilePostmounted: styleWhilePostmounted, hidden: hidden, name: name !== null && name !== void 0 ? name : '<Img>', showInTimeline: showInTimeline, _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/img", _remotionInternalCropComponentName: "<Img />", controls: controls, ...canvasProps }));
305
308
  };
306
309
  /*
307
310
  * @description Works just like a regular HTML img tag. When you use the <Img> tag, Remotion will ensure that the image is loaded before rendering the frame.
@@ -6,7 +6,7 @@ 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' | 'playbackRate' | 'freeze' | 'hidden' | 'name' | 'showInTimeline'>;
9
+ export type InteractiveBaseProps = Pick<SequenceProps, 'durationInFrames' | 'from' | 'trimBefore' | 'playbackRate' | 'loop' | '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'>;
@@ -14,6 +14,25 @@ type InteractiveManagedProps = InteractiveBaseProps & InteractiveCropProps & Int
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}`;
17
+ type NonIntrinsicComponent<Component extends React.ElementType> = Component & React.ComponentType<React.ComponentProps<Component>>;
18
+ type KeysOfUnion<Props> = Props extends unknown ? keyof Props : never;
19
+ type ComponentWithoutReservedProps<Component extends React.ElementType, ReservedKey extends PropertyKey> = NonIntrinsicComponent<Component> & (Extract<KeysOfUnion<React.ComponentPropsWithoutRef<Component>>, ReservedKey> extends never ? unknown : never);
20
+ type WithSchemaReservedKey = keyof InteractiveBaseProps | keyof InteractiveCropProps | keyof InteractivePremountProps | 'controls';
21
+ type IsAny<Value> = 0 extends 1 & Value ? true : false;
22
+ type StyleMemberAcceptsCssProperties<Style> = IsAny<Style> extends true ? true : Style extends unknown ? [Style] extends [null | undefined] ? false : Exclude<keyof React.CSSProperties, keyof Style> extends never ? React.CSSProperties extends Style ? true : false : false : never;
23
+ type StyleAcceptsCssProperties<Style> = true extends StyleMemberAcceptsCssProperties<Style> ? true : false;
24
+ type PropsBranchAcceptsStyle<Props> = Props extends unknown ? 'style' extends keyof Props ? StyleAcceptsCssProperties<Props[Extract<'style', keyof Props>]> : false : never;
25
+ type EveryPropsBranchAcceptsStyle<Props> = [Props] extends [never] ? false : false extends PropsBranchAcceptsStyle<Props> ? false : true;
26
+ type ComponentAcceptingStyle<Component extends React.ElementType, ReservedKey extends PropertyKey> = ComponentWithoutReservedProps<Component, ReservedKey> & (EveryPropsBranchAcceptsStyle<React.ComponentPropsWithoutRef<Component>> extends true ? unknown : never);
27
+ type WithSchema = {
28
+ <S extends InteractivitySchema, Component extends React.ElementType>(options: Omit<WithInteractivitySchemaOptions<S, React.ComponentPropsWithoutRef<Component>>, 'Component' | 'supportsEffects'> & {
29
+ readonly Component: ComponentAcceptingStyle<Component, WithSchemaReservedKey>;
30
+ readonly wrapInSequence: true;
31
+ }): React.FC<React.ComponentPropsWithRef<Component> & InteractiveBaseProps & InteractivePremountProps & InteractiveCropProps>;
32
+ <S extends InteractivitySchema, Props extends object>(options: WithInteractivitySchemaOptions<S, Props> & {
33
+ readonly wrapInSequence?: false;
34
+ }): React.ComponentType<Props>;
35
+ };
17
36
  /**
18
37
  * @description HTML and SVG elements that are registered in the Remotion Studio timeline and can be visually edited.
19
38
  */
@@ -573,7 +592,7 @@ export declare const Interactive: {
573
592
  };
574
593
  };
575
594
  };
576
- withSchema: <S extends InteractivitySchema, Props extends object>(options: WithInteractivitySchemaOptions<S, Props>) => React.ComponentType<Props>;
595
+ withSchema: WithSchema;
577
596
  _internalMakeRemotionComponentIdentity: ({ packageName, componentName, }: {
578
597
  readonly packageName: RemotionComponentIdentityPackage;
579
598
  readonly componentName: string;
@@ -36,9 +36,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.Interactive = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const react_1 = __importStar(require("react"));
39
+ const CompositionManagerContext_js_1 = require("./CompositionManagerContext.js");
39
40
  const enable_sequence_stack_traces_js_1 = require("./enable-sequence-stack-traces.js");
40
41
  const freeze_js_1 = require("./freeze.js");
41
42
  const interactivity_schema_js_1 = require("./interactivity-schema.js");
43
+ const resolve_sequence_duration_js_1 = require("./resolve-sequence-duration.js");
42
44
  const Sequence_js_1 = require("./Sequence.js");
43
45
  const use_crop_style_js_1 = require("./use-crop-style.js");
44
46
  const use_premounting_js_1 = require("./use-premounting.js");
@@ -113,17 +115,78 @@ const setRef = (ref, value) => {
113
115
  ref.current = value;
114
116
  }
115
117
  };
116
- const withSchema = (options) => {
117
- const Wrapped = (0, with_interactivity_schema_js_1.withInteractivitySchema)(options);
118
+ const withSchema = (untypedOptions) => {
119
+ const options = untypedOptions;
120
+ if (!options.wrapInSequence) {
121
+ const LegacyWrapped = (0, with_interactivity_schema_js_1.withInteractivitySchema)(options);
122
+ (0, enable_sequence_stack_traces_js_1.addSequenceStackTraces)(LegacyWrapped);
123
+ return LegacyWrapped;
124
+ }
125
+ const { Component, componentName, schema, wrapInSequence: _, ...rest } = options;
126
+ const ComponentWrappedInSequence = (0, react_1.forwardRef)((props, ref) => {
127
+ const { canvasContent, compositions } = (0, react_1.useContext)(CompositionManagerContext_js_1.CompositionManager);
128
+ // The render callback runs after the exported wrapper has been initialized.
129
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
130
+ const componentIdentity = (0, enable_sequence_stack_traces_js_1.resolveComponentIdentity)(Wrapped);
131
+ const isCurrentComposition = compositions.some((composition) => (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' &&
132
+ composition.id === canvasContent.compositionId &&
133
+ composition.componentFromProps === componentIdentity);
134
+ const { durationInFrames, from, trimBefore, playbackRate, loop, freeze, hidden, name, showInTimeline, controls, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, ...componentProps } = props;
135
+ const { cropLeft, cropRight, cropTop, cropBottom, style, ...componentPropsWithoutCropping } = componentProps;
136
+ const { effectivePremountFor, effectivePostmountFor, freezeFrame, isPremountingOrPostmounting, premountingActive, postmountingActive, premountingStyle, } = (0, use_premounting_js_1.usePremounting)({
137
+ from: from !== null && from !== void 0 ? from : 0,
138
+ durationInFrames: (0, resolve_sequence_duration_js_1.resolveSequenceDuration)({
139
+ durationInFrames,
140
+ playbackRate,
141
+ loop,
142
+ }),
143
+ premountFor: premountFor !== null && premountFor !== void 0 ? premountFor : null,
144
+ postmountFor: postmountFor !== null && postmountFor !== void 0 ? postmountFor : null,
145
+ style: style !== null && style !== void 0 ? style : null,
146
+ styleWhilePremounted: styleWhilePremounted !== null && styleWhilePremounted !== void 0 ? styleWhilePremounted : null,
147
+ styleWhilePostmounted: styleWhilePostmounted !== null && styleWhilePostmounted !== void 0 ? styleWhilePostmounted : null,
148
+ hideWhilePremounted: 'opacity',
149
+ });
150
+ const croppedStyle = (0, use_crop_style_js_1.useCropStyle)({
151
+ cropLeft,
152
+ cropRight,
153
+ cropTop,
154
+ cropBottom,
155
+ style: premountingStyle,
156
+ componentName,
157
+ });
158
+ return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, children: jsx_runtime_1.jsx(Sequence_js_1.SequenceWithoutSchema, { _remotionInternalSingleChildComponent: isCurrentComposition ? null : componentIdentity, layout: "none", durationInFrames: durationInFrames, from: from, trimBefore: trimBefore, playbackRate: playbackRate, loop: loop, freeze: freeze, hidden: hidden, name: name !== null && name !== void 0 ? name : componentName, showInTimeline: isCurrentComposition ? false : showInTimeline, controls: controls, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, children: react_1.default.createElement(Component, {
159
+ ...componentPropsWithoutCropping,
160
+ style: croppedStyle !== null && croppedStyle !== void 0 ? croppedStyle : undefined,
161
+ ref,
162
+ }) }) }));
163
+ });
164
+ const Wrapped = (0, with_interactivity_schema_js_1.withInteractivitySchema)({
165
+ ...rest,
166
+ Component: ComponentWrappedInSequence,
167
+ componentName,
168
+ schema: {
169
+ ...schema,
170
+ ...interactivity_schema_js_1.transformSchema,
171
+ ...interactivity_schema_js_1.baseSchema,
172
+ ...interactivity_schema_js_1.premountSchema,
173
+ ...interactivity_schema_js_1.cropSchema,
174
+ },
175
+ supportsEffects: false,
176
+ });
118
177
  (0, enable_sequence_stack_traces_js_1.addSequenceStackTraces)(Wrapped);
119
178
  return Wrapped;
120
179
  };
121
180
  const makeInteractiveElement = (tag, displayName, schema) => {
122
181
  const Inner = (0, react_1.forwardRef)((propsWithControls, ref) => {
123
- const { durationInFrames, from, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, trimBefore, playbackRate, freeze, hidden, name, showInTimeline, controls, cropLeft, cropRight, cropTop, cropBottom, style, ...props } = propsWithControls;
182
+ const { durationInFrames, from, premountFor, postmountFor, styleWhilePremounted, styleWhilePostmounted, trimBefore, playbackRate, loop, freeze, hidden, name, showInTimeline, controls, cropLeft, cropRight, cropTop, cropBottom, style, ...props } = propsWithControls;
124
183
  const { effectivePremountFor, effectivePostmountFor, freezeFrame, isPremountingOrPostmounting, premountingActive, postmountingActive, premountingStyle, } = (0, use_premounting_js_1.usePremounting)({
125
184
  from: from !== null && from !== void 0 ? from : 0,
126
- durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : Infinity,
185
+ durationInFrames: (0, resolve_sequence_duration_js_1.resolveSequenceDuration)({
186
+ durationInFrames,
187
+ playbackRate,
188
+ loop,
189
+ }),
127
190
  premountFor: premountFor !== null && premountFor !== void 0 ? premountFor : null,
128
191
  postmountFor: postmountFor !== null && postmountFor !== void 0 ? postmountFor : null,
129
192
  style: style !== null && style !== void 0 ? style : null,
@@ -139,12 +202,10 @@ const makeInteractiveElement = (tag, displayName, schema) => {
139
202
  style: premountingStyle,
140
203
  componentName: displayName,
141
204
  });
142
- const refForOutline = (0, react_1.useRef)(null);
143
205
  const callbackRef = (0, react_1.useCallback)((element) => {
144
- refForOutline.current = element;
145
206
  setRef(ref, element);
146
207
  }, [ref]);
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, {
208
+ return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, _remotionInternalIsPremounting: premountingActive, children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from !== null && from !== void 0 ? from : 0, trimBefore: trimBefore, playbackRate: playbackRate, loop: loop, durationInFrames: durationInFrames, 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", _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, children: react_1.default.createElement(tag, {
148
209
  ...props,
149
210
  style: croppedStyle !== null && croppedStyle !== void 0 ? croppedStyle : undefined,
150
211
  ref: callbackRef,
@@ -25,6 +25,7 @@ export type SequencePropsWithoutDuration = {
25
25
  readonly from?: number;
26
26
  readonly trimBefore?: number;
27
27
  readonly playbackRate?: number;
28
+ readonly loop?: boolean;
28
29
  readonly freeze?: number | null;
29
30
  readonly name?: string;
30
31
  readonly showInTimeline?: boolean;
@@ -74,8 +75,8 @@ export type SequencePropsWithoutDuration = {
74
75
  src: string;
75
76
  };
76
77
  /**
77
- * A React ref pointing to the element that Remotion Studio should use for
78
- * drawing the selection outline in the preview.
78
+ * @deprecated Remotion Studio discovers rendered elements automatically.
79
+ * Remove this prop.
79
80
  */
80
81
  readonly outlineRef?: React.RefObject<Element | null> | null;
81
82
  } & LayoutAndStyle;