remotion 4.0.464 → 4.0.466

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.
@@ -9,9 +9,14 @@ type State = {
9
9
  };
10
10
  export declare class CompositionErrorBoundary extends React.Component<Props, State> {
11
11
  state: State;
12
+ private hmrStatusHandler;
12
13
  static getDerivedStateFromError(): Partial<State>;
13
14
  componentDidCatch(error: Error): void;
14
- componentDidUpdate(_prevProps: Props): void;
15
+ componentDidMount(): void;
16
+ componentDidUpdate(_prevProps: Props, prevState: State): void;
17
+ componentWillUnmount(): void;
18
+ private subscribeToHmrReset;
19
+ private unsubscribeFromHmrReset;
15
20
  render(): React.ReactNode;
16
21
  }
17
22
  export {};
@@ -5,22 +5,86 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.CompositionErrorBoundary = void 0;
7
7
  const react_1 = __importDefault(require("react"));
8
+ const getHot = () => {
9
+ var _a;
10
+ try {
11
+ if (typeof __webpack_module__ === 'undefined') {
12
+ return null;
13
+ }
14
+ return (_a = __webpack_module__.hot) !== null && _a !== void 0 ? _a : null;
15
+ }
16
+ catch (_b) {
17
+ return null;
18
+ }
19
+ };
8
20
  class CompositionErrorBoundary extends react_1.default.Component {
9
21
  constructor() {
10
22
  super(...arguments);
11
23
  this.state = { hasError: false };
24
+ this.hmrStatusHandler = null;
12
25
  }
13
26
  static getDerivedStateFromError() {
14
27
  return { hasError: true };
15
28
  }
16
29
  componentDidCatch(error) {
17
30
  this.props.onError(error);
31
+ this.subscribeToHmrReset();
18
32
  }
19
- componentDidUpdate(_prevProps) {
33
+ componentDidMount() {
34
+ // A fresh boundary mounting in the success state means any stale
35
+ // `renderError` left over by a previous boundary instance should be
36
+ // cleared. Fast Refresh sometimes unmounts the old (errored) boundary
37
+ // and mounts a new one during `apply`, so `componentDidUpdate`'s
38
+ // error→success transition never fires.
20
39
  if (!this.state.hasError) {
21
40
  this.props.onClear();
22
41
  }
23
42
  }
43
+ componentDidUpdate(_prevProps, prevState) {
44
+ if (prevState.hasError && !this.state.hasError) {
45
+ this.props.onClear();
46
+ }
47
+ }
48
+ componentWillUnmount() {
49
+ this.unsubscribeFromHmrReset();
50
+ }
51
+ subscribeToHmrReset() {
52
+ if (this.hmrStatusHandler) {
53
+ return;
54
+ }
55
+ const hot = getHot();
56
+ if (!hot) {
57
+ return;
58
+ }
59
+ // Once the boundary catches a runtime error it returns `null` on every
60
+ // render and never retries the children — so any subsequent HMR fix
61
+ // would be invisible. While in the error state, wait for the next
62
+ // time webpack HMR settles (`idle`), drop the error flag, and let the
63
+ // boundary re-render. If the children still throw, `componentDidCatch`
64
+ // resubscribes. If they succeed, `componentDidUpdate` calls
65
+ // `onClear()`. See https://github.com/remotion-dev/remotion/issues/7447.
66
+ const handler = (status) => {
67
+ if (status !== 'idle') {
68
+ return;
69
+ }
70
+ this.unsubscribeFromHmrReset();
71
+ this.setState({ hasError: false });
72
+ };
73
+ this.hmrStatusHandler = handler;
74
+ hot.addStatusHandler(handler);
75
+ }
76
+ unsubscribeFromHmrReset() {
77
+ const handler = this.hmrStatusHandler;
78
+ if (!handler) {
79
+ return;
80
+ }
81
+ this.hmrStatusHandler = null;
82
+ const hot = getHot();
83
+ if (!hot) {
84
+ return;
85
+ }
86
+ hot.removeStatusHandler(handler);
87
+ }
24
88
  render() {
25
89
  if (this.state.hasError) {
26
90
  return null;
@@ -60,6 +60,7 @@ export type TSequence = {
60
60
  duration: number;
61
61
  id: string;
62
62
  displayName: string;
63
+ documentationLink: string | null;
63
64
  parent: string | null;
64
65
  rootId: string;
65
66
  showInTimeline: boolean;
@@ -51,11 +51,11 @@ export declare const HTML_IN_CANVAS_UNSUPPORTED_MESSAGE = "HTML in Canvas is not
51
51
  export type HtmlInCanvasOnPaint = (params: HtmlInCanvasOnPaintParams) => void | Promise<void>;
52
52
  export type HtmlInCanvasOnInitCleanup = () => void;
53
53
  export type HtmlInCanvasOnInit = (params: HtmlInCanvasOnPaintParams) => HtmlInCanvasOnInitCleanup | Promise<HtmlInCanvasOnInitCleanup>;
54
- export type HtmlInCanvasProps = Omit<SequenceProps, 'children' | 'durationInFrames' | keyof LayoutAndStyle | '_experimentalEffects'> & Omit<AbsoluteFillLayout, 'layout' | 'styleWhilePostmounted' | 'postmountFor' | 'premountFor' | 'styleWhilePremounted'> & {
54
+ export type HtmlInCanvasProps = Omit<SequenceProps, 'children' | 'durationInFrames' | keyof LayoutAndStyle | '_remotionInternalEffects'> & Omit<AbsoluteFillLayout, 'layout' | 'styleWhilePostmounted' | 'postmountFor' | 'premountFor' | 'styleWhilePremounted'> & {
55
55
  readonly durationInFrames?: number;
56
56
  readonly width: number;
57
57
  readonly height: number;
58
- readonly _experimentalEffects?: EffectsProp;
58
+ readonly effects?: EffectsProp;
59
59
  readonly children: React.ReactNode;
60
60
  readonly onPaint?: HtmlInCanvasOnPaint;
61
61
  readonly onInit?: HtmlInCanvasOnInit;
@@ -231,11 +231,13 @@ const HtmlInCanvasContent = (0, react_1.forwardRef)(({ width, height, effects, c
231
231
  return ((0, jsx_runtime_1.jsx)(HtmlInCanvasAncestorContext.Provider, { value: true, children: (0, jsx_runtime_1.jsx)("canvas", { ref: setLayoutCanvasRef, width: width, height: height, style: style, children: (0, jsx_runtime_1.jsx)("div", { ref: divRef, style: innerStyle, children: children }) }, canvasSizeKey) }));
232
232
  });
233
233
  HtmlInCanvasContent.displayName = 'HtmlInCanvasContent';
234
- const HtmlInCanvasInner = (0, react_1.forwardRef)(({ width, height, _experimentalEffects: effects = [], children, onPaint, onInit, _experimentalControls: controls, style, durationInFrames, name, ...sequenceProps }, ref) => {
234
+ const HtmlInCanvasInner = (0, react_1.forwardRef)(({ width, height, effects = [], children, onPaint, onInit, _experimentalControls: controls, style, durationInFrames, name, ...sequenceProps }, ref) => {
235
235
  const { durationInFrames: videoDuration } = (0, use_video_config_js_1.useVideoConfig)();
236
236
  const resolvedDuration = durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : videoDuration;
237
237
  const memoizedEffectDefinitions = (0, use_memoized_effects_js_1.useMemoizedEffectDefinitions)(effects);
238
- return ((0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { durationInFrames: resolvedDuration, name: name !== null && name !== void 0 ? name : '<HtmlInCanvas>', _experimentalControls: controls, _experimentalEffects: memoizedEffectDefinitions, layout: "none", ...sequenceProps, children: (0, jsx_runtime_1.jsx)(HtmlInCanvasContent, { ref: ref, width: width, height: height, effects: effects, onPaint: onPaint, onInit: onInit, controls: controls, style: style, children: children }) }));
238
+ return ((0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { durationInFrames: resolvedDuration, name: name !== null && name !== void 0 ? name : '<HtmlInCanvas>', _remotionInternalDocumentationLink: name === undefined
239
+ ? 'https://www.remotion.dev/docs/remotion/html-in-canvas'
240
+ : undefined, _experimentalControls: controls, _remotionInternalEffects: memoizedEffectDefinitions, layout: "none", ...sequenceProps, children: (0, jsx_runtime_1.jsx)(HtmlInCanvasContent, { ref: ref, width: width, height: height, effects: effects, onPaint: onPaint, onInit: onInit, controls: controls, style: style, children: children }) }));
239
241
  });
240
242
  HtmlInCanvasInner.displayName = 'HtmlInCanvas';
241
243
  const htmlInCanvasSchema = {
package/dist/cjs/Img.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { SequenceProps } from './Sequence.js';
2
3
  export declare function truncateSrcForLabel(src: string): string;
3
4
  type NativeImgProps = Omit<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, 'src'>;
4
5
  export type ImgProps = NativeImgProps & {
@@ -14,7 +15,7 @@ export type ImgProps = NativeImgProps & {
14
15
  * @deprecated For internal use only
15
16
  */
16
17
  readonly stack?: string;
17
- };
18
+ } & Pick<SequenceProps, 'durationInFrames' | 'from' | 'hidden'>;
18
19
  export declare const Img: React.ComponentType<NativeImgProps & {
19
20
  readonly maxRetries?: number;
20
21
  readonly pauseWhenLoading?: boolean;
@@ -28,5 +29,5 @@ export declare const Img: React.ComponentType<NativeImgProps & {
28
29
  * @deprecated For internal use only
29
30
  */
30
31
  readonly stack?: string;
31
- }>;
32
+ } & Pick<SequenceProps, "hidden" | "durationInFrames" | "from">>;
32
33
  export {};
package/dist/cjs/Img.js CHANGED
@@ -8,10 +8,10 @@ const enable_sequence_stack_traces_js_1 = require("./enable-sequence-stack-trace
8
8
  const get_cross_origin_value_js_1 = require("./get-cross-origin-value.js");
9
9
  const prefetch_js_1 = require("./prefetch.js");
10
10
  const sequence_field_schema_js_1 = require("./sequence-field-schema.js");
11
+ const Sequence_js_1 = require("./Sequence.js");
11
12
  const SequenceContext_js_1 = require("./SequenceContext.js");
12
13
  const use_buffer_state_js_1 = require("./use-buffer-state.js");
13
14
  const use_delay_render_js_1 = require("./use-delay-render.js");
14
- const use_media_in_timeline_js_1 = require("./use-media-in-timeline.js");
15
15
  const use_remotion_environment_js_1 = require("./use-remotion-environment.js");
16
16
  const wrap_in_schema_js_1 = require("./wrap-in-schema.js");
17
17
  function exponentialBackoff(errorCount) {
@@ -181,31 +181,11 @@ const ImgContent = ({ onError, maxRetries = 2, src, pauseWhenLoading, delayRende
181
181
  // src gets set once we've loaded and decoded the image.
182
182
  return ((0, jsx_runtime_1.jsx)("img", { ...props, ref: imageRef, crossOrigin: crossOriginValue, onError: didGetError, decoding: "sync" }));
183
183
  };
184
- const ImgInner = ({ hidden, name, stack, showInTimeline, src, _experimentalControls: controls, ...props }) => {
185
- var _a, _b;
186
- const sequenceContext = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext);
187
- const [timelineId] = (0, react_1.useState)(() => String(Math.random()));
184
+ const ImgInner = ({ hidden, name, stack, showInTimeline, src, from, durationInFrames, _experimentalControls: controls, ...props }) => {
188
185
  if (!src) {
189
186
  throw new Error('No "src" prop was passed to <Img>.');
190
187
  }
191
- const stackRef = (0, react_1.useRef)(null);
192
- stackRef.current = stack !== null && stack !== void 0 ? stack : null;
193
- const getStack = (0, react_1.useCallback)(() => stackRef.current, []);
194
- (0, use_media_in_timeline_js_1.useImageInTimeline)({
195
- src,
196
- displayName: name !== null && name !== void 0 ? name : null,
197
- id: timelineId,
198
- getStack,
199
- showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true,
200
- premountDisplay: (_a = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premountDisplay) !== null && _a !== void 0 ? _a : null,
201
- postmountDisplay: (_b = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmountDisplay) !== null && _b !== void 0 ? _b : null,
202
- loopDisplay: undefined,
203
- controls: controls !== null && controls !== void 0 ? controls : null,
204
- });
205
- if (hidden) {
206
- return null;
207
- }
208
- return (0, jsx_runtime_1.jsx)(ImgContent, { src: src, ...props });
188
+ return ((0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { layout: "none", from: from !== null && from !== void 0 ? from : 0, durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : Infinity, _remotionInternalStack: stack, _remotionInternalDocumentationLink: name === undefined ? 'https://www.remotion.dev/docs/img' : undefined, _remotionInternalIsMedia: { type: 'image', src }, name: name !== null && name !== void 0 ? name : '<Img>', _experimentalControls: controls, showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, hidden: hidden, children: (0, jsx_runtime_1.jsx)(ImgContent, { src: src, ...props }) }));
209
189
  };
210
190
  const imgSchema = {
211
191
  ...sequence_field_schema_js_1.sequenceVisualStyleSchema,
@@ -23,7 +23,7 @@ export type SequencePropsWithoutDuration = {
23
23
  readonly showInTimeline?: boolean;
24
24
  readonly hidden?: boolean;
25
25
  readonly _experimentalControls?: SequenceControls;
26
- readonly _experimentalEffects?: readonly EffectDefinition<unknown>[];
26
+ readonly _remotionInternalEffects?: readonly EffectDefinition<unknown>[];
27
27
  /**
28
28
  * @deprecated For internal use only.
29
29
  */
@@ -40,6 +40,10 @@ export type SequencePropsWithoutDuration = {
40
40
  * @deprecated For internal use only.
41
41
  */
42
42
  readonly _remotionInternalStack?: string;
43
+ /**
44
+ * @deprecated For internal use only.
45
+ */
46
+ readonly _remotionInternalDocumentationLink?: string;
43
47
  /**
44
48
  * @deprecated For internal use only.
45
49
  */
@@ -54,6 +58,9 @@ export type SequencePropsWithoutDuration = {
54
58
  readonly _remotionInternalIsMedia?: {
55
59
  type: 'video' | 'audio';
56
60
  data: BasicMediaInTimelineReturnType;
61
+ } | {
62
+ type: 'image';
63
+ src: string;
57
64
  };
58
65
  } & LayoutAndStyle;
59
66
  export type SequenceProps = {
@@ -18,7 +18,7 @@ const use_remotion_environment_js_1 = require("./use-remotion-environment.js");
18
18
  const use_video_config_js_1 = require("./use-video-config.js");
19
19
  const v5_flag_js_1 = require("./v5-flag.js");
20
20
  const wrap_in_schema_js_1 = require("./wrap-in-schema.js");
21
- const RegularSequenceRefForwardingFunction = ({ from = 0, durationInFrames = Infinity, children, name, height, width, showInTimeline = true, hidden = false, _experimentalControls: controls, _experimentalEffects, _remotionInternalLoopDisplay: loopDisplay, _remotionInternalStack: stack, _remotionInternalPremountDisplay: premountDisplay, _remotionInternalPostmountDisplay: postmountDisplay, _remotionInternalIsMedia: isMedia, ...other }, ref) => {
21
+ const RegularSequenceRefForwardingFunction = ({ from = 0, durationInFrames = Infinity, children, name, height, width, showInTimeline = true, hidden = false, _experimentalControls: controls, _remotionInternalEffects, _remotionInternalLoopDisplay: loopDisplay, _remotionInternalStack: stack, _remotionInternalDocumentationLink: documentationLink, _remotionInternalPremountDisplay: premountDisplay, _remotionInternalPostmountDisplay: postmountDisplay, _remotionInternalIsMedia: isMedia, ...other }, ref) => {
22
22
  var _a;
23
23
  const { layout = 'absolute-fill' } = other;
24
24
  const [id] = (0, react_1.useState)(() => String(Math.random()));
@@ -97,6 +97,7 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, durationInFrames = Inf
97
97
  const timelineClipName = (0, react_1.useMemo)(() => {
98
98
  return name !== null && name !== void 0 ? name : '';
99
99
  }, [name]);
100
+ const resolvedDocumentationLink = documentationLink !== null && documentationLink !== void 0 ? documentationLink : (name === undefined ? 'https://www.remotion.dev/docs/sequence' : null);
100
101
  const env = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
101
102
  const inheritedStack = (_a = other === null || other === void 0 ? void 0 : other.stack) !== null && _a !== void 0 ? _a : null;
102
103
  // Our assumption: Stack doesnt' change. After we symbolicate we assign it a nodePath
@@ -104,33 +105,57 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, durationInFrames = Inf
104
105
  const stackRef = (0, react_2.useRef)(null);
105
106
  stackRef.current = stack !== null && stack !== void 0 ? stack : inheritedStack;
106
107
  (0, react_1.useEffect)(() => {
107
- var _a, _b;
108
+ var _a, _b, _c;
108
109
  if (!env.isStudio) {
109
110
  return;
110
111
  }
111
112
  if (isMedia) {
112
- registerSequence({
113
- type: isMedia.type,
114
- controls: controls !== null && controls !== void 0 ? controls : null,
115
- effects: _experimentalEffects !== null && _experimentalEffects !== void 0 ? _experimentalEffects : [],
116
- displayName: timelineClipName,
117
- doesVolumeChange: isMedia.data.doesVolumeChange,
118
- duration: actualDurationInFrames,
119
- from,
120
- id,
121
- loopDisplay,
122
- nonce: nonce.get(),
123
- parent: (_a = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.id) !== null && _a !== void 0 ? _a : null,
124
- playbackRate: isMedia.data.playbackRate,
125
- postmountDisplay: postmountDisplay !== null && postmountDisplay !== void 0 ? postmountDisplay : null,
126
- premountDisplay: premountDisplay !== null && premountDisplay !== void 0 ? premountDisplay : null,
127
- rootId,
128
- showInTimeline,
129
- src: isMedia.data.src,
130
- getStack: () => stackRef.current,
131
- startMediaFrom: isMedia.data.startMediaFrom,
132
- volume: isMedia.data.volumes,
133
- });
113
+ if (isMedia.type === 'image') {
114
+ registerSequence({
115
+ type: 'image',
116
+ controls: controls !== null && controls !== void 0 ? controls : null,
117
+ effects: _remotionInternalEffects !== null && _remotionInternalEffects !== void 0 ? _remotionInternalEffects : [],
118
+ displayName: timelineClipName,
119
+ documentationLink: resolvedDocumentationLink,
120
+ duration: actualDurationInFrames,
121
+ from,
122
+ id,
123
+ loopDisplay,
124
+ nonce: nonce.get(),
125
+ parent: (_a = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.id) !== null && _a !== void 0 ? _a : null,
126
+ postmountDisplay: postmountDisplay !== null && postmountDisplay !== void 0 ? postmountDisplay : null,
127
+ premountDisplay: premountDisplay !== null && premountDisplay !== void 0 ? premountDisplay : null,
128
+ rootId,
129
+ showInTimeline,
130
+ src: isMedia.src,
131
+ getStack: () => stackRef.current,
132
+ });
133
+ }
134
+ else {
135
+ registerSequence({
136
+ type: isMedia.type,
137
+ controls: controls !== null && controls !== void 0 ? controls : null,
138
+ effects: _remotionInternalEffects !== null && _remotionInternalEffects !== void 0 ? _remotionInternalEffects : [],
139
+ displayName: timelineClipName,
140
+ documentationLink: resolvedDocumentationLink,
141
+ doesVolumeChange: isMedia.data.doesVolumeChange,
142
+ duration: actualDurationInFrames,
143
+ from,
144
+ id,
145
+ loopDisplay,
146
+ nonce: nonce.get(),
147
+ parent: (_b = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.id) !== null && _b !== void 0 ? _b : null,
148
+ playbackRate: isMedia.data.playbackRate,
149
+ postmountDisplay: postmountDisplay !== null && postmountDisplay !== void 0 ? postmountDisplay : null,
150
+ premountDisplay: premountDisplay !== null && premountDisplay !== void 0 ? premountDisplay : null,
151
+ rootId,
152
+ showInTimeline,
153
+ src: isMedia.data.src,
154
+ getStack: () => stackRef.current,
155
+ startMediaFrom: isMedia.data.startMediaFrom,
156
+ volume: isMedia.data.volumes,
157
+ });
158
+ }
134
159
  return () => {
135
160
  unregisterSequence(id);
136
161
  };
@@ -140,7 +165,8 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, durationInFrames = Inf
140
165
  duration: actualDurationInFrames,
141
166
  id,
142
167
  displayName: timelineClipName,
143
- parent: (_b = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.id) !== null && _b !== void 0 ? _b : null,
168
+ documentationLink: resolvedDocumentationLink,
169
+ parent: (_c = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.id) !== null && _c !== void 0 ? _c : null,
144
170
  type: 'sequence',
145
171
  rootId,
146
172
  showInTimeline,
@@ -150,7 +176,7 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, durationInFrames = Inf
150
176
  premountDisplay: premountDisplay !== null && premountDisplay !== void 0 ? premountDisplay : null,
151
177
  postmountDisplay: postmountDisplay !== null && postmountDisplay !== void 0 ? postmountDisplay : null,
152
178
  controls: controls !== null && controls !== void 0 ? controls : null,
153
- effects: _experimentalEffects !== null && _experimentalEffects !== void 0 ? _experimentalEffects : [],
179
+ effects: _remotionInternalEffects !== null && _remotionInternalEffects !== void 0 ? _remotionInternalEffects : [],
154
180
  });
155
181
  return () => {
156
182
  unregisterSequence(id);
@@ -173,8 +199,9 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, durationInFrames = Inf
173
199
  postmountDisplay,
174
200
  env.isStudio,
175
201
  controls,
176
- _experimentalEffects,
202
+ _remotionInternalEffects,
177
203
  isMedia,
204
+ resolvedDocumentationLink,
178
205
  ]);
179
206
  // Ceil to support floats
180
207
  // https://github.com/remotion-dev/remotion/issues/2958
@@ -2,9 +2,9 @@ import type React from 'react';
2
2
  import type { SequenceControls } from '../CompositionManager.js';
3
3
  import type { EffectsProp } from '../effects/effect-types.js';
4
4
  import type { RemotionAnimatedImageProps } from './props';
5
- export declare const AnimatedImage: React.ComponentType<Omit<import("../Sequence.js").SequenceProps, "children" | "layout" | "durationInFrames" | "_experimentalEffects"> & RemotionAnimatedImageProps & {
5
+ export declare const AnimatedImage: React.ComponentType<Omit<import("../Sequence.js").SequenceProps, "children" | "layout" | "durationInFrames" | "_remotionInternalEffects"> & RemotionAnimatedImageProps & {
6
6
  readonly durationInFrames?: number;
7
- readonly _experimentalEffects?: EffectsProp;
7
+ readonly effects?: EffectsProp;
8
8
  } & {
9
9
  readonly _experimentalControls?: SequenceControls | undefined;
10
10
  readonly ref?: React.Ref<HTMLCanvasElement>;
@@ -142,7 +142,7 @@ const AnimatedImageContent = (0, react_1.forwardRef)(({ src, width, height, onEr
142
142
  return ((0, jsx_runtime_1.jsx)(canvas_1.Canvas, { ref: ref, width: width, height: height, fit: fit, effects: memoizedEffects, ...props }));
143
143
  });
144
144
  AnimatedImageContent.displayName = 'AnimatedImageContent';
145
- const AnimatedImageInner = ({ src, width, height, onError, fit, playbackRate, loopBehavior, id, className, style, durationInFrames, _experimentalEffects: effects = [], _experimentalControls: controls, ref, ...sequenceProps }) => {
145
+ const AnimatedImageInner = ({ src, width, height, onError, fit, playbackRate, loopBehavior, id, className, style, durationInFrames, effects = [], _experimentalControls: controls, ref, ...sequenceProps }) => {
146
146
  const { durationInFrames: videoDuration } = (0, use_video_config_js_1.useVideoConfig)();
147
147
  const resolvedDuration = durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : videoDuration;
148
148
  const memoizedEffectDefinitions = (0, use_memoized_effects_js_1.useMemoizedEffectDefinitions)(effects);
@@ -158,7 +158,7 @@ const AnimatedImageInner = ({ src, width, height, onError, fit, playbackRate, lo
158
158
  className,
159
159
  style,
160
160
  };
161
- return ((0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { layout: "none", durationInFrames: resolvedDuration, name: "<AnimatedImage>", _experimentalControls: controls, _experimentalEffects: memoizedEffectDefinitions, ...sequenceProps, children: (0, jsx_runtime_1.jsx)(AnimatedImageContent, { ...animatedImageProps, ref: ref, effects: effects, controls: controls }) }));
161
+ return ((0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { layout: "none", durationInFrames: resolvedDuration, name: "<AnimatedImage>", _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/animatedimage", _experimentalControls: controls, _remotionInternalEffects: memoizedEffectDefinitions, ...sequenceProps, children: (0, jsx_runtime_1.jsx)(AnimatedImageContent, { ...animatedImageProps, ref: ref, effects: effects, controls: controls }) }));
162
162
  };
163
163
  exports.AnimatedImage = (0, wrap_in_schema_js_1.wrapInSchema)(AnimatedImageInner, animatedImageSchema);
164
164
  exports.AnimatedImage.displayName = 'AnimatedImage';
@@ -13,8 +13,8 @@ export type RemotionAnimatedImageProps = {
13
13
  id?: string;
14
14
  className?: string;
15
15
  };
16
- export type AnimatedImageProps = Omit<SequenceProps, 'children' | 'durationInFrames' | 'layout' | '_experimentalEffects'> & RemotionAnimatedImageProps & {
16
+ export type AnimatedImageProps = Omit<SequenceProps, 'children' | 'durationInFrames' | 'layout' | '_remotionInternalEffects'> & RemotionAnimatedImageProps & {
17
17
  readonly durationInFrames?: number;
18
- readonly _experimentalEffects?: EffectsProp;
18
+ readonly effects?: EffectsProp;
19
19
  };
20
20
  export type AnimatedImageFillMode = 'contain' | 'cover' | 'fill';
@@ -134,6 +134,7 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
134
134
  premountDisplay: (_a = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premountDisplay) !== null && _a !== void 0 ? _a : null,
135
135
  postmountDisplay: (_b = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmountDisplay) !== null && _b !== void 0 ? _b : null,
136
136
  loopDisplay: undefined,
137
+ documentationLink: name === undefined ? 'https://www.remotion.dev/docs/html5-audio' : null,
137
138
  });
138
139
  // putting playback before useVolume
139
140
  // because volume looks at playbackrate
@@ -7,7 +7,7 @@ type MandatoryProps = {
7
7
  };
8
8
  type OptionalProps = {
9
9
  readonly color: string | undefined;
10
- readonly _experimentalEffects: EffectsProp;
10
+ readonly effects: EffectsProp;
11
11
  readonly className: string | undefined;
12
12
  readonly style: React.CSSProperties | undefined;
13
13
  };
@@ -33,11 +33,11 @@ const solidSchema = {
33
33
  },
34
34
  ...sequence_field_schema_js_1.sequenceVisualStyleSchema,
35
35
  };
36
- const SolidInner = ({ color, width, height, _experimentalEffects: experimentalEffects = [], className, style, overrideId, ref, }) => {
36
+ const SolidInner = ({ color, width, height, effects = [], className, style, overrideId, ref, }) => {
37
37
  const { delayRender, continueRender, cancelRender } = (0, use_delay_render_js_1.useDelayRender)();
38
38
  const [outputCanvas, setOutputCanvas] = (0, react_1.useState)(null);
39
39
  const memoizedEffects = (0, use_memoized_effects_js_1.useMemoizedEffects)({
40
- effects: experimentalEffects,
40
+ effects,
41
41
  overrideId: overrideId !== null && overrideId !== void 0 ? overrideId : null,
42
42
  });
43
43
  const sourceCanvas = (0, react_1.useMemo)(() => {
@@ -114,11 +114,11 @@ const SolidInner = ({ color, width, height, _experimentalEffects: experimentalEf
114
114
  ]);
115
115
  return ((0, jsx_runtime_1.jsx)("canvas", { ref: canvasRef, width: width, height: height, className: className, style: style }));
116
116
  };
117
- const SolidOuter = (0, react_1.forwardRef)(({ _experimentalEffects = [], _experimentalControls: controls, color, height, width, className, durationInFrames, style, name, from, hidden, showInTimeline, ...props }, ref) => {
117
+ const SolidOuter = (0, react_1.forwardRef)(({ effects = [], _experimentalControls: controls, color, height, width, className, durationInFrames, style, name, from, hidden, showInTimeline, ...props }, ref) => {
118
118
  var _a;
119
119
  props;
120
- const memoizedEffectDefinitions = (0, use_memoized_effects_js_1.useMemoizedEffectDefinitions)(_experimentalEffects);
121
- return ((0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { layout: "none", from: from, hidden: hidden, showInTimeline: showInTimeline, _experimentalControls: controls, _experimentalEffects: memoizedEffectDefinitions, durationInFrames: durationInFrames, name: name !== null && name !== void 0 ? name : '<Solid>', ...props, children: (0, jsx_runtime_1.jsx)(SolidInner, { ref: ref, overrideId: (_a = controls === null || controls === void 0 ? void 0 : controls.overrideId) !== null && _a !== void 0 ? _a : null, color: color, height: height, width: width, className: className, style: style, _experimentalEffects: _experimentalEffects }) }));
120
+ const memoizedEffectDefinitions = (0, use_memoized_effects_js_1.useMemoizedEffectDefinitions)(effects);
121
+ return ((0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { layout: "none", from: from, hidden: hidden, showInTimeline: showInTimeline, _experimentalControls: controls, _remotionInternalEffects: memoizedEffectDefinitions, durationInFrames: durationInFrames, name: name !== null && name !== void 0 ? name : '<Solid>', _remotionInternalDocumentationLink: name === undefined ? 'https://www.remotion.dev/docs/solid' : undefined, ...props, children: (0, jsx_runtime_1.jsx)(SolidInner, { ref: ref, overrideId: (_a = controls === null || controls === void 0 ? void 0 : controls.overrideId) !== null && _a !== void 0 ? _a : null, color: color, height: height, width: width, className: className, style: style, effects: effects }) }));
122
122
  });
123
123
  exports.Solid = (0, wrap_in_schema_js_1.wrapInSchema)(SolidOuter, solidSchema);
124
124
  exports.Solid.displayName = 'Solid';
@@ -21,12 +21,14 @@ exports.disabledEffectField = {
21
21
  // erasure the descriptor would be contravariant in `P` (via `apply`'s
22
22
  // argument) and concrete descriptors could not flow into `unknown` slots.
23
23
  const createEffect = (definition) => {
24
+ var _a;
24
25
  // Wrap `calculateKey` to fold the framework-level `disabled` flag into the
25
26
  // memoization key. Without this, toggling `disabled` via code/drag overrides
26
27
  // would not invalidate the cached `EffectDefinitionAndStack`.
27
28
  const { calculateKey: userCalculateKey, validateParams } = definition;
28
29
  const widened = {
29
30
  ...definition,
31
+ documentationLink: (_a = definition.documentationLink) !== null && _a !== void 0 ? _a : null,
30
32
  calculateKey: (params) => {
31
33
  var _a;
32
34
  const disabled = (_a = params.disabled) !== null && _a !== void 0 ? _a : false;
@@ -9,10 +9,17 @@ export type EffectApplyParams<P, S> = {
9
9
  readonly width: number;
10
10
  readonly height: number;
11
11
  readonly gpuDevice: AnyGpuDevice | null;
12
+ /**
13
+ * When `true`, WebGL `texImage2D` uploads use `UNPACK_FLIP_Y_WEBGL` so DOM-style
14
+ * 2D frame canvases match clip-space UVs. Set by `runEffectChain` — `false` for
15
+ * prior WebGL outputs and `ImageBitmap` bridges from WebGL.
16
+ */
17
+ readonly flipSourceY: boolean;
12
18
  };
13
19
  export type EffectDefinition<P, S = unknown> = {
14
20
  readonly type: string;
15
21
  readonly label: string;
22
+ readonly documentationLink: string | null;
16
23
  readonly backend: Backend;
17
24
  /**
18
25
  * Stable string for comparing effect instances: two descriptors with the same
@@ -68,6 +68,8 @@ const runEffectChain = async ({ state, source, effects, output, width, height, }
68
68
  if (isCancelled()) {
69
69
  return false;
70
70
  }
71
+ // Raw component sources are 2D frame canvases (Gif, WrappedCanvas.canvas, …).
72
+ let flipWebGLSourceY = true;
71
73
  for (let runIndex = 0; runIndex < runs.length; runIndex++) {
72
74
  const run = runs[runIndex];
73
75
  const [a, b] = state.pool.getPair(run.backend);
@@ -83,8 +85,10 @@ const runEffectChain = async ({ state, source, effects, output, width, height, }
83
85
  width,
84
86
  height,
85
87
  gpuDevice,
88
+ flipSourceY: run.backend === 'webgl2' ? flipWebGLSourceY : false,
86
89
  });
87
90
  if (run.backend === 'webgl2') {
91
+ flipWebGLSourceY = false;
88
92
  state.pool.assertContextNotLost(dst);
89
93
  }
90
94
  currentImage = dst;
@@ -93,19 +97,29 @@ const runEffectChain = async ({ state, source, effects, output, width, height, }
93
97
  lastTarget = (_a = currentImage) !== null && _a !== void 0 ? _a : lastTarget;
94
98
  const nextRun = runs[runIndex + 1];
95
99
  if (nextRun && nextRun.backend !== run.backend && lastTarget) {
96
- // Bridge between backend groups via `createImageBitmap` rather than
97
- // passing the canvas straight through. A direct `drawImage(webglCanvas)`
98
- // in the next backend's first effect forces an implicit GPU readback /
99
- // finish on the consuming context, which empirically blows the per-frame
100
- // vsync budget and halves the paint rate. `createImageBitmap` performs
101
- // the same handoff but pipelines the GPU work, so the next effect reads
102
- // from a ready-to-sample bitmap without stalling.
103
- const bitmap = await createImageBitmap(lastTarget);
104
- if (isCancelled()) {
105
- bitmap.close();
106
- return false;
100
+ // 2D WebGL: pass the 2D canvas directly so `texImage2D` + `UNPACK_FLIP_Y`
101
+ // matches blur-only on a raw frame canvas. `createImageBitmap` here changes
102
+ // upload orientation and produced upside-down stacks (wave + blur).
103
+ if (run.backend === '2d' && nextRun.backend === 'webgl2') {
104
+ currentImage = lastTarget;
105
+ flipWebGLSourceY = true;
106
+ }
107
+ else {
108
+ // Other bridges use `createImageBitmap` rather than passing the canvas
109
+ // straight through. A direct `drawImage(webglCanvas)` in the next
110
+ // backend's first effect forces an implicit GPU readback / finish on the
111
+ // consuming context, which empirically blows the per-frame vsync budget and
112
+ // halves the paint rate. `createImageBitmap` pipelines the GPU work.
113
+ const bitmap = await createImageBitmap(lastTarget);
114
+ if (isCancelled()) {
115
+ bitmap.close();
116
+ return false;
117
+ }
118
+ currentImage = bitmap;
119
+ if (nextRun.backend === 'webgl2') {
120
+ flipWebGLSourceY = false;
121
+ }
107
122
  }
108
- currentImage = bitmap;
109
123
  }
110
124
  }
111
125
  if (!lastTarget) {
@@ -269,7 +269,7 @@ export declare const Internals: {
269
269
  readonly getRoot: () => import("react").FC<{}> | null;
270
270
  readonly useMediaVolumeState: () => readonly [number, (u: number) => void];
271
271
  readonly useMediaMutedState: () => readonly [boolean, (u: React.SetStateAction<boolean>) => void];
272
- readonly useMediaInTimeline: ({ volume, mediaVolume, src, mediaType, playbackRate, displayName, id, getStack, showInTimeline, premountDisplay, postmountDisplay, loopDisplay, }: {
272
+ readonly useMediaInTimeline: ({ volume, mediaVolume, src, mediaType, playbackRate, displayName, id, getStack, showInTimeline, premountDisplay, postmountDisplay, loopDisplay, documentationLink, }: {
273
273
  volume: import("./volume-prop.js").VolumeProp | undefined;
274
274
  mediaVolume: number;
275
275
  src: string | undefined;
@@ -282,6 +282,7 @@ export declare const Internals: {
282
282
  premountDisplay: number | null;
283
283
  postmountDisplay: number | null;
284
284
  loopDisplay: import("./CompositionManager.js").LoopDisplay | undefined;
285
+ documentationLink: string | null;
285
286
  }) => void;
286
287
  readonly useLazyComponent: <Props>({ compProps, componentName, noSuspense, }: {
287
288
  compProps: CompProps<Props>;
@@ -84,7 +84,7 @@ const Loop = ({ durationInFrames, times = Infinity, children, name, showInTimeli
84
84
  durationInFrames,
85
85
  };
86
86
  }, [currentFrame, durationInFrames]);
87
- return ((0, jsx_runtime_1.jsx)(LoopContext.Provider, { value: loopContext, children: (0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { durationInFrames: durationInFrames, from: from, name: name !== null && name !== void 0 ? name : '<Loop>', _remotionInternalLoopDisplay: loopDisplay, layout: props.layout, style: style, showInTimeline: showInTimeline, children: children }) }));
87
+ return ((0, jsx_runtime_1.jsx)(LoopContext.Provider, { value: loopContext, children: (0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { durationInFrames: durationInFrames, from: from, name: name !== null && name !== void 0 ? name : '<Loop>', _remotionInternalDocumentationLink: name === undefined ? 'https://www.remotion.dev/docs/loop' : undefined, _remotionInternalLoopDisplay: loopDisplay, layout: props.layout, style: style, showInTimeline: showInTimeline, children: children }) }));
88
88
  };
89
89
  exports.Loop = Loop;
90
90
  exports.Loop.useLoop = useLoop;
@@ -55,10 +55,10 @@ const SeriesInner = (props) => {
55
55
  }
56
56
  const currentStartFrame = startFrame + offset;
57
57
  startFrame += durationInFramesProp + offset;
58
- return ((0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { name: name || '<Series.Sequence>', from: currentStartFrame, durationInFrames: durationInFramesProp, ...passedProps, ref: castedChild.ref, children: child }));
58
+ return ((0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { name: name || '<Series.Sequence>', _remotionInternalDocumentationLink: name ? undefined : 'https://www.remotion.dev/docs/series', from: currentStartFrame, durationInFrames: durationInFramesProp, ...passedProps, ref: castedChild.ref, children: child }));
59
59
  });
60
60
  }, [props.children]);
61
- return ((0, jsx_runtime_1.jsx)(is_inside_series_js_1.IsInsideSeriesContainer, { children: (0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { layout: "none", name: "<Series>", ...props, children: childrenValue }) }));
61
+ return ((0, jsx_runtime_1.jsx)(is_inside_series_js_1.IsInsideSeriesContainer, { children: (0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { layout: "none", name: "<Series>", _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/series", ...props, children: childrenValue }) }));
62
62
  };
63
63
  /**
64
64
  * @description with this component, you can easily stitch together scenes that should play sequentially after another.