@remotion/transitions 4.0.496 → 4.0.498
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/dist/TransitionSeries.d.ts +2 -2
- package/dist/TransitionSeries.js +1 -0
- package/dist/esm/book-flip.mjs +96 -24
- package/dist/esm/cross-zoom.mjs +96 -24
- package/dist/esm/crosswarp.mjs +96 -24
- package/dist/esm/dissolve.mjs +96 -24
- package/dist/esm/dreamy-zoom.mjs +96 -24
- package/dist/esm/film-burn.mjs +96 -24
- package/dist/esm/index.mjs +106 -33
- package/dist/esm/linear-blur.mjs +96 -24
- package/dist/esm/ripple.mjs +96 -24
- package/dist/esm/swap.mjs +96 -24
- package/dist/esm/zoom-blur.mjs +96 -24
- package/dist/esm/zoom-in-out.mjs +96 -24
- package/dist/html-in-canvas-presentation.d.ts +2 -2
- package/dist/html-in-canvas-presentation.js +81 -16
- package/dist/presentations/book-flip.js +3 -2
- package/dist/presentations/cross-zoom.js +3 -2
- package/dist/presentations/crosswarp.js +3 -2
- package/dist/presentations/dissolve.js +3 -2
- package/dist/presentations/dreamy-zoom.js +3 -2
- package/dist/presentations/film-burn.js +3 -2
- package/dist/presentations/linear-blur.js +3 -2
- package/dist/presentations/ripple.js +3 -2
- package/dist/presentations/swap.js +3 -2
- package/dist/presentations/upload-element-image.d.ts +1 -0
- package/dist/presentations/upload-element-image.js +7 -0
- package/dist/presentations/zoom-blur.js +3 -2
- package/dist/presentations/zoom-in-out.js +3 -2
- package/dist/types.d.ts +1 -1
- package/package.json +8 -8
package/dist/esm/ripple.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
Internals,
|
|
8
8
|
useDelayRender
|
|
9
9
|
} from "remotion";
|
|
10
|
-
import { jsx } from "react/jsx-runtime";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
11
|
var HtmlInCanvasPresentation = ({
|
|
12
12
|
children,
|
|
13
13
|
onElementImage,
|
|
@@ -23,6 +23,7 @@ var HtmlInCanvasPresentation = ({
|
|
|
23
23
|
throw new Error(HTML_IN_CANVAS_UNSUPPORTED_MESSAGE);
|
|
24
24
|
}
|
|
25
25
|
const canvasRef = useRef(null);
|
|
26
|
+
const outputCanvasRef = useRef(null);
|
|
26
27
|
const canvasSubtreeStyle = useMemo(() => {
|
|
27
28
|
return {
|
|
28
29
|
width: "100%",
|
|
@@ -34,7 +35,21 @@ var HtmlInCanvasPresentation = ({
|
|
|
34
35
|
bottom: 0
|
|
35
36
|
};
|
|
36
37
|
}, []);
|
|
37
|
-
const
|
|
38
|
+
const outputCanvasStyle = useMemo(() => {
|
|
39
|
+
return {
|
|
40
|
+
width: "100%",
|
|
41
|
+
height: "100%",
|
|
42
|
+
position: "absolute",
|
|
43
|
+
top: 0,
|
|
44
|
+
left: 0,
|
|
45
|
+
right: 0,
|
|
46
|
+
bottom: 0,
|
|
47
|
+
pointerEvents: "none"
|
|
48
|
+
};
|
|
49
|
+
}, []);
|
|
50
|
+
const captureCanvasRef = useRef(null);
|
|
51
|
+
const captureContextRef = useRef(null);
|
|
52
|
+
const [shaderCanvas] = useState(() => new OffscreenCanvas(1, 1));
|
|
38
53
|
const passedPropsRef = useRef(passedProps);
|
|
39
54
|
passedPropsRef.current = passedProps;
|
|
40
55
|
const memoizedEffects = Internals.useMemoizedEffects({
|
|
@@ -43,33 +58,58 @@ var HtmlInCanvasPresentation = ({
|
|
|
43
58
|
});
|
|
44
59
|
const effectsRef = useRef(memoizedEffects);
|
|
45
60
|
effectsRef.current = memoizedEffects;
|
|
46
|
-
const [instance] = useState(() => shader(
|
|
61
|
+
const [instance] = useState(() => shader(shaderCanvas));
|
|
47
62
|
useLayoutEffect(() => {
|
|
63
|
+
const canvas = canvasRef.current;
|
|
64
|
+
if (!canvas) {
|
|
65
|
+
return () => {
|
|
66
|
+
instance.cleanup();
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const captureCanvas = canvas.transferControlToOffscreen();
|
|
70
|
+
const captureContext = captureCanvas.getContext("2d");
|
|
71
|
+
if (!captureContext) {
|
|
72
|
+
throw new Error("Failed to create capture canvas context");
|
|
73
|
+
}
|
|
74
|
+
captureCanvasRef.current = captureCanvas;
|
|
75
|
+
captureContextRef.current = captureContext;
|
|
48
76
|
return () => {
|
|
49
77
|
instance.cleanup();
|
|
78
|
+
captureCanvasRef.current = null;
|
|
79
|
+
captureContextRef.current = null;
|
|
50
80
|
};
|
|
51
|
-
}, [
|
|
81
|
+
}, [instance]);
|
|
52
82
|
const chainState = Internals.useEffectChainState();
|
|
53
83
|
const { delayRender, continueRender } = useDelayRender();
|
|
54
84
|
const draw = useCallback(async (prevImage, nextImage, progress) => {
|
|
55
|
-
|
|
85
|
+
const outputCanvas = outputCanvasRef.current;
|
|
86
|
+
if (!outputCanvas) {
|
|
56
87
|
throw new Error("Canvas not found");
|
|
57
88
|
}
|
|
58
89
|
const handle = delayRender("onPaint");
|
|
90
|
+
const clearOutput = () => {
|
|
91
|
+
const context = outputCanvas.getContext("2d");
|
|
92
|
+
if (!context) {
|
|
93
|
+
throw new Error("Failed to create output canvas context");
|
|
94
|
+
}
|
|
95
|
+
context.clearRect(0, 0, outputCanvas.width, outputCanvas.height);
|
|
96
|
+
};
|
|
59
97
|
if (!prevImage && !nextImage) {
|
|
60
|
-
continueRender(handle);
|
|
61
98
|
instance.clear();
|
|
99
|
+
clearOutput();
|
|
100
|
+
continueRender(handle);
|
|
62
101
|
return;
|
|
63
102
|
}
|
|
64
103
|
const width = prevImage?.width ?? nextImage?.width ?? 0;
|
|
65
104
|
const height = prevImage?.height ?? nextImage?.height ?? 0;
|
|
66
105
|
if (width === 0 || height === 0) {
|
|
67
|
-
continueRender(handle);
|
|
68
106
|
instance.clear();
|
|
107
|
+
clearOutput();
|
|
108
|
+
continueRender(handle);
|
|
69
109
|
return;
|
|
70
110
|
}
|
|
71
|
-
|
|
72
|
-
|
|
111
|
+
shaderCanvas.width = width;
|
|
112
|
+
shaderCanvas.height = height;
|
|
73
113
|
instance.draw({
|
|
74
114
|
prevImage,
|
|
75
115
|
nextImage,
|
|
@@ -80,14 +120,14 @@ var HtmlInCanvasPresentation = ({
|
|
|
80
120
|
});
|
|
81
121
|
await Internals.runEffectChain({
|
|
82
122
|
state: chainState.get(width, height),
|
|
83
|
-
source:
|
|
123
|
+
source: shaderCanvas,
|
|
84
124
|
effects: effectsRef.current ?? [],
|
|
85
125
|
width,
|
|
86
126
|
height,
|
|
87
|
-
output:
|
|
127
|
+
output: outputCanvas
|
|
88
128
|
});
|
|
89
129
|
continueRender(handle);
|
|
90
|
-
}, [chainState,
|
|
130
|
+
}, [chainState, continueRender, delayRender, instance, shaderCanvas]);
|
|
91
131
|
const passThrough = bothEnteringAndExiting && presentationDirection === "exiting";
|
|
92
132
|
useLayoutEffect(() => {
|
|
93
133
|
if (passThrough) {
|
|
@@ -100,11 +140,19 @@ var HtmlInCanvasPresentation = ({
|
|
|
100
140
|
canvas.layoutSubtree = true;
|
|
101
141
|
const onPaint = () => {
|
|
102
142
|
const firstChild = canvas.firstChild;
|
|
103
|
-
|
|
143
|
+
const captureCanvas = captureCanvasRef.current;
|
|
144
|
+
const captureContext = captureContextRef.current;
|
|
145
|
+
if (!firstChild || !captureCanvas || !captureContext) {
|
|
104
146
|
return;
|
|
105
147
|
}
|
|
106
148
|
const elementImage = canvas.captureElementImage(firstChild);
|
|
107
|
-
|
|
149
|
+
try {
|
|
150
|
+
captureContext.reset();
|
|
151
|
+
captureContext.drawElementImage(elementImage, 0, 0);
|
|
152
|
+
} finally {
|
|
153
|
+
elementImage.close();
|
|
154
|
+
}
|
|
155
|
+
onElementImage(captureCanvas, draw);
|
|
108
156
|
};
|
|
109
157
|
canvas.addEventListener("paint", onPaint);
|
|
110
158
|
return () => {
|
|
@@ -138,20 +186,39 @@ var HtmlInCanvasPresentation = ({
|
|
|
138
186
|
return;
|
|
139
187
|
}
|
|
140
188
|
const observer = new ResizeObserver(([entry]) => {
|
|
141
|
-
|
|
142
|
-
|
|
189
|
+
const outputCanvas = outputCanvasRef.current;
|
|
190
|
+
const captureCanvas = captureCanvasRef.current;
|
|
191
|
+
if (!outputCanvas || !captureCanvas) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const width = entry.devicePixelContentBoxSize[0].inlineSize;
|
|
195
|
+
const height = entry.devicePixelContentBoxSize[0].blockSize;
|
|
196
|
+
captureCanvas.width = width;
|
|
197
|
+
captureCanvas.height = height;
|
|
198
|
+
outputCanvas.width = width;
|
|
199
|
+
outputCanvas.height = height;
|
|
200
|
+
canvas.requestPaint?.();
|
|
143
201
|
});
|
|
144
202
|
observer.observe(canvas, { box: "device-pixel-content-box" });
|
|
203
|
+
return () => {
|
|
204
|
+
observer.disconnect();
|
|
205
|
+
};
|
|
145
206
|
}, [passThrough]);
|
|
146
207
|
if (passThrough) {
|
|
147
208
|
return children;
|
|
148
209
|
}
|
|
149
|
-
return /* @__PURE__ */
|
|
150
|
-
children:
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
210
|
+
return /* @__PURE__ */ jsxs(AbsoluteFill, {
|
|
211
|
+
children: [
|
|
212
|
+
/* @__PURE__ */ jsx("canvas", {
|
|
213
|
+
ref: canvasRef,
|
|
214
|
+
style: canvasSubtreeStyle,
|
|
215
|
+
children
|
|
216
|
+
}),
|
|
217
|
+
/* @__PURE__ */ jsx("canvas", {
|
|
218
|
+
ref: outputCanvasRef,
|
|
219
|
+
style: outputCanvasStyle
|
|
220
|
+
})
|
|
221
|
+
]
|
|
155
222
|
});
|
|
156
223
|
};
|
|
157
224
|
var makeHtmlInCanvasPresentation = (shader) => {
|
|
@@ -173,6 +240,11 @@ var makeHtmlInCanvasPresentation = (shader) => {
|
|
|
173
240
|
};
|
|
174
241
|
};
|
|
175
242
|
|
|
243
|
+
// src/presentations/upload-element-image.ts
|
|
244
|
+
var uploadElementImage = (gl, elementImage) => {
|
|
245
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, elementImage);
|
|
246
|
+
};
|
|
247
|
+
|
|
176
248
|
// src/presentations/ripple.tsx
|
|
177
249
|
var DEFAULT_AMPLITUDE = 100;
|
|
178
250
|
var DEFAULT_SPEED = 50;
|
|
@@ -315,13 +387,13 @@ var rippleShader = (canvas) => {
|
|
|
315
387
|
gl.activeTexture(gl.TEXTURE0);
|
|
316
388
|
gl.bindTexture(gl.TEXTURE_2D, prevTex);
|
|
317
389
|
if (prevImage) {
|
|
318
|
-
|
|
390
|
+
uploadElementImage(gl, prevImage);
|
|
319
391
|
}
|
|
320
392
|
gl.uniform1i(uPrev, 0);
|
|
321
393
|
gl.activeTexture(gl.TEXTURE1);
|
|
322
394
|
gl.bindTexture(gl.TEXTURE_2D, nextTex);
|
|
323
395
|
if (nextImage) {
|
|
324
|
-
|
|
396
|
+
uploadElementImage(gl, nextImage);
|
|
325
397
|
}
|
|
326
398
|
gl.uniform1i(uNext, 1);
|
|
327
399
|
gl.uniform1f(uTime, effectiveTime);
|
package/dist/esm/swap.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
Internals,
|
|
8
8
|
useDelayRender
|
|
9
9
|
} from "remotion";
|
|
10
|
-
import { jsx } from "react/jsx-runtime";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
11
|
var HtmlInCanvasPresentation = ({
|
|
12
12
|
children,
|
|
13
13
|
onElementImage,
|
|
@@ -23,6 +23,7 @@ var HtmlInCanvasPresentation = ({
|
|
|
23
23
|
throw new Error(HTML_IN_CANVAS_UNSUPPORTED_MESSAGE);
|
|
24
24
|
}
|
|
25
25
|
const canvasRef = useRef(null);
|
|
26
|
+
const outputCanvasRef = useRef(null);
|
|
26
27
|
const canvasSubtreeStyle = useMemo(() => {
|
|
27
28
|
return {
|
|
28
29
|
width: "100%",
|
|
@@ -34,7 +35,21 @@ var HtmlInCanvasPresentation = ({
|
|
|
34
35
|
bottom: 0
|
|
35
36
|
};
|
|
36
37
|
}, []);
|
|
37
|
-
const
|
|
38
|
+
const outputCanvasStyle = useMemo(() => {
|
|
39
|
+
return {
|
|
40
|
+
width: "100%",
|
|
41
|
+
height: "100%",
|
|
42
|
+
position: "absolute",
|
|
43
|
+
top: 0,
|
|
44
|
+
left: 0,
|
|
45
|
+
right: 0,
|
|
46
|
+
bottom: 0,
|
|
47
|
+
pointerEvents: "none"
|
|
48
|
+
};
|
|
49
|
+
}, []);
|
|
50
|
+
const captureCanvasRef = useRef(null);
|
|
51
|
+
const captureContextRef = useRef(null);
|
|
52
|
+
const [shaderCanvas] = useState(() => new OffscreenCanvas(1, 1));
|
|
38
53
|
const passedPropsRef = useRef(passedProps);
|
|
39
54
|
passedPropsRef.current = passedProps;
|
|
40
55
|
const memoizedEffects = Internals.useMemoizedEffects({
|
|
@@ -43,33 +58,58 @@ var HtmlInCanvasPresentation = ({
|
|
|
43
58
|
});
|
|
44
59
|
const effectsRef = useRef(memoizedEffects);
|
|
45
60
|
effectsRef.current = memoizedEffects;
|
|
46
|
-
const [instance] = useState(() => shader(
|
|
61
|
+
const [instance] = useState(() => shader(shaderCanvas));
|
|
47
62
|
useLayoutEffect(() => {
|
|
63
|
+
const canvas = canvasRef.current;
|
|
64
|
+
if (!canvas) {
|
|
65
|
+
return () => {
|
|
66
|
+
instance.cleanup();
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const captureCanvas = canvas.transferControlToOffscreen();
|
|
70
|
+
const captureContext = captureCanvas.getContext("2d");
|
|
71
|
+
if (!captureContext) {
|
|
72
|
+
throw new Error("Failed to create capture canvas context");
|
|
73
|
+
}
|
|
74
|
+
captureCanvasRef.current = captureCanvas;
|
|
75
|
+
captureContextRef.current = captureContext;
|
|
48
76
|
return () => {
|
|
49
77
|
instance.cleanup();
|
|
78
|
+
captureCanvasRef.current = null;
|
|
79
|
+
captureContextRef.current = null;
|
|
50
80
|
};
|
|
51
|
-
}, [
|
|
81
|
+
}, [instance]);
|
|
52
82
|
const chainState = Internals.useEffectChainState();
|
|
53
83
|
const { delayRender, continueRender } = useDelayRender();
|
|
54
84
|
const draw = useCallback(async (prevImage, nextImage, progress) => {
|
|
55
|
-
|
|
85
|
+
const outputCanvas = outputCanvasRef.current;
|
|
86
|
+
if (!outputCanvas) {
|
|
56
87
|
throw new Error("Canvas not found");
|
|
57
88
|
}
|
|
58
89
|
const handle = delayRender("onPaint");
|
|
90
|
+
const clearOutput = () => {
|
|
91
|
+
const context = outputCanvas.getContext("2d");
|
|
92
|
+
if (!context) {
|
|
93
|
+
throw new Error("Failed to create output canvas context");
|
|
94
|
+
}
|
|
95
|
+
context.clearRect(0, 0, outputCanvas.width, outputCanvas.height);
|
|
96
|
+
};
|
|
59
97
|
if (!prevImage && !nextImage) {
|
|
60
|
-
continueRender(handle);
|
|
61
98
|
instance.clear();
|
|
99
|
+
clearOutput();
|
|
100
|
+
continueRender(handle);
|
|
62
101
|
return;
|
|
63
102
|
}
|
|
64
103
|
const width = prevImage?.width ?? nextImage?.width ?? 0;
|
|
65
104
|
const height = prevImage?.height ?? nextImage?.height ?? 0;
|
|
66
105
|
if (width === 0 || height === 0) {
|
|
67
|
-
continueRender(handle);
|
|
68
106
|
instance.clear();
|
|
107
|
+
clearOutput();
|
|
108
|
+
continueRender(handle);
|
|
69
109
|
return;
|
|
70
110
|
}
|
|
71
|
-
|
|
72
|
-
|
|
111
|
+
shaderCanvas.width = width;
|
|
112
|
+
shaderCanvas.height = height;
|
|
73
113
|
instance.draw({
|
|
74
114
|
prevImage,
|
|
75
115
|
nextImage,
|
|
@@ -80,14 +120,14 @@ var HtmlInCanvasPresentation = ({
|
|
|
80
120
|
});
|
|
81
121
|
await Internals.runEffectChain({
|
|
82
122
|
state: chainState.get(width, height),
|
|
83
|
-
source:
|
|
123
|
+
source: shaderCanvas,
|
|
84
124
|
effects: effectsRef.current ?? [],
|
|
85
125
|
width,
|
|
86
126
|
height,
|
|
87
|
-
output:
|
|
127
|
+
output: outputCanvas
|
|
88
128
|
});
|
|
89
129
|
continueRender(handle);
|
|
90
|
-
}, [chainState,
|
|
130
|
+
}, [chainState, continueRender, delayRender, instance, shaderCanvas]);
|
|
91
131
|
const passThrough = bothEnteringAndExiting && presentationDirection === "exiting";
|
|
92
132
|
useLayoutEffect(() => {
|
|
93
133
|
if (passThrough) {
|
|
@@ -100,11 +140,19 @@ var HtmlInCanvasPresentation = ({
|
|
|
100
140
|
canvas.layoutSubtree = true;
|
|
101
141
|
const onPaint = () => {
|
|
102
142
|
const firstChild = canvas.firstChild;
|
|
103
|
-
|
|
143
|
+
const captureCanvas = captureCanvasRef.current;
|
|
144
|
+
const captureContext = captureContextRef.current;
|
|
145
|
+
if (!firstChild || !captureCanvas || !captureContext) {
|
|
104
146
|
return;
|
|
105
147
|
}
|
|
106
148
|
const elementImage = canvas.captureElementImage(firstChild);
|
|
107
|
-
|
|
149
|
+
try {
|
|
150
|
+
captureContext.reset();
|
|
151
|
+
captureContext.drawElementImage(elementImage, 0, 0);
|
|
152
|
+
} finally {
|
|
153
|
+
elementImage.close();
|
|
154
|
+
}
|
|
155
|
+
onElementImage(captureCanvas, draw);
|
|
108
156
|
};
|
|
109
157
|
canvas.addEventListener("paint", onPaint);
|
|
110
158
|
return () => {
|
|
@@ -138,20 +186,39 @@ var HtmlInCanvasPresentation = ({
|
|
|
138
186
|
return;
|
|
139
187
|
}
|
|
140
188
|
const observer = new ResizeObserver(([entry]) => {
|
|
141
|
-
|
|
142
|
-
|
|
189
|
+
const outputCanvas = outputCanvasRef.current;
|
|
190
|
+
const captureCanvas = captureCanvasRef.current;
|
|
191
|
+
if (!outputCanvas || !captureCanvas) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const width = entry.devicePixelContentBoxSize[0].inlineSize;
|
|
195
|
+
const height = entry.devicePixelContentBoxSize[0].blockSize;
|
|
196
|
+
captureCanvas.width = width;
|
|
197
|
+
captureCanvas.height = height;
|
|
198
|
+
outputCanvas.width = width;
|
|
199
|
+
outputCanvas.height = height;
|
|
200
|
+
canvas.requestPaint?.();
|
|
143
201
|
});
|
|
144
202
|
observer.observe(canvas, { box: "device-pixel-content-box" });
|
|
203
|
+
return () => {
|
|
204
|
+
observer.disconnect();
|
|
205
|
+
};
|
|
145
206
|
}, [passThrough]);
|
|
146
207
|
if (passThrough) {
|
|
147
208
|
return children;
|
|
148
209
|
}
|
|
149
|
-
return /* @__PURE__ */
|
|
150
|
-
children:
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
210
|
+
return /* @__PURE__ */ jsxs(AbsoluteFill, {
|
|
211
|
+
children: [
|
|
212
|
+
/* @__PURE__ */ jsx("canvas", {
|
|
213
|
+
ref: canvasRef,
|
|
214
|
+
style: canvasSubtreeStyle,
|
|
215
|
+
children
|
|
216
|
+
}),
|
|
217
|
+
/* @__PURE__ */ jsx("canvas", {
|
|
218
|
+
ref: outputCanvasRef,
|
|
219
|
+
style: outputCanvasStyle
|
|
220
|
+
})
|
|
221
|
+
]
|
|
155
222
|
});
|
|
156
223
|
};
|
|
157
224
|
var makeHtmlInCanvasPresentation = (shader) => {
|
|
@@ -173,6 +240,11 @@ var makeHtmlInCanvasPresentation = (shader) => {
|
|
|
173
240
|
};
|
|
174
241
|
};
|
|
175
242
|
|
|
243
|
+
// src/presentations/upload-element-image.ts
|
|
244
|
+
var uploadElementImage = (gl, elementImage) => {
|
|
245
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, elementImage);
|
|
246
|
+
};
|
|
247
|
+
|
|
176
248
|
// src/presentations/swap.tsx
|
|
177
249
|
var DEFAULT_REFLECTION = 0.4;
|
|
178
250
|
var DEFAULT_PERSPECTIVE = 0.2;
|
|
@@ -366,13 +438,13 @@ var swapShader = (canvas) => {
|
|
|
366
438
|
gl.activeTexture(gl.TEXTURE0);
|
|
367
439
|
gl.bindTexture(gl.TEXTURE_2D, prevTex);
|
|
368
440
|
if (prevImage) {
|
|
369
|
-
|
|
441
|
+
uploadElementImage(gl, prevImage);
|
|
370
442
|
}
|
|
371
443
|
gl.uniform1i(uPrev, 0);
|
|
372
444
|
gl.activeTexture(gl.TEXTURE1);
|
|
373
445
|
gl.bindTexture(gl.TEXTURE_2D, nextTex);
|
|
374
446
|
if (nextImage) {
|
|
375
|
-
|
|
447
|
+
uploadElementImage(gl, nextImage);
|
|
376
448
|
}
|
|
377
449
|
gl.uniform1i(uNext, 1);
|
|
378
450
|
gl.uniform1f(uTime, effectiveTime);
|
package/dist/esm/zoom-blur.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
Internals,
|
|
8
8
|
useDelayRender
|
|
9
9
|
} from "remotion";
|
|
10
|
-
import { jsx } from "react/jsx-runtime";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
11
|
var HtmlInCanvasPresentation = ({
|
|
12
12
|
children,
|
|
13
13
|
onElementImage,
|
|
@@ -23,6 +23,7 @@ var HtmlInCanvasPresentation = ({
|
|
|
23
23
|
throw new Error(HTML_IN_CANVAS_UNSUPPORTED_MESSAGE);
|
|
24
24
|
}
|
|
25
25
|
const canvasRef = useRef(null);
|
|
26
|
+
const outputCanvasRef = useRef(null);
|
|
26
27
|
const canvasSubtreeStyle = useMemo(() => {
|
|
27
28
|
return {
|
|
28
29
|
width: "100%",
|
|
@@ -34,7 +35,21 @@ var HtmlInCanvasPresentation = ({
|
|
|
34
35
|
bottom: 0
|
|
35
36
|
};
|
|
36
37
|
}, []);
|
|
37
|
-
const
|
|
38
|
+
const outputCanvasStyle = useMemo(() => {
|
|
39
|
+
return {
|
|
40
|
+
width: "100%",
|
|
41
|
+
height: "100%",
|
|
42
|
+
position: "absolute",
|
|
43
|
+
top: 0,
|
|
44
|
+
left: 0,
|
|
45
|
+
right: 0,
|
|
46
|
+
bottom: 0,
|
|
47
|
+
pointerEvents: "none"
|
|
48
|
+
};
|
|
49
|
+
}, []);
|
|
50
|
+
const captureCanvasRef = useRef(null);
|
|
51
|
+
const captureContextRef = useRef(null);
|
|
52
|
+
const [shaderCanvas] = useState(() => new OffscreenCanvas(1, 1));
|
|
38
53
|
const passedPropsRef = useRef(passedProps);
|
|
39
54
|
passedPropsRef.current = passedProps;
|
|
40
55
|
const memoizedEffects = Internals.useMemoizedEffects({
|
|
@@ -43,33 +58,58 @@ var HtmlInCanvasPresentation = ({
|
|
|
43
58
|
});
|
|
44
59
|
const effectsRef = useRef(memoizedEffects);
|
|
45
60
|
effectsRef.current = memoizedEffects;
|
|
46
|
-
const [instance] = useState(() => shader(
|
|
61
|
+
const [instance] = useState(() => shader(shaderCanvas));
|
|
47
62
|
useLayoutEffect(() => {
|
|
63
|
+
const canvas = canvasRef.current;
|
|
64
|
+
if (!canvas) {
|
|
65
|
+
return () => {
|
|
66
|
+
instance.cleanup();
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const captureCanvas = canvas.transferControlToOffscreen();
|
|
70
|
+
const captureContext = captureCanvas.getContext("2d");
|
|
71
|
+
if (!captureContext) {
|
|
72
|
+
throw new Error("Failed to create capture canvas context");
|
|
73
|
+
}
|
|
74
|
+
captureCanvasRef.current = captureCanvas;
|
|
75
|
+
captureContextRef.current = captureContext;
|
|
48
76
|
return () => {
|
|
49
77
|
instance.cleanup();
|
|
78
|
+
captureCanvasRef.current = null;
|
|
79
|
+
captureContextRef.current = null;
|
|
50
80
|
};
|
|
51
|
-
}, [
|
|
81
|
+
}, [instance]);
|
|
52
82
|
const chainState = Internals.useEffectChainState();
|
|
53
83
|
const { delayRender, continueRender } = useDelayRender();
|
|
54
84
|
const draw = useCallback(async (prevImage, nextImage, progress) => {
|
|
55
|
-
|
|
85
|
+
const outputCanvas = outputCanvasRef.current;
|
|
86
|
+
if (!outputCanvas) {
|
|
56
87
|
throw new Error("Canvas not found");
|
|
57
88
|
}
|
|
58
89
|
const handle = delayRender("onPaint");
|
|
90
|
+
const clearOutput = () => {
|
|
91
|
+
const context = outputCanvas.getContext("2d");
|
|
92
|
+
if (!context) {
|
|
93
|
+
throw new Error("Failed to create output canvas context");
|
|
94
|
+
}
|
|
95
|
+
context.clearRect(0, 0, outputCanvas.width, outputCanvas.height);
|
|
96
|
+
};
|
|
59
97
|
if (!prevImage && !nextImage) {
|
|
60
|
-
continueRender(handle);
|
|
61
98
|
instance.clear();
|
|
99
|
+
clearOutput();
|
|
100
|
+
continueRender(handle);
|
|
62
101
|
return;
|
|
63
102
|
}
|
|
64
103
|
const width = prevImage?.width ?? nextImage?.width ?? 0;
|
|
65
104
|
const height = prevImage?.height ?? nextImage?.height ?? 0;
|
|
66
105
|
if (width === 0 || height === 0) {
|
|
67
|
-
continueRender(handle);
|
|
68
106
|
instance.clear();
|
|
107
|
+
clearOutput();
|
|
108
|
+
continueRender(handle);
|
|
69
109
|
return;
|
|
70
110
|
}
|
|
71
|
-
|
|
72
|
-
|
|
111
|
+
shaderCanvas.width = width;
|
|
112
|
+
shaderCanvas.height = height;
|
|
73
113
|
instance.draw({
|
|
74
114
|
prevImage,
|
|
75
115
|
nextImage,
|
|
@@ -80,14 +120,14 @@ var HtmlInCanvasPresentation = ({
|
|
|
80
120
|
});
|
|
81
121
|
await Internals.runEffectChain({
|
|
82
122
|
state: chainState.get(width, height),
|
|
83
|
-
source:
|
|
123
|
+
source: shaderCanvas,
|
|
84
124
|
effects: effectsRef.current ?? [],
|
|
85
125
|
width,
|
|
86
126
|
height,
|
|
87
|
-
output:
|
|
127
|
+
output: outputCanvas
|
|
88
128
|
});
|
|
89
129
|
continueRender(handle);
|
|
90
|
-
}, [chainState,
|
|
130
|
+
}, [chainState, continueRender, delayRender, instance, shaderCanvas]);
|
|
91
131
|
const passThrough = bothEnteringAndExiting && presentationDirection === "exiting";
|
|
92
132
|
useLayoutEffect(() => {
|
|
93
133
|
if (passThrough) {
|
|
@@ -100,11 +140,19 @@ var HtmlInCanvasPresentation = ({
|
|
|
100
140
|
canvas.layoutSubtree = true;
|
|
101
141
|
const onPaint = () => {
|
|
102
142
|
const firstChild = canvas.firstChild;
|
|
103
|
-
|
|
143
|
+
const captureCanvas = captureCanvasRef.current;
|
|
144
|
+
const captureContext = captureContextRef.current;
|
|
145
|
+
if (!firstChild || !captureCanvas || !captureContext) {
|
|
104
146
|
return;
|
|
105
147
|
}
|
|
106
148
|
const elementImage = canvas.captureElementImage(firstChild);
|
|
107
|
-
|
|
149
|
+
try {
|
|
150
|
+
captureContext.reset();
|
|
151
|
+
captureContext.drawElementImage(elementImage, 0, 0);
|
|
152
|
+
} finally {
|
|
153
|
+
elementImage.close();
|
|
154
|
+
}
|
|
155
|
+
onElementImage(captureCanvas, draw);
|
|
108
156
|
};
|
|
109
157
|
canvas.addEventListener("paint", onPaint);
|
|
110
158
|
return () => {
|
|
@@ -138,20 +186,39 @@ var HtmlInCanvasPresentation = ({
|
|
|
138
186
|
return;
|
|
139
187
|
}
|
|
140
188
|
const observer = new ResizeObserver(([entry]) => {
|
|
141
|
-
|
|
142
|
-
|
|
189
|
+
const outputCanvas = outputCanvasRef.current;
|
|
190
|
+
const captureCanvas = captureCanvasRef.current;
|
|
191
|
+
if (!outputCanvas || !captureCanvas) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const width = entry.devicePixelContentBoxSize[0].inlineSize;
|
|
195
|
+
const height = entry.devicePixelContentBoxSize[0].blockSize;
|
|
196
|
+
captureCanvas.width = width;
|
|
197
|
+
captureCanvas.height = height;
|
|
198
|
+
outputCanvas.width = width;
|
|
199
|
+
outputCanvas.height = height;
|
|
200
|
+
canvas.requestPaint?.();
|
|
143
201
|
});
|
|
144
202
|
observer.observe(canvas, { box: "device-pixel-content-box" });
|
|
203
|
+
return () => {
|
|
204
|
+
observer.disconnect();
|
|
205
|
+
};
|
|
145
206
|
}, [passThrough]);
|
|
146
207
|
if (passThrough) {
|
|
147
208
|
return children;
|
|
148
209
|
}
|
|
149
|
-
return /* @__PURE__ */
|
|
150
|
-
children:
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
210
|
+
return /* @__PURE__ */ jsxs(AbsoluteFill, {
|
|
211
|
+
children: [
|
|
212
|
+
/* @__PURE__ */ jsx("canvas", {
|
|
213
|
+
ref: canvasRef,
|
|
214
|
+
style: canvasSubtreeStyle,
|
|
215
|
+
children
|
|
216
|
+
}),
|
|
217
|
+
/* @__PURE__ */ jsx("canvas", {
|
|
218
|
+
ref: outputCanvasRef,
|
|
219
|
+
style: outputCanvasStyle
|
|
220
|
+
})
|
|
221
|
+
]
|
|
155
222
|
});
|
|
156
223
|
};
|
|
157
224
|
var makeHtmlInCanvasPresentation = (shader) => {
|
|
@@ -173,6 +240,11 @@ var makeHtmlInCanvasPresentation = (shader) => {
|
|
|
173
240
|
};
|
|
174
241
|
};
|
|
175
242
|
|
|
243
|
+
// src/presentations/upload-element-image.ts
|
|
244
|
+
var uploadElementImage = (gl, elementImage) => {
|
|
245
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, elementImage);
|
|
246
|
+
};
|
|
247
|
+
|
|
176
248
|
// src/presentations/zoom-blur.tsx
|
|
177
249
|
var VERTEX_SHADER = `#version 300 es
|
|
178
250
|
in vec2 a_pos;
|
|
@@ -338,13 +410,13 @@ var zoomBlurShader = (canvas) => {
|
|
|
338
410
|
gl.activeTexture(gl.TEXTURE0);
|
|
339
411
|
gl.bindTexture(gl.TEXTURE_2D, prevTex);
|
|
340
412
|
if (prevImage) {
|
|
341
|
-
|
|
413
|
+
uploadElementImage(gl, prevImage);
|
|
342
414
|
}
|
|
343
415
|
gl.uniform1i(uPrev, 0);
|
|
344
416
|
gl.activeTexture(gl.TEXTURE1);
|
|
345
417
|
gl.bindTexture(gl.TEXTURE_2D, nextTex);
|
|
346
418
|
if (nextImage) {
|
|
347
|
-
|
|
419
|
+
uploadElementImage(gl, nextImage);
|
|
348
420
|
}
|
|
349
421
|
gl.uniform1i(uNext, 1);
|
|
350
422
|
gl.uniform1f(uTime, effectiveTime);
|