@remotion/motion-blur 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.
package/README.md CHANGED
@@ -15,4 +15,4 @@ Remove the `^` character from the version number to use the exact version.
15
15
 
16
16
  ## Usage
17
17
 
18
- See the [documentation](https://www.remotion.dev/docs/motion-blur) for more information.
18
+ See the [documentation](https://www.remotion.dev/docs/motion-blur/api) for more information.
@@ -1,11 +1,12 @@
1
1
  import React from 'react';
2
- import { type HtmlInCanvasProps } from 'remotion';
3
- export type HtmlInCanvasMotionBlurProps = Pick<HtmlInCanvasProps, 'from' | 'durationInFrames' | 'trimBefore' | 'playbackRate'> & {
2
+ import { type InteractiveBaseProps, type InteractivePremountProps } from 'remotion';
3
+ export type HtmlInCanvasMotionBlurProps = InteractiveBaseProps & InteractivePremountProps & {
4
4
  readonly children: React.ReactNode;
5
5
  readonly width: number;
6
6
  readonly height: number;
7
7
  readonly shutterAngle?: number;
8
8
  readonly samples?: number;
9
+ readonly disabled?: boolean;
9
10
  };
10
11
  /**
11
12
  * Experimental motion blur that averages separately captured HTML-in-canvas
@@ -13,4 +14,4 @@ export type HtmlInCanvasMotionBlurProps = Pick<HtmlInCanvasProps, 'from' | 'dura
13
14
  * the experimental HTML-in-canvas flag enabled. Nested HtmlInCanvas components
14
15
  * are currently unsupported.
15
16
  */
16
- export declare const HtmlInCanvasMotionBlur: React.FC<HtmlInCanvasMotionBlurProps>;
17
+ export declare const HtmlInCanvasMotionBlur: React.ComponentType<HtmlInCanvasMotionBlurProps>;
@@ -4,25 +4,50 @@ exports.HtmlInCanvasMotionBlur = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
+ const htmlInCanvasMotionBlurSchema = {
8
+ ...remotion_1.Interactive.baseSchema,
9
+ ...remotion_1.Interactive.premountSchema,
10
+ shutterAngle: {
11
+ type: 'number',
12
+ min: 0,
13
+ max: 360,
14
+ step: 1,
15
+ default: 180,
16
+ description: 'Shutter angle',
17
+ hiddenFromList: false,
18
+ },
19
+ samples: {
20
+ type: 'number',
21
+ min: 1,
22
+ max: 64,
23
+ step: 1,
24
+ integer: true,
25
+ default: 8,
26
+ description: 'Samples',
27
+ hiddenFromList: false,
28
+ keyframable: false,
29
+ },
30
+ disabled: {
31
+ type: 'boolean',
32
+ default: false,
33
+ description: 'Disabled',
34
+ },
35
+ };
7
36
  const MotionBlurSample = ({ children, width, height, index, count, shutterInFrames, firstFrame, lastFrame, }) => {
8
37
  const frame = (0, remotion_1.useCurrentFrame)();
9
38
  const sampleFrame = Math.max(firstFrame, Math.min(lastFrame, frame + ((index + 0.5) / count - 0.5) * shutterInFrames));
10
- return (jsx_runtime_1.jsx("div", { "aria-hidden": index !== Math.floor(count / 2), drawable: '', style: {
39
+ const content = jsx_runtime_1.jsx(remotion_1.Freeze, { frame: sampleFrame, children: children });
40
+ const isRepresentativeSample = index === Math.floor(count / 2);
41
+ return (jsx_runtime_1.jsx("div", { "aria-hidden": !isRepresentativeSample, ...(index === 0 ? {} : { drawable: '' }), style: {
11
42
  position: 'absolute',
12
43
  inset: 0,
13
44
  width,
14
45
  height,
15
46
  isolation: 'isolate',
16
- pointerEvents: index === Math.floor(count / 2) ? 'auto' : 'none',
17
- }, children: jsx_runtime_1.jsx(remotion_1.Freeze, { frame: sampleFrame, children: children }) }));
47
+ pointerEvents: isRepresentativeSample ? 'auto' : 'none',
48
+ }, children: isRepresentativeSample ? (content) : (jsx_runtime_1.jsx(remotion_1.Internals.DisableSequenceRegistrationProvider, { children: content })) }));
18
49
  };
19
- /**
20
- * Experimental motion blur that averages separately captured HTML-in-canvas
21
- * snapshots of the children at fractional frames. Preview requires Chrome with
22
- * the experimental HTML-in-canvas flag enabled. Nested HtmlInCanvas components
23
- * are currently unsupported.
24
- */
25
- const HtmlInCanvasMotionBlur = ({ children, width, height, shutterAngle = 180, samples = 8, from, durationInFrames, trimBefore, playbackRate, }) => {
50
+ const HtmlInCanvasMotionBlurInner = ({ children, width, height, shutterAngle = 180, samples = 8, disabled = false, from, durationInFrames, trimBefore, playbackRate, loop, freeze, hidden, name, premountFor, postmountFor, showInTimeline, styleWhilePremounted, styleWhilePostmounted, controls, }) => {
26
51
  const { durationInFrames: compositionDurationInFrames } = (0, remotion_1.useVideoConfig)();
27
52
  if (!Number.isInteger(samples) || samples < 1 || samples > 64) {
28
53
  throw new TypeError(`"samples" must be an integer between 1 and 64, but got ${String(samples)}`);
@@ -33,10 +58,15 @@ const HtmlInCanvasMotionBlur = ({ children, width, height, shutterAngle = 180, s
33
58
  shutterAngle > 360) {
34
59
  throw new TypeError(`"shutterAngle" must be between 0 and 360, but got ${String(shutterAngle)}`);
35
60
  }
36
- const actualSamples = shutterAngle === 0 ? 1 : samples;
61
+ // Keep the first sample mounted when blur is disabled so the canvas stays visible.
62
+ const actualSamples = disabled || shutterAngle === 0 ? 1 : samples;
37
63
  const shutterInFrames = (shutterAngle / 360) * (playbackRate !== null && playbackRate !== void 0 ? playbackRate : 1);
38
64
  const firstFrame = trimBefore !== null && trimBefore !== void 0 ? trimBefore : 0;
39
- const visibleDuration = Math.max(0, Math.min(durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : Infinity, compositionDurationInFrames - (from !== null && from !== void 0 ? from : 0)));
65
+ const visibleDuration = Math.max(0, Math.min(remotion_1.Internals.resolveSequenceDuration({
66
+ durationInFrames,
67
+ playbackRate,
68
+ loop,
69
+ }), compositionDurationInFrames - (from !== null && from !== void 0 ? from : 0)));
40
70
  const lastFrame = firstFrame + Math.max(0, visibleDuration - 1) * (playbackRate !== null && playbackRate !== void 0 ? playbackRate : 1);
41
71
  const onPaint = (0, react_1.useCallback)(({ canvas, element, elementImage }) => {
42
72
  const context = canvas.getContext('2d');
@@ -60,11 +90,7 @@ const HtmlInCanvasMotionBlur = ({ children, width, height, shutterAngle = 180, s
60
90
  ? elementImage
61
91
  : layoutCanvas.captureElementImage(sampleElement);
62
92
  try {
63
- const sampleTransform = context.drawElementImage(image, 0, 0);
64
- if (index === Math.floor(actualSamples / 2)) {
65
- sampleElement.style.transform =
66
- sampleTransform.toString();
67
- }
93
+ context.drawElementImage(image, 0, 0);
68
94
  }
69
95
  finally {
70
96
  if (index !== 0) {
@@ -77,6 +103,20 @@ const HtmlInCanvasMotionBlur = ({ children, width, height, shutterAngle = 180, s
77
103
  return (jsx_runtime_1.jsx(MotionBlurSample, { width: width, height: height, index: index, count: actualSamples, shutterInFrames: shutterInFrames, firstFrame: firstFrame, lastFrame: lastFrame, children: children }, index));
78
104
  });
79
105
  // The root wrapper holds the first sample. The rest must be canvas children.
80
- return (jsx_runtime_1.jsx(remotion_1.HtmlInCanvas, { width: width, height: height, from: from, durationInFrames: durationInFrames, trimBefore: trimBefore, playbackRate: playbackRate, name: "<HtmlInCanvasMotionBlur>", onPaint: onPaint, _remotionInternalCanvasSiblings: sampleElements.slice(1), children: sampleElements[0] }));
106
+ // Reuse HtmlInCanvas's Sequence for the motion blur controls.
107
+ return (jsx_runtime_1.jsx(remotion_1.HtmlInCanvas, { width: width, height: height, from: from, durationInFrames: durationInFrames, trimBefore: trimBefore, playbackRate: playbackRate, loop: loop, freeze: freeze, hidden: hidden, name: name !== null && name !== void 0 ? name : '<HtmlInCanvasMotionBlur>', premountFor: premountFor, postmountFor: postmountFor, showInTimeline: showInTimeline, styleWhilePremounted: styleWhilePremounted, styleWhilePostmounted: styleWhilePostmounted, controls, onPaint: onPaint, _remotionInternalCanvasSiblings: sampleElements.slice(1), children: sampleElements[0] }));
81
108
  };
82
- exports.HtmlInCanvasMotionBlur = HtmlInCanvasMotionBlur;
109
+ /**
110
+ * Experimental motion blur that averages separately captured HTML-in-canvas
111
+ * snapshots of the children at fractional frames. Preview requires Chrome with
112
+ * the experimental HTML-in-canvas flag enabled. Nested HtmlInCanvas components
113
+ * are currently unsupported.
114
+ */
115
+ exports.HtmlInCanvasMotionBlur = remotion_1.Interactive.withSchema({
116
+ Component: HtmlInCanvasMotionBlurInner,
117
+ componentName: '<HtmlInCanvasMotionBlur>',
118
+ componentIdentity: 'dev.remotion.motionBlur.HtmlInCanvasMotionBlur',
119
+ schema: htmlInCanvasMotionBlurSchema,
120
+ supportsEffects: false,
121
+ });
122
+ exports.HtmlInCanvasMotionBlur.displayName = 'HtmlInCanvasMotionBlur';
@@ -61,10 +61,41 @@ import { useCallback } from "react";
61
61
  import {
62
62
  Freeze as Freeze2,
63
63
  HtmlInCanvas,
64
+ Interactive,
65
+ Internals,
64
66
  useCurrentFrame as useCurrentFrame2,
65
67
  useVideoConfig
66
68
  } from "remotion";
67
69
  import { jsx as jsx2 } from "react/jsx-runtime";
70
+ var htmlInCanvasMotionBlurSchema = {
71
+ ...Interactive.baseSchema,
72
+ ...Interactive.premountSchema,
73
+ shutterAngle: {
74
+ type: "number",
75
+ min: 0,
76
+ max: 360,
77
+ step: 1,
78
+ default: 180,
79
+ description: "Shutter angle",
80
+ hiddenFromList: false
81
+ },
82
+ samples: {
83
+ type: "number",
84
+ min: 1,
85
+ max: 64,
86
+ step: 1,
87
+ integer: true,
88
+ default: 8,
89
+ description: "Samples",
90
+ hiddenFromList: false,
91
+ keyframable: false
92
+ },
93
+ disabled: {
94
+ type: "boolean",
95
+ default: false,
96
+ description: "Disabled"
97
+ }
98
+ };
68
99
  var MotionBlurSample = ({
69
100
  children,
70
101
  width,
@@ -77,33 +108,48 @@ var MotionBlurSample = ({
77
108
  }) => {
78
109
  const frame = useCurrentFrame2();
79
110
  const sampleFrame = Math.max(firstFrame, Math.min(lastFrame, frame + ((index + 0.5) / count - 0.5) * shutterInFrames));
111
+ const content = /* @__PURE__ */ jsx2(Freeze2, {
112
+ frame: sampleFrame,
113
+ children
114
+ });
115
+ const isRepresentativeSample = index === Math.floor(count / 2);
80
116
  return /* @__PURE__ */ jsx2("div", {
81
- "aria-hidden": index !== Math.floor(count / 2),
82
- ...{ drawable: "" },
117
+ "aria-hidden": !isRepresentativeSample,
118
+ ...index === 0 ? {} : { drawable: "" },
83
119
  style: {
84
120
  position: "absolute",
85
121
  inset: 0,
86
122
  width,
87
123
  height,
88
124
  isolation: "isolate",
89
- pointerEvents: index === Math.floor(count / 2) ? "auto" : "none"
125
+ pointerEvents: isRepresentativeSample ? "auto" : "none"
90
126
  },
91
- children: /* @__PURE__ */ jsx2(Freeze2, {
92
- frame: sampleFrame,
93
- children
127
+ children: isRepresentativeSample ? content : /* @__PURE__ */ jsx2(Internals.DisableSequenceRegistrationProvider, {
128
+ children: content
94
129
  })
95
130
  });
96
131
  };
97
- var HtmlInCanvasMotionBlur = ({
132
+ var HtmlInCanvasMotionBlurInner = ({
98
133
  children,
99
134
  width,
100
135
  height,
101
136
  shutterAngle = 180,
102
137
  samples = 8,
138
+ disabled = false,
103
139
  from,
104
140
  durationInFrames,
105
141
  trimBefore,
106
- playbackRate
142
+ playbackRate,
143
+ loop,
144
+ freeze,
145
+ hidden,
146
+ name,
147
+ premountFor,
148
+ postmountFor,
149
+ showInTimeline,
150
+ styleWhilePremounted,
151
+ styleWhilePostmounted,
152
+ controls
107
153
  }) => {
108
154
  const { durationInFrames: compositionDurationInFrames } = useVideoConfig();
109
155
  if (!Number.isInteger(samples) || samples < 1 || samples > 64) {
@@ -112,10 +158,14 @@ var HtmlInCanvasMotionBlur = ({
112
158
  if (typeof shutterAngle !== "number" || !Number.isFinite(shutterAngle) || shutterAngle < 0 || shutterAngle > 360) {
113
159
  throw new TypeError(`"shutterAngle" must be between 0 and 360, but got ${String(shutterAngle)}`);
114
160
  }
115
- const actualSamples = shutterAngle === 0 ? 1 : samples;
161
+ const actualSamples = disabled || shutterAngle === 0 ? 1 : samples;
116
162
  const shutterInFrames = shutterAngle / 360 * (playbackRate ?? 1);
117
163
  const firstFrame = trimBefore ?? 0;
118
- const visibleDuration = Math.max(0, Math.min(durationInFrames ?? Infinity, compositionDurationInFrames - (from ?? 0)));
164
+ const visibleDuration = Math.max(0, Math.min(Internals.resolveSequenceDuration({
165
+ durationInFrames,
166
+ playbackRate,
167
+ loop
168
+ }), compositionDurationInFrames - (from ?? 0)));
119
169
  const lastFrame = firstFrame + Math.max(0, visibleDuration - 1) * (playbackRate ?? 1);
120
170
  const onPaint = useCallback(({ canvas, element, elementImage }) => {
121
171
  const context = canvas.getContext("2d");
@@ -136,10 +186,7 @@ var HtmlInCanvasMotionBlur = ({
136
186
  for (const [index, sampleElement] of captureElements.entries()) {
137
187
  const image = index === 0 ? elementImage : layoutCanvas.captureElementImage(sampleElement);
138
188
  try {
139
- const sampleTransform = context.drawElementImage(image, 0, 0);
140
- if (index === Math.floor(actualSamples / 2)) {
141
- sampleElement.style.transform = sampleTransform.toString();
142
- }
189
+ context.drawElementImage(image, 0, 0);
143
190
  } finally {
144
191
  if (index !== 0) {
145
192
  image.close();
@@ -166,12 +213,29 @@ var HtmlInCanvasMotionBlur = ({
166
213
  durationInFrames,
167
214
  trimBefore,
168
215
  playbackRate,
169
- name: "<HtmlInCanvasMotionBlur>",
216
+ loop,
217
+ freeze,
218
+ hidden,
219
+ name: name ?? "<HtmlInCanvasMotionBlur>",
220
+ premountFor,
221
+ postmountFor,
222
+ showInTimeline,
223
+ styleWhilePremounted,
224
+ styleWhilePostmounted,
225
+ ...{ controls },
170
226
  onPaint,
171
227
  _remotionInternalCanvasSiblings: sampleElements.slice(1),
172
228
  children: sampleElements[0]
173
229
  });
174
230
  };
231
+ var HtmlInCanvasMotionBlur = Interactive.withSchema({
232
+ Component: HtmlInCanvasMotionBlurInner,
233
+ componentName: "<HtmlInCanvasMotionBlur>",
234
+ componentIdentity: "dev.remotion.motionBlur.HtmlInCanvasMotionBlur",
235
+ schema: htmlInCanvasMotionBlurSchema,
236
+ supportsEffects: false
237
+ });
238
+ HtmlInCanvasMotionBlur.displayName = "HtmlInCanvasMotionBlur";
175
239
  // src/Trail.tsx
176
240
  import { AbsoluteFill as AbsoluteFill2, Freeze as Freeze3, useCurrentFrame as useCurrentFrame3 } from "remotion";
177
241
  import { jsx as jsx3, jsxs } from "react/jsx-runtime";
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/motion-blur"
4
4
  },
5
5
  "name": "@remotion/motion-blur",
6
- "version": "4.0.529",
6
+ "version": "4.0.531",
7
7
  "description": "Motion blur effect for Remotion",
8
8
  "main": "dist/cjs/index.js",
9
9
  "types": "dist/cjs/index.d.ts",
@@ -21,7 +21,7 @@
21
21
  "url": "https://github.com/remotion-dev/remotion/issues"
22
22
  },
23
23
  "dependencies": {
24
- "remotion": "4.0.529"
24
+ "remotion": "4.0.531"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "react": ">=16.8.0",
@@ -39,8 +39,8 @@
39
39
  "devDependencies": {
40
40
  "react": "19.2.3",
41
41
  "react-dom": "19.2.3",
42
- "remotion": "4.0.529",
43
- "@remotion/eslint-config-internal": "4.0.529",
42
+ "remotion": "4.0.531",
43
+ "@remotion/eslint-config-internal": "4.0.531",
44
44
  "eslint": "9.19.0",
45
45
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
46
46
  },
@@ -52,5 +52,5 @@
52
52
  "publishConfig": {
53
53
  "access": "public"
54
54
  },
55
- "homepage": "https://www.remotion.dev/docs/motion-blur"
55
+ "homepage": "https://www.remotion.dev/docs/motion-blur/api"
56
56
  }