@remotion/transitions 4.0.466 → 4.0.467
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/cross-zoom.js +2 -0
- package/dist/esm/book-flip.mjs +4 -3
- package/dist/esm/cross-zoom.mjs +377 -0
- package/dist/esm/crosswarp.mjs +4 -3
- package/dist/esm/dissolve.mjs +4 -3
- package/dist/esm/dreamy-zoom.mjs +4 -3
- package/dist/esm/film-burn.mjs +443 -0
- package/dist/esm/index.mjs +492 -25
- package/dist/esm/linear-blur.mjs +4 -3
- package/dist/esm/ripple.mjs +4 -3
- package/dist/esm/swap.mjs +4 -3
- package/dist/esm/zoom-blur.mjs +4 -3
- package/dist/esm/zoom-in-out.mjs +4 -3
- package/dist/html-in-canvas-presentation.js +4 -5
- package/dist/index.d.ts +6 -2
- package/dist/index.js +7 -3
- package/dist/presentations/cross-zoom.d.ts +13 -0
- package/dist/presentations/cross-zoom.js +199 -0
- package/dist/presentations/film-burn.d.ts +13 -0
- package/dist/presentations/film-burn.js +265 -0
- package/dist/types.d.ts +1 -1
- package/film-burn.js +2 -0
- package/package.json +26 -8
|
@@ -4,7 +4,6 @@ exports.makeHtmlInCanvasPresentation = exports.HtmlInCanvasPresentation = 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 remotion_2 = require("remotion");
|
|
8
7
|
const HtmlInCanvasPresentation = ({ children, onElementImage, onUnmount, presentationProgress, presentationDirection, shader, effects, passedProps, bothEnteringAndExiting, }) => {
|
|
9
8
|
if (!remotion_1.HtmlInCanvas.isSupported()) {
|
|
10
9
|
throw new Error(remotion_1.HTML_IN_CANVAS_UNSUPPORTED_MESSAGE);
|
|
@@ -24,7 +23,7 @@ const HtmlInCanvasPresentation = ({ children, onElementImage, onUnmount, present
|
|
|
24
23
|
const [offscreenCanvas] = (0, react_1.useState)(() => new OffscreenCanvas(1, 1));
|
|
25
24
|
const passedPropsRef = (0, react_1.useRef)(passedProps);
|
|
26
25
|
passedPropsRef.current = passedProps;
|
|
27
|
-
const memoizedEffects =
|
|
26
|
+
const memoizedEffects = remotion_1.Internals.useMemoizedEffects({
|
|
28
27
|
effects: effects !== null && effects !== void 0 ? effects : [],
|
|
29
28
|
overrideId: null,
|
|
30
29
|
});
|
|
@@ -36,7 +35,7 @@ const HtmlInCanvasPresentation = ({ children, onElementImage, onUnmount, present
|
|
|
36
35
|
instance.cleanup();
|
|
37
36
|
};
|
|
38
37
|
}, [offscreenCanvas, instance]);
|
|
39
|
-
const chainState =
|
|
38
|
+
const chainState = remotion_1.Internals.useEffectChainState();
|
|
40
39
|
const { delayRender, continueRender } = (0, remotion_1.useDelayRender)();
|
|
41
40
|
const draw = (0, react_1.useCallback)(async (prevImage, nextImage, progress) => {
|
|
42
41
|
var _a, _b, _c, _d, _e;
|
|
@@ -66,7 +65,7 @@ const HtmlInCanvasPresentation = ({ children, onElementImage, onUnmount, present
|
|
|
66
65
|
time: progress,
|
|
67
66
|
passedProps: passedPropsRef.current,
|
|
68
67
|
});
|
|
69
|
-
await
|
|
68
|
+
await remotion_1.Internals.runEffectChain({
|
|
70
69
|
state: chainState.get(width, height),
|
|
71
70
|
source: offscreenCanvas,
|
|
72
71
|
effects: (_e = effectsRef.current) !== null && _e !== void 0 ? _e : [],
|
|
@@ -136,7 +135,7 @@ const HtmlInCanvasPresentation = ({ children, onElementImage, onUnmount, present
|
|
|
136
135
|
if (passThrough) {
|
|
137
136
|
return children;
|
|
138
137
|
}
|
|
139
|
-
return (jsx_runtime_1.jsx(
|
|
138
|
+
return (jsx_runtime_1.jsx(remotion_1.AbsoluteFill, { children: jsx_runtime_1.jsx("canvas", { ref: canvasRef, style: canvasSubtreeStyle, children: children }) }));
|
|
140
139
|
};
|
|
141
140
|
exports.HtmlInCanvasPresentation = HtmlInCanvasPresentation;
|
|
142
141
|
const makeHtmlInCanvasPresentation = (shader) => {
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,11 @@ export { useTransitionProgress } from './use-transition-progress.js';
|
|
|
6
6
|
export type { TransitionState } from './use-transition-progress.js';
|
|
7
7
|
export { makeHtmlInCanvasPresentation } from './html-in-canvas-presentation.js';
|
|
8
8
|
export type { HtmlInCanvasShader, HtmlInCanvasShaderDraw, HtmlInCanvasShaderDrawParams, } from './html-in-canvas-presentation.js';
|
|
9
|
-
export {
|
|
10
|
-
export type {
|
|
9
|
+
export { crossZoom } from './presentations/cross-zoom.js';
|
|
10
|
+
export type { CrossZoomProps } from './presentations/cross-zoom.js';
|
|
11
11
|
export { dreamyZoom } from './presentations/dreamy-zoom.js';
|
|
12
12
|
export type { DreamyZoomProps } from './presentations/dreamy-zoom.js';
|
|
13
|
+
export { filmBurn } from './presentations/film-burn.js';
|
|
14
|
+
export type { FilmBurnProps } from './presentations/film-burn.js';
|
|
15
|
+
export { linearBlur } from './presentations/linear-blur.js';
|
|
16
|
+
export type { LinearBlurProps } from './presentations/linear-blur.js';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.dreamyZoom = exports.
|
|
3
|
+
exports.linearBlur = exports.filmBurn = exports.dreamyZoom = exports.crossZoom = exports.makeHtmlInCanvasPresentation = exports.useTransitionProgress = exports.TransitionSeries = exports.springTiming = exports.linearTiming = void 0;
|
|
4
4
|
// Timings
|
|
5
5
|
const linear_timing_js_1 = require("./timings/linear-timing.js");
|
|
6
6
|
Object.defineProperty(exports, "linearTiming", { enumerable: true, get: function () { return linear_timing_js_1.linearTiming; } });
|
|
@@ -15,7 +15,11 @@ Object.defineProperty(exports, "useTransitionProgress", { enumerable: true, get:
|
|
|
15
15
|
// HTML-in-canvas
|
|
16
16
|
const html_in_canvas_presentation_js_1 = require("./html-in-canvas-presentation.js");
|
|
17
17
|
Object.defineProperty(exports, "makeHtmlInCanvasPresentation", { enumerable: true, get: function () { return html_in_canvas_presentation_js_1.makeHtmlInCanvasPresentation; } });
|
|
18
|
-
const
|
|
19
|
-
Object.defineProperty(exports, "
|
|
18
|
+
const cross_zoom_js_1 = require("./presentations/cross-zoom.js");
|
|
19
|
+
Object.defineProperty(exports, "crossZoom", { enumerable: true, get: function () { return cross_zoom_js_1.crossZoom; } });
|
|
20
20
|
const dreamy_zoom_js_1 = require("./presentations/dreamy-zoom.js");
|
|
21
21
|
Object.defineProperty(exports, "dreamyZoom", { enumerable: true, get: function () { return dreamy_zoom_js_1.dreamyZoom; } });
|
|
22
|
+
const film_burn_js_1 = require("./presentations/film-burn.js");
|
|
23
|
+
Object.defineProperty(exports, "filmBurn", { enumerable: true, get: function () { return film_burn_js_1.filmBurn; } });
|
|
24
|
+
const linear_blur_js_1 = require("./presentations/linear-blur.js");
|
|
25
|
+
Object.defineProperty(exports, "linearBlur", { enumerable: true, get: function () { return linear_blur_js_1.linearBlur; } });
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type CrossZoomProps = {
|
|
2
|
+
strength?: number;
|
|
3
|
+
};
|
|
4
|
+
export declare const crossZoomShader: (canvas: OffscreenCanvas) => {
|
|
5
|
+
clear: () => void;
|
|
6
|
+
cleanup: () => void;
|
|
7
|
+
draw: import("..").HtmlInCanvasShaderDraw<CrossZoomProps>;
|
|
8
|
+
};
|
|
9
|
+
export declare const crossZoom: (props: CrossZoomProps & {
|
|
10
|
+
effects?: import("remotion").EffectsProp | undefined;
|
|
11
|
+
}) => import("..").TransitionPresentation<CrossZoomProps & {
|
|
12
|
+
effects?: import("remotion").EffectsProp | undefined;
|
|
13
|
+
}>;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.crossZoom = exports.crossZoomShader = void 0;
|
|
4
|
+
const html_in_canvas_presentation_1 = require("../html-in-canvas-presentation");
|
|
5
|
+
const DEFAULT_STRENGTH = 0.4;
|
|
6
|
+
const VERTEX_SHADER = `#version 300 es
|
|
7
|
+
in vec2 a_pos;
|
|
8
|
+
out vec2 v_uv;
|
|
9
|
+
void main() {
|
|
10
|
+
v_uv = vec2(a_pos.x * 0.5 + 0.5, 0.5 - a_pos.y * 0.5);
|
|
11
|
+
gl_Position = vec4(a_pos, 0.0, 1.0);
|
|
12
|
+
}`;
|
|
13
|
+
// Adapted from https://gl-transitions.com/editor/CrossZoom
|
|
14
|
+
// Author: rectalogic · License: MIT
|
|
15
|
+
const FRAGMENT_SHADER = `#version 300 es
|
|
16
|
+
precision highp float;
|
|
17
|
+
|
|
18
|
+
uniform sampler2D u_prev;
|
|
19
|
+
uniform sampler2D u_next;
|
|
20
|
+
uniform float u_time;
|
|
21
|
+
uniform float u_strength;
|
|
22
|
+
|
|
23
|
+
in vec2 v_uv;
|
|
24
|
+
out vec4 outColor;
|
|
25
|
+
|
|
26
|
+
const float PI = 3.141592653589793;
|
|
27
|
+
|
|
28
|
+
float linearEase(float begin, float change, float duration, float time) {
|
|
29
|
+
return change * time / duration + begin;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
float exponentialEaseInOut(float begin, float change, float duration, float time) {
|
|
33
|
+
if (time == 0.0) {
|
|
34
|
+
return begin;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (time == duration) {
|
|
38
|
+
return begin + change;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
float t = time / (duration / 2.0);
|
|
42
|
+
if (t < 1.0) {
|
|
43
|
+
return change / 2.0 * pow(2.0, 10.0 * (t - 1.0)) + begin;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return change / 2.0 * (-pow(2.0, -10.0 * (t - 1.0)) + 2.0) + begin;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
float sinusoidalEaseInOut(float begin, float change, float duration, float time) {
|
|
50
|
+
return -change / 2.0 * (cos(PI * time / duration) - 1.0) + begin;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
float random(vec2 co) {
|
|
54
|
+
return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
vec4 crossFade(vec2 uv, float dissolve) {
|
|
58
|
+
return mix(texture(u_prev, uv), texture(u_next, uv), dissolve);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
vec4 transition(vec2 uv, float progress) {
|
|
62
|
+
vec2 center = vec2(linearEase(0.25, 0.5, 1.0, progress), 0.5);
|
|
63
|
+
float dissolve = exponentialEaseInOut(0.0, 1.0, 1.0, progress);
|
|
64
|
+
float strength = sinusoidalEaseInOut(0.0, u_strength, 0.5, progress);
|
|
65
|
+
|
|
66
|
+
vec4 color = vec4(0.0);
|
|
67
|
+
float total = 0.0;
|
|
68
|
+
vec2 toCenter = center - uv;
|
|
69
|
+
float offset = random(uv);
|
|
70
|
+
|
|
71
|
+
for (int i = 0; i <= 40; i++) {
|
|
72
|
+
float percent = (float(i) + offset) / 40.0;
|
|
73
|
+
float weight = 4.0 * (percent - percent * percent);
|
|
74
|
+
color += crossFade(uv + toCenter * percent * strength, dissolve) * weight;
|
|
75
|
+
total += weight;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return color / total;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
void main() {
|
|
82
|
+
float progress = 1.0 - u_time;
|
|
83
|
+
outColor = transition(v_uv, progress);
|
|
84
|
+
}`;
|
|
85
|
+
const compileShader = (gl, source, type) => {
|
|
86
|
+
const shader = gl.createShader(type);
|
|
87
|
+
if (!shader) {
|
|
88
|
+
throw new Error('Failed to create shader');
|
|
89
|
+
}
|
|
90
|
+
gl.shaderSource(shader, source);
|
|
91
|
+
gl.compileShader(shader);
|
|
92
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
93
|
+
const log = gl.getShaderInfoLog(shader);
|
|
94
|
+
gl.deleteShader(shader);
|
|
95
|
+
throw new Error(`Failed to compile shader: ${log}`);
|
|
96
|
+
}
|
|
97
|
+
return shader;
|
|
98
|
+
};
|
|
99
|
+
const createProgram = (gl) => {
|
|
100
|
+
const program = gl.createProgram();
|
|
101
|
+
if (!program) {
|
|
102
|
+
throw new Error('Failed to create WebGL program');
|
|
103
|
+
}
|
|
104
|
+
const vs = compileShader(gl, VERTEX_SHADER, gl.VERTEX_SHADER);
|
|
105
|
+
const fs = compileShader(gl, FRAGMENT_SHADER, gl.FRAGMENT_SHADER);
|
|
106
|
+
gl.attachShader(program, vs);
|
|
107
|
+
gl.attachShader(program, fs);
|
|
108
|
+
gl.linkProgram(program);
|
|
109
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
110
|
+
const log = gl.getProgramInfoLog(program);
|
|
111
|
+
gl.deleteProgram(program);
|
|
112
|
+
throw new Error(`Failed to link program: ${log}`);
|
|
113
|
+
}
|
|
114
|
+
return program;
|
|
115
|
+
};
|
|
116
|
+
const createTexture = (gl) => {
|
|
117
|
+
const tex = gl.createTexture();
|
|
118
|
+
if (!tex) {
|
|
119
|
+
throw new Error('Failed to create texture');
|
|
120
|
+
}
|
|
121
|
+
gl.bindTexture(gl.TEXTURE_2D, tex);
|
|
122
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
123
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
124
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
125
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
126
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 0]));
|
|
127
|
+
return tex;
|
|
128
|
+
};
|
|
129
|
+
const crossZoomShader = (canvas) => {
|
|
130
|
+
const gl = canvas.getContext('webgl2', { premultipliedAlpha: true });
|
|
131
|
+
if (!gl) {
|
|
132
|
+
throw new Error('Failed to create WebGL2 context');
|
|
133
|
+
}
|
|
134
|
+
const program = createProgram(gl);
|
|
135
|
+
const prevTex = createTexture(gl);
|
|
136
|
+
const nextTex = createTexture(gl);
|
|
137
|
+
const vao = gl.createVertexArray();
|
|
138
|
+
gl.bindVertexArray(vao);
|
|
139
|
+
const buffer = gl.createBuffer();
|
|
140
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
141
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);
|
|
142
|
+
const aPos = gl.getAttribLocation(program, 'a_pos');
|
|
143
|
+
gl.enableVertexAttribArray(aPos);
|
|
144
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
|
|
145
|
+
const uTime = gl.getUniformLocation(program, 'u_time');
|
|
146
|
+
const uPrev = gl.getUniformLocation(program, 'u_prev');
|
|
147
|
+
const uNext = gl.getUniformLocation(program, 'u_next');
|
|
148
|
+
const uStrength = gl.getUniformLocation(program, 'u_strength');
|
|
149
|
+
const cleanup = () => {
|
|
150
|
+
gl.deleteProgram(program);
|
|
151
|
+
gl.deleteTexture(prevTex);
|
|
152
|
+
gl.deleteTexture(nextTex);
|
|
153
|
+
};
|
|
154
|
+
const clear = () => {
|
|
155
|
+
gl.clearColor(0, 0, 0, 0);
|
|
156
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
157
|
+
};
|
|
158
|
+
const draw = ({ prevImage, nextImage, width, height, time, passedProps, }) => {
|
|
159
|
+
const { strength = DEFAULT_STRENGTH } = passedProps;
|
|
160
|
+
if (!prevImage && !nextImage) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (prevImage && (prevImage.width === 0 || prevImage.height === 0)) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (nextImage && (nextImage.width === 0 || nextImage.height === 0)) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
// When one side is missing, force the mix to fully show the other.
|
|
170
|
+
// At time=0 the shader outputs nextImage. At time=1 the shader outputs prevImage.
|
|
171
|
+
const effectiveTime = !prevImage ? 0 : !nextImage ? 1 : time;
|
|
172
|
+
gl.viewport(0, 0, width, height);
|
|
173
|
+
gl.clearColor(0, 0, 0, 0);
|
|
174
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
175
|
+
gl.useProgram(program);
|
|
176
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
177
|
+
gl.bindTexture(gl.TEXTURE_2D, prevTex);
|
|
178
|
+
if (prevImage) {
|
|
179
|
+
gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, prevImage);
|
|
180
|
+
}
|
|
181
|
+
gl.uniform1i(uPrev, 0);
|
|
182
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
183
|
+
gl.bindTexture(gl.TEXTURE_2D, nextTex);
|
|
184
|
+
if (nextImage) {
|
|
185
|
+
gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, nextImage);
|
|
186
|
+
}
|
|
187
|
+
gl.uniform1i(uNext, 1);
|
|
188
|
+
gl.uniform1f(uTime, effectiveTime);
|
|
189
|
+
gl.uniform1f(uStrength, strength);
|
|
190
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
191
|
+
};
|
|
192
|
+
return {
|
|
193
|
+
clear,
|
|
194
|
+
cleanup,
|
|
195
|
+
draw,
|
|
196
|
+
};
|
|
197
|
+
};
|
|
198
|
+
exports.crossZoomShader = crossZoomShader;
|
|
199
|
+
exports.crossZoom = (0, html_in_canvas_presentation_1.makeHtmlInCanvasPresentation)(exports.crossZoomShader);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type FilmBurnProps = {
|
|
2
|
+
seed?: number;
|
|
3
|
+
};
|
|
4
|
+
export declare const filmBurnShader: (canvas: OffscreenCanvas) => {
|
|
5
|
+
clear: () => void;
|
|
6
|
+
cleanup: () => void;
|
|
7
|
+
draw: import("..").HtmlInCanvasShaderDraw<FilmBurnProps>;
|
|
8
|
+
};
|
|
9
|
+
export declare const filmBurn: (props: FilmBurnProps & {
|
|
10
|
+
effects?: import("remotion").EffectsProp | undefined;
|
|
11
|
+
}) => import("..").TransitionPresentation<FilmBurnProps & {
|
|
12
|
+
effects?: import("remotion").EffectsProp | undefined;
|
|
13
|
+
}>;
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.filmBurn = exports.filmBurnShader = void 0;
|
|
4
|
+
const html_in_canvas_presentation_1 = require("../html-in-canvas-presentation");
|
|
5
|
+
const DEFAULT_SEED = 2.31;
|
|
6
|
+
const VERTEX_SHADER = `#version 300 es
|
|
7
|
+
in vec2 a_pos;
|
|
8
|
+
out vec2 v_uv;
|
|
9
|
+
void main() {
|
|
10
|
+
v_uv = vec2(a_pos.x * 0.5 + 0.5, 0.5 - a_pos.y * 0.5);
|
|
11
|
+
gl_Position = vec4(a_pos, 0.0, 1.0);
|
|
12
|
+
}`;
|
|
13
|
+
// Adapted from https://gl-transitions.com/editor/FilmBurn
|
|
14
|
+
// Author: Anastasia Dunbar · License: MIT
|
|
15
|
+
const FRAGMENT_SHADER = `#version 300 es
|
|
16
|
+
precision highp float;
|
|
17
|
+
|
|
18
|
+
uniform sampler2D u_prev;
|
|
19
|
+
uniform sampler2D u_next;
|
|
20
|
+
uniform float u_time;
|
|
21
|
+
uniform float u_seed;
|
|
22
|
+
|
|
23
|
+
in vec2 v_uv;
|
|
24
|
+
out vec4 outColor;
|
|
25
|
+
|
|
26
|
+
#define PI 3.14159265358979323
|
|
27
|
+
#define CLAMPS(x) clamp(x, 0.0, 1.0)
|
|
28
|
+
#define REPEATS 50.0
|
|
29
|
+
|
|
30
|
+
float sigmoid(float x, float a) {
|
|
31
|
+
float b = pow(x * 2.0, a) / 2.0;
|
|
32
|
+
if (x > 0.5) {
|
|
33
|
+
b = 1.0 - pow(2.0 - (x * 2.0), a) / 2.0;
|
|
34
|
+
}
|
|
35
|
+
return b;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
float rand(float co) {
|
|
39
|
+
return fract(sin((co * 24.9898) + u_seed) * 43758.5453);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
float rand(vec2 co) {
|
|
43
|
+
return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
float apow(float a, float b) {
|
|
47
|
+
return pow(abs(a), b) * sign(b);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
vec3 pow3(vec3 a, vec3 b) {
|
|
51
|
+
return vec3(apow(a.r, b.r), apow(a.g, b.g), apow(a.b, b.b));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
float smoothMix(float a, float b, float c) {
|
|
55
|
+
return mix(a, b, sigmoid(c, 2.0));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
float random(vec2 co, float shft) {
|
|
59
|
+
co += 10.0;
|
|
60
|
+
return smoothMix(
|
|
61
|
+
fract(
|
|
62
|
+
sin(
|
|
63
|
+
dot(
|
|
64
|
+
co.xy,
|
|
65
|
+
vec2(12.9898 + (floor(shft) * 0.5), 78.233 + u_seed)
|
|
66
|
+
)
|
|
67
|
+
) * 43758.5453
|
|
68
|
+
),
|
|
69
|
+
fract(
|
|
70
|
+
sin(
|
|
71
|
+
dot(
|
|
72
|
+
co.xy,
|
|
73
|
+
vec2(12.9898 + (floor(shft + 1.0) * 0.5), 78.233 + u_seed)
|
|
74
|
+
)
|
|
75
|
+
) * 43758.5453
|
|
76
|
+
),
|
|
77
|
+
fract(shft)
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
float smoothRandom(vec2 co, float shft) {
|
|
82
|
+
return smoothMix(
|
|
83
|
+
smoothMix(
|
|
84
|
+
random(floor(co), shft),
|
|
85
|
+
random(floor(co + vec2(1.0, 0.0)), shft),
|
|
86
|
+
fract(co.x)
|
|
87
|
+
),
|
|
88
|
+
smoothMix(
|
|
89
|
+
random(floor(co + vec2(0.0, 1.0)), shft),
|
|
90
|
+
random(floor(co + vec2(1.0, 1.0)), shft),
|
|
91
|
+
fract(co.x)
|
|
92
|
+
),
|
|
93
|
+
fract(co.y)
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
vec4 sampleTexture(vec2 p, float progress) {
|
|
98
|
+
return mix(texture(u_prev, p), texture(u_next, p), sigmoid(progress, 10.0));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
vec4 transition(vec2 p, float progress) {
|
|
102
|
+
vec3 f = vec3(0.0);
|
|
103
|
+
for (float i = 0.0; i < 13.0; i++) {
|
|
104
|
+
f += sin(((p.x * rand(i) * 6.0) + (progress * 8.0)) + rand(i + 1.43)) *
|
|
105
|
+
sin(
|
|
106
|
+
((p.y * rand(i + 4.4) * 6.0) + (progress * 6.0)) +
|
|
107
|
+
rand(i + 2.4)
|
|
108
|
+
);
|
|
109
|
+
f += 1.0 - CLAMPS(
|
|
110
|
+
length(
|
|
111
|
+
p -
|
|
112
|
+
vec2(
|
|
113
|
+
smoothRandom(vec2(progress * 1.3), i + 1.0),
|
|
114
|
+
smoothRandom(vec2(progress * 0.5), i + 6.25)
|
|
115
|
+
)
|
|
116
|
+
) * mix(20.0, 70.0, rand(i))
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
f += 4.0;
|
|
121
|
+
f /= 11.0;
|
|
122
|
+
f = pow3(
|
|
123
|
+
f * vec3(1.0, 0.7, 0.6),
|
|
124
|
+
vec3(1.0, 2.0 - sin(progress * PI), 1.3)
|
|
125
|
+
);
|
|
126
|
+
f *= sin(progress * PI);
|
|
127
|
+
|
|
128
|
+
p -= 0.5;
|
|
129
|
+
p *= 1.0 + (smoothRandom(vec2(progress * 5.0), 6.3) * sin(progress * PI) * 0.05);
|
|
130
|
+
p += 0.5;
|
|
131
|
+
|
|
132
|
+
vec4 blurredImage = vec4(0.0);
|
|
133
|
+
float blurAmount = sin(progress * PI) * 0.03;
|
|
134
|
+
for (float i = 0.0; i < REPEATS; i++) {
|
|
135
|
+
vec2 q = vec2(
|
|
136
|
+
cos(degrees((i / REPEATS) * 360.0)),
|
|
137
|
+
sin(degrees((i / REPEATS) * 360.0))
|
|
138
|
+
) * (rand(vec2(i, p.x + p.y)) + blurAmount);
|
|
139
|
+
vec2 uv2 = p + (q * blurAmount);
|
|
140
|
+
blurredImage += sampleTexture(uv2, progress);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
blurredImage /= REPEATS;
|
|
144
|
+
return blurredImage + vec4(f, 0.0);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
void main() {
|
|
148
|
+
float progress = 1.0 - u_time;
|
|
149
|
+
outColor = transition(v_uv, progress);
|
|
150
|
+
}`;
|
|
151
|
+
const compileShader = (gl, source, type) => {
|
|
152
|
+
const shader = gl.createShader(type);
|
|
153
|
+
if (!shader) {
|
|
154
|
+
throw new Error('Failed to create shader');
|
|
155
|
+
}
|
|
156
|
+
gl.shaderSource(shader, source);
|
|
157
|
+
gl.compileShader(shader);
|
|
158
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
159
|
+
const log = gl.getShaderInfoLog(shader);
|
|
160
|
+
gl.deleteShader(shader);
|
|
161
|
+
throw new Error(`Failed to compile shader: ${log}`);
|
|
162
|
+
}
|
|
163
|
+
return shader;
|
|
164
|
+
};
|
|
165
|
+
const createProgram = (gl) => {
|
|
166
|
+
const program = gl.createProgram();
|
|
167
|
+
if (!program) {
|
|
168
|
+
throw new Error('Failed to create WebGL program');
|
|
169
|
+
}
|
|
170
|
+
const vs = compileShader(gl, VERTEX_SHADER, gl.VERTEX_SHADER);
|
|
171
|
+
const fs = compileShader(gl, FRAGMENT_SHADER, gl.FRAGMENT_SHADER);
|
|
172
|
+
gl.attachShader(program, vs);
|
|
173
|
+
gl.attachShader(program, fs);
|
|
174
|
+
gl.linkProgram(program);
|
|
175
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
176
|
+
const log = gl.getProgramInfoLog(program);
|
|
177
|
+
gl.deleteProgram(program);
|
|
178
|
+
throw new Error(`Failed to link program: ${log}`);
|
|
179
|
+
}
|
|
180
|
+
return program;
|
|
181
|
+
};
|
|
182
|
+
const createTexture = (gl) => {
|
|
183
|
+
const tex = gl.createTexture();
|
|
184
|
+
if (!tex) {
|
|
185
|
+
throw new Error('Failed to create texture');
|
|
186
|
+
}
|
|
187
|
+
gl.bindTexture(gl.TEXTURE_2D, tex);
|
|
188
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
189
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
190
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
191
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
192
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 0]));
|
|
193
|
+
return tex;
|
|
194
|
+
};
|
|
195
|
+
const filmBurnShader = (canvas) => {
|
|
196
|
+
const gl = canvas.getContext('webgl2', { premultipliedAlpha: true });
|
|
197
|
+
if (!gl) {
|
|
198
|
+
throw new Error('Failed to create WebGL2 context');
|
|
199
|
+
}
|
|
200
|
+
const program = createProgram(gl);
|
|
201
|
+
const prevTex = createTexture(gl);
|
|
202
|
+
const nextTex = createTexture(gl);
|
|
203
|
+
const vao = gl.createVertexArray();
|
|
204
|
+
gl.bindVertexArray(vao);
|
|
205
|
+
const buffer = gl.createBuffer();
|
|
206
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
207
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);
|
|
208
|
+
const aPos = gl.getAttribLocation(program, 'a_pos');
|
|
209
|
+
gl.enableVertexAttribArray(aPos);
|
|
210
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
|
|
211
|
+
const uTime = gl.getUniformLocation(program, 'u_time');
|
|
212
|
+
const uPrev = gl.getUniformLocation(program, 'u_prev');
|
|
213
|
+
const uNext = gl.getUniformLocation(program, 'u_next');
|
|
214
|
+
const uSeed = gl.getUniformLocation(program, 'u_seed');
|
|
215
|
+
const cleanup = () => {
|
|
216
|
+
gl.deleteProgram(program);
|
|
217
|
+
gl.deleteTexture(prevTex);
|
|
218
|
+
gl.deleteTexture(nextTex);
|
|
219
|
+
};
|
|
220
|
+
const clear = () => {
|
|
221
|
+
gl.clearColor(0, 0, 0, 0);
|
|
222
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
223
|
+
};
|
|
224
|
+
const draw = ({ prevImage, nextImage, width, height, time, passedProps, }) => {
|
|
225
|
+
const { seed = DEFAULT_SEED } = passedProps;
|
|
226
|
+
if (!prevImage && !nextImage) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (prevImage && (prevImage.width === 0 || prevImage.height === 0)) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (nextImage && (nextImage.width === 0 || nextImage.height === 0)) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
// When one side is missing, force the mix to fully show the other.
|
|
236
|
+
// At time=0 the shader outputs nextImage. At time=1 the shader outputs prevImage.
|
|
237
|
+
const effectiveTime = !prevImage ? 0 : !nextImage ? 1 : time;
|
|
238
|
+
gl.viewport(0, 0, width, height);
|
|
239
|
+
gl.clearColor(0, 0, 0, 0);
|
|
240
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
241
|
+
gl.useProgram(program);
|
|
242
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
243
|
+
gl.bindTexture(gl.TEXTURE_2D, prevTex);
|
|
244
|
+
if (prevImage) {
|
|
245
|
+
gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, prevImage);
|
|
246
|
+
}
|
|
247
|
+
gl.uniform1i(uPrev, 0);
|
|
248
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
249
|
+
gl.bindTexture(gl.TEXTURE_2D, nextTex);
|
|
250
|
+
if (nextImage) {
|
|
251
|
+
gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, nextImage);
|
|
252
|
+
}
|
|
253
|
+
gl.uniform1i(uNext, 1);
|
|
254
|
+
gl.uniform1f(uTime, effectiveTime);
|
|
255
|
+
gl.uniform1f(uSeed, seed);
|
|
256
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
257
|
+
};
|
|
258
|
+
return {
|
|
259
|
+
clear,
|
|
260
|
+
cleanup,
|
|
261
|
+
draw,
|
|
262
|
+
};
|
|
263
|
+
};
|
|
264
|
+
exports.filmBurnShader = filmBurnShader;
|
|
265
|
+
exports.filmBurn = (0, html_in_canvas_presentation_1.makeHtmlInCanvasPresentation)(exports.filmBurnShader);
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ComponentType } from 'react';
|
|
2
1
|
import type React from 'react';
|
|
2
|
+
import type { ComponentType } from 'react';
|
|
3
3
|
import type { DrawFunction } from './TransitionSeries';
|
|
4
4
|
export type PresentationDirection = 'entering' | 'exiting';
|
|
5
5
|
export type TransitionTiming = {
|
package/film-burn.js
ADDED
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/transitions"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/transitions",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.467",
|
|
7
7
|
"description": "Library for creating transitions in Remotion",
|
|
8
8
|
"main": "dist/esm/index.mjs",
|
|
9
9
|
"module": "dist/esm/index.js",
|
|
@@ -22,18 +22,18 @@
|
|
|
22
22
|
"url": "https://github.com/remotion-dev/remotion/issues"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"remotion": "4.0.
|
|
26
|
-
"@remotion/shapes": "4.0.
|
|
27
|
-
"@remotion/paths": "4.0.
|
|
25
|
+
"remotion": "4.0.467",
|
|
26
|
+
"@remotion/shapes": "4.0.467",
|
|
27
|
+
"@remotion/paths": "4.0.467"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@happy-dom/global-registrator": "14.5.1",
|
|
31
|
-
"remotion": "4.0.
|
|
31
|
+
"remotion": "4.0.467",
|
|
32
32
|
"react": "19.2.3",
|
|
33
33
|
"react-dom": "19.2.3",
|
|
34
|
-
"@remotion/test-utils": "4.0.
|
|
35
|
-
"@remotion/player": "4.0.
|
|
36
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
34
|
+
"@remotion/test-utils": "4.0.467",
|
|
35
|
+
"@remotion/player": "4.0.467",
|
|
36
|
+
"@remotion/eslint-config-internal": "4.0.467",
|
|
37
37
|
"eslint": "9.19.0",
|
|
38
38
|
"@typescript/native-preview": "7.0.0-dev.20260217.1"
|
|
39
39
|
},
|
|
@@ -103,6 +103,12 @@
|
|
|
103
103
|
"import": "./dist/esm/dreamy-zoom.mjs",
|
|
104
104
|
"require": "./dist/presentations/dreamy-zoom.js"
|
|
105
105
|
},
|
|
106
|
+
"./film-burn": {
|
|
107
|
+
"types": "./dist/presentations/film-burn.d.ts",
|
|
108
|
+
"module": "./dist/esm/film-burn.mjs",
|
|
109
|
+
"import": "./dist/esm/film-burn.mjs",
|
|
110
|
+
"require": "./dist/presentations/film-burn.js"
|
|
111
|
+
},
|
|
106
112
|
"./linear-blur": {
|
|
107
113
|
"types": "./dist/presentations/linear-blur.d.ts",
|
|
108
114
|
"module": "./dist/esm/linear-blur.mjs",
|
|
@@ -145,6 +151,12 @@
|
|
|
145
151
|
"import": "./dist/esm/crosswarp.mjs",
|
|
146
152
|
"require": "./dist/presentations/crosswarp.js"
|
|
147
153
|
},
|
|
154
|
+
"./cross-zoom": {
|
|
155
|
+
"types": "./dist/presentations/cross-zoom.d.ts",
|
|
156
|
+
"module": "./dist/esm/cross-zoom.mjs",
|
|
157
|
+
"import": "./dist/esm/cross-zoom.mjs",
|
|
158
|
+
"require": "./dist/presentations/cross-zoom.js"
|
|
159
|
+
},
|
|
148
160
|
"./swap": {
|
|
149
161
|
"types": "./dist/presentations/swap.d.ts",
|
|
150
162
|
"module": "./dist/esm/swap.mjs",
|
|
@@ -185,6 +197,9 @@
|
|
|
185
197
|
"dreamy-zoom": [
|
|
186
198
|
"dist/presentations/dreamy-zoom.d.ts"
|
|
187
199
|
],
|
|
200
|
+
"film-burn": [
|
|
201
|
+
"dist/presentations/film-burn.d.ts"
|
|
202
|
+
],
|
|
188
203
|
"linear-blur": [
|
|
189
204
|
"dist/presentations/linear-blur.d.ts"
|
|
190
205
|
],
|
|
@@ -200,6 +215,9 @@
|
|
|
200
215
|
"crosswarp": [
|
|
201
216
|
"dist/presentations/crosswarp.d.ts"
|
|
202
217
|
],
|
|
218
|
+
"cross-zoom": [
|
|
219
|
+
"dist/presentations/cross-zoom.d.ts"
|
|
220
|
+
],
|
|
203
221
|
"swap": [
|
|
204
222
|
"dist/presentations/swap.d.ts"
|
|
205
223
|
]
|