@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
|
@@ -9,8 +9,8 @@ type SeriesSequenceProps = PropsWithChildren<{
|
|
|
9
9
|
readonly durationInFrames: number;
|
|
10
10
|
readonly offset?: number;
|
|
11
11
|
readonly className?: string;
|
|
12
|
-
} & LayoutBasedProps & Pick<SequencePropsWithoutDuration, 'name' | 'showInTimeline' | 'freeze' | 'hidden'>>;
|
|
13
|
-
export type DrawFunction = (prevImage:
|
|
12
|
+
} & LayoutBasedProps & Pick<SequencePropsWithoutDuration, 'name' | 'showInTimeline' | 'freeze' | 'hidden' | 'trimBefore'>>;
|
|
13
|
+
export type DrawFunction = (prevImage: OffscreenCanvas | null, nextImage: OffscreenCanvas | null, progress: number) => void;
|
|
14
14
|
declare const TransitionSeries: FC<SequencePropsWithoutDuration> & {
|
|
15
15
|
Sequence: FC<SeriesSequenceProps>;
|
|
16
16
|
Transition: TransitionSeriesTransitionComponent;
|
package/dist/TransitionSeries.js
CHANGED
|
@@ -77,6 +77,7 @@ const transitionSeriesSequenceSchema = {
|
|
|
77
77
|
hidden: remotion_1.Internals.sequenceSchema.hidden,
|
|
78
78
|
showInTimeline: remotion_1.Internals.sequenceSchema.showInTimeline,
|
|
79
79
|
freeze: remotion_1.Internals.freezeField,
|
|
80
|
+
trimBefore: remotion_1.Internals.sequenceSchema.trimBefore,
|
|
80
81
|
layout: remotion_1.Internals.sequenceSchema.layout,
|
|
81
82
|
};
|
|
82
83
|
const SeriesSequenceInner = ({ offset = 0, className = '', stack = null, _remotionInternalRender = null, ...props }) => {
|
package/dist/esm/book-flip.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/book-flip.tsx
|
|
177
249
|
var DIRECTION_FROM_LEFT = 0;
|
|
178
250
|
var DIRECTION_FROM_RIGHT = 1;
|
|
@@ -408,13 +480,13 @@ var bookFlipShader = (canvas) => {
|
|
|
408
480
|
gl.activeTexture(gl.TEXTURE0);
|
|
409
481
|
gl.bindTexture(gl.TEXTURE_2D, prevTex);
|
|
410
482
|
if (prevImage) {
|
|
411
|
-
|
|
483
|
+
uploadElementImage(gl, prevImage);
|
|
412
484
|
}
|
|
413
485
|
gl.uniform1i(uPrev, 0);
|
|
414
486
|
gl.activeTexture(gl.TEXTURE1);
|
|
415
487
|
gl.bindTexture(gl.TEXTURE_2D, nextTex);
|
|
416
488
|
if (nextImage) {
|
|
417
|
-
|
|
489
|
+
uploadElementImage(gl, nextImage);
|
|
418
490
|
}
|
|
419
491
|
gl.uniform1i(uNext, 1);
|
|
420
492
|
gl.uniform1f(uTime, effectiveTime);
|
package/dist/esm/cross-zoom.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/cross-zoom.tsx
|
|
177
249
|
var DEFAULT_STRENGTH = 0.4;
|
|
178
250
|
var VERTEX_SHADER = `#version 300 es
|
|
@@ -351,13 +423,13 @@ var crossZoomShader = (canvas) => {
|
|
|
351
423
|
gl.activeTexture(gl.TEXTURE0);
|
|
352
424
|
gl.bindTexture(gl.TEXTURE_2D, prevTex);
|
|
353
425
|
if (prevImage) {
|
|
354
|
-
|
|
426
|
+
uploadElementImage(gl, prevImage);
|
|
355
427
|
}
|
|
356
428
|
gl.uniform1i(uPrev, 0);
|
|
357
429
|
gl.activeTexture(gl.TEXTURE1);
|
|
358
430
|
gl.bindTexture(gl.TEXTURE_2D, nextTex);
|
|
359
431
|
if (nextImage) {
|
|
360
|
-
|
|
432
|
+
uploadElementImage(gl, nextImage);
|
|
361
433
|
}
|
|
362
434
|
gl.uniform1i(uNext, 1);
|
|
363
435
|
gl.uniform1f(uTime, effectiveTime);
|
package/dist/esm/crosswarp.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/crosswarp.tsx
|
|
177
249
|
var VERTEX_SHADER = `#version 300 es
|
|
178
250
|
in vec2 a_pos;
|
|
@@ -306,13 +378,13 @@ var crosswarpShader = (canvas) => {
|
|
|
306
378
|
gl.activeTexture(gl.TEXTURE0);
|
|
307
379
|
gl.bindTexture(gl.TEXTURE_2D, prevTex);
|
|
308
380
|
if (prevImage) {
|
|
309
|
-
|
|
381
|
+
uploadElementImage(gl, prevImage);
|
|
310
382
|
}
|
|
311
383
|
gl.uniform1i(uPrev, 0);
|
|
312
384
|
gl.activeTexture(gl.TEXTURE1);
|
|
313
385
|
gl.bindTexture(gl.TEXTURE_2D, nextTex);
|
|
314
386
|
if (nextImage) {
|
|
315
|
-
|
|
387
|
+
uploadElementImage(gl, nextImage);
|
|
316
388
|
}
|
|
317
389
|
gl.uniform1i(uNext, 1);
|
|
318
390
|
gl.uniform1f(uTime, effectiveTime);
|