@remotion/transitions 4.0.465 → 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.
Files changed (42) hide show
  1. package/book-flip.js +2 -0
  2. package/cross-zoom.js +2 -0
  3. package/crosswarp.js +2 -0
  4. package/dist/TransitionSeries.js +16 -6
  5. package/dist/esm/book-flip.mjs +434 -0
  6. package/dist/esm/cross-zoom.mjs +377 -0
  7. package/dist/esm/crosswarp.mjs +331 -0
  8. package/dist/esm/dissolve.mjs +4 -3
  9. package/dist/esm/dreamy-zoom.mjs +348 -0
  10. package/dist/esm/film-burn.mjs +443 -0
  11. package/dist/esm/index.mjs +1020 -209
  12. package/dist/esm/linear-blur.mjs +343 -0
  13. package/dist/esm/ripple.mjs +342 -0
  14. package/dist/esm/swap.mjs +394 -0
  15. package/dist/esm/zoom-blur.mjs +4 -3
  16. package/dist/esm/zoom-in-out.mjs +4 -3
  17. package/dist/html-in-canvas-presentation.js +4 -5
  18. package/dist/index.d.ts +13 -3
  19. package/dist/index.js +9 -1
  20. package/dist/presentations/book-flip.d.ts +14 -0
  21. package/dist/presentations/book-flip.js +255 -0
  22. package/dist/presentations/cross-zoom.d.ts +13 -0
  23. package/dist/presentations/cross-zoom.js +199 -0
  24. package/dist/presentations/crosswarp.d.ts +11 -0
  25. package/dist/presentations/crosswarp.js +154 -0
  26. package/dist/presentations/dreamy-zoom.d.ts +14 -0
  27. package/dist/presentations/dreamy-zoom.js +169 -0
  28. package/dist/presentations/film-burn.d.ts +13 -0
  29. package/dist/presentations/film-burn.js +265 -0
  30. package/dist/presentations/linear-blur.d.ts +13 -0
  31. package/dist/presentations/linear-blur.js +164 -0
  32. package/dist/presentations/ripple.d.ts +14 -0
  33. package/dist/presentations/ripple.js +164 -0
  34. package/dist/presentations/swap.d.ts +15 -0
  35. package/dist/presentations/swap.js +212 -0
  36. package/dist/types.d.ts +1 -1
  37. package/dreamy-zoom.js +2 -0
  38. package/film-burn.js +2 -0
  39. package/linear-blur.js +2 -0
  40. package/package.json +80 -8
  41. package/ripple.js +2 -0
  42. package/swap.js +2 -0
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.bookFlip = exports.bookFlipShader = void 0;
4
+ const html_in_canvas_presentation_1 = require("../html-in-canvas-presentation");
5
+ const DIRECTION_FROM_LEFT = 0;
6
+ const DIRECTION_FROM_RIGHT = 1;
7
+ const DIRECTION_FROM_TOP = 2;
8
+ const DIRECTION_FROM_BOTTOM = 3;
9
+ const DEFAULT_DIRECTION = 'from-right';
10
+ const VERTEX_SHADER = `#version 300 es
11
+ in vec2 a_pos;
12
+ out vec2 v_uv;
13
+ void main() {
14
+ v_uv = vec2(a_pos.x * 0.5 + 0.5, 0.5 - a_pos.y * 0.5);
15
+ gl_Position = vec4(a_pos, 0.0, 1.0);
16
+ }`;
17
+ // Adapted from https://gl-transitions.com/editor/BookFlip
18
+ // Author: hong · License: MIT
19
+ const FRAGMENT_SHADER = `#version 300 es
20
+ precision highp float;
21
+
22
+ uniform sampler2D u_prev;
23
+ uniform sampler2D u_next;
24
+ uniform float u_time;
25
+ uniform float u_direction;
26
+
27
+ in vec2 v_uv;
28
+ out vec4 outColor;
29
+
30
+ const float EPSILON = 0.0001;
31
+
32
+ float avoidZero(float value) {
33
+ if (abs(value) < EPSILON) {
34
+ return value < 0.0 ? -EPSILON : EPSILON;
35
+ }
36
+
37
+ return value;
38
+ }
39
+
40
+ vec2 skewRight(vec2 p, float progress) {
41
+ float skewX = (p.x - progress) / avoidZero(0.5 - progress) * 0.5;
42
+ float skewY =
43
+ (p.y - 0.5) /
44
+ avoidZero(0.5 + progress * (p.x - 0.5) / 0.5) *
45
+ 0.5 +
46
+ 0.5;
47
+ return vec2(skewX, skewY);
48
+ }
49
+
50
+ vec2 skewLeft(vec2 p, float progress) {
51
+ float skewX = (p.x - 0.5) / avoidZero(progress - 0.5) * 0.5 + 0.5;
52
+ float skewY =
53
+ (p.y - 0.5) /
54
+ avoidZero(0.5 + (1.0 - progress) * (0.5 - p.x) / 0.5) *
55
+ 0.5 +
56
+ 0.5;
57
+ return vec2(skewX, skewY);
58
+ }
59
+
60
+ vec4 addShade(float progress) {
61
+ float shadeVal = max(0.7, abs(progress - 0.5) * 2.0);
62
+ return vec4(vec3(shadeVal), 1.0);
63
+ }
64
+
65
+ vec2 toCanonicalUv(vec2 p) {
66
+ if (u_direction < 0.5) {
67
+ return p;
68
+ }
69
+
70
+ if (u_direction < 1.5) {
71
+ return vec2(1.0 - p.x, p.y);
72
+ }
73
+
74
+ if (u_direction < 2.5) {
75
+ return vec2(p.y, 1.0 - p.x);
76
+ }
77
+
78
+ return vec2(1.0 - p.y, p.x);
79
+ }
80
+
81
+ vec2 fromCanonicalUv(vec2 p) {
82
+ if (u_direction < 0.5) {
83
+ return p;
84
+ }
85
+
86
+ if (u_direction < 1.5) {
87
+ return vec2(1.0 - p.x, p.y);
88
+ }
89
+
90
+ if (u_direction < 2.5) {
91
+ return vec2(1.0 - p.y, p.x);
92
+ }
93
+
94
+ return vec2(p.y, 1.0 - p.x);
95
+ }
96
+
97
+ vec4 samplePrev(vec2 p) {
98
+ return texture(u_prev, fromCanonicalUv(p));
99
+ }
100
+
101
+ vec4 sampleNext(vec2 p) {
102
+ return texture(u_next, fromCanonicalUv(p));
103
+ }
104
+
105
+ vec4 transition(vec2 p, float progress) {
106
+ float pr = step(1.0 - progress, p.x);
107
+
108
+ if (p.x < 0.5) {
109
+ return mix(
110
+ samplePrev(p),
111
+ sampleNext(skewLeft(p, progress)) * addShade(progress),
112
+ pr
113
+ );
114
+ }
115
+
116
+ return mix(
117
+ samplePrev(skewRight(p, progress)) * addShade(progress),
118
+ sampleNext(p),
119
+ pr
120
+ );
121
+ }
122
+
123
+ void main() {
124
+ vec2 p = toCanonicalUv(v_uv);
125
+ float progress = 1.0 - u_time;
126
+ outColor = transition(p, progress);
127
+ }`;
128
+ const compileShader = (gl, source, type) => {
129
+ const shader = gl.createShader(type);
130
+ if (!shader) {
131
+ throw new Error('Failed to create shader');
132
+ }
133
+ gl.shaderSource(shader, source);
134
+ gl.compileShader(shader);
135
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
136
+ const log = gl.getShaderInfoLog(shader);
137
+ gl.deleteShader(shader);
138
+ throw new Error(`Failed to compile shader: ${log}`);
139
+ }
140
+ return shader;
141
+ };
142
+ const createProgram = (gl) => {
143
+ const program = gl.createProgram();
144
+ if (!program) {
145
+ throw new Error('Failed to create WebGL program');
146
+ }
147
+ const vs = compileShader(gl, VERTEX_SHADER, gl.VERTEX_SHADER);
148
+ const fs = compileShader(gl, FRAGMENT_SHADER, gl.FRAGMENT_SHADER);
149
+ gl.attachShader(program, vs);
150
+ gl.attachShader(program, fs);
151
+ gl.linkProgram(program);
152
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
153
+ const log = gl.getProgramInfoLog(program);
154
+ gl.deleteProgram(program);
155
+ throw new Error(`Failed to link program: ${log}`);
156
+ }
157
+ return program;
158
+ };
159
+ const createTexture = (gl) => {
160
+ const tex = gl.createTexture();
161
+ if (!tex) {
162
+ throw new Error('Failed to create texture');
163
+ }
164
+ gl.bindTexture(gl.TEXTURE_2D, tex);
165
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
166
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
167
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
168
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
169
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 0]));
170
+ return tex;
171
+ };
172
+ const getDirectionConstant = (direction) => {
173
+ switch (direction) {
174
+ case 'from-left':
175
+ return DIRECTION_FROM_LEFT;
176
+ case 'from-right':
177
+ return DIRECTION_FROM_RIGHT;
178
+ case 'from-top':
179
+ return DIRECTION_FROM_TOP;
180
+ case 'from-bottom':
181
+ return DIRECTION_FROM_BOTTOM;
182
+ default:
183
+ return DIRECTION_FROM_RIGHT;
184
+ }
185
+ };
186
+ const bookFlipShader = (canvas) => {
187
+ const gl = canvas.getContext('webgl2', { premultipliedAlpha: true });
188
+ if (!gl) {
189
+ throw new Error('Failed to create WebGL2 context');
190
+ }
191
+ const program = createProgram(gl);
192
+ const prevTex = createTexture(gl);
193
+ const nextTex = createTexture(gl);
194
+ const vao = gl.createVertexArray();
195
+ gl.bindVertexArray(vao);
196
+ const buffer = gl.createBuffer();
197
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
198
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);
199
+ const aPos = gl.getAttribLocation(program, 'a_pos');
200
+ gl.enableVertexAttribArray(aPos);
201
+ gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
202
+ const uTime = gl.getUniformLocation(program, 'u_time');
203
+ const uPrev = gl.getUniformLocation(program, 'u_prev');
204
+ const uNext = gl.getUniformLocation(program, 'u_next');
205
+ const uDirection = gl.getUniformLocation(program, 'u_direction');
206
+ const cleanup = () => {
207
+ gl.deleteProgram(program);
208
+ gl.deleteTexture(prevTex);
209
+ gl.deleteTexture(nextTex);
210
+ };
211
+ const clear = () => {
212
+ gl.clearColor(0, 0, 0, 0);
213
+ gl.clear(gl.COLOR_BUFFER_BIT);
214
+ };
215
+ const draw = ({ prevImage, nextImage, width, height, time, passedProps, }) => {
216
+ const { direction = DEFAULT_DIRECTION } = passedProps;
217
+ if (!prevImage && !nextImage) {
218
+ return;
219
+ }
220
+ if (prevImage && (prevImage.width === 0 || prevImage.height === 0)) {
221
+ return;
222
+ }
223
+ if (nextImage && (nextImage.width === 0 || nextImage.height === 0)) {
224
+ return;
225
+ }
226
+ // At time=0 the shader outputs nextImage. At time=1 the shader outputs prevImage.
227
+ const effectiveTime = !prevImage ? 0 : !nextImage ? 1 : time;
228
+ gl.viewport(0, 0, width, height);
229
+ gl.clearColor(0, 0, 0, 0);
230
+ gl.clear(gl.COLOR_BUFFER_BIT);
231
+ gl.useProgram(program);
232
+ gl.activeTexture(gl.TEXTURE0);
233
+ gl.bindTexture(gl.TEXTURE_2D, prevTex);
234
+ if (prevImage) {
235
+ gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, prevImage);
236
+ }
237
+ gl.uniform1i(uPrev, 0);
238
+ gl.activeTexture(gl.TEXTURE1);
239
+ gl.bindTexture(gl.TEXTURE_2D, nextTex);
240
+ if (nextImage) {
241
+ gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, nextImage);
242
+ }
243
+ gl.uniform1i(uNext, 1);
244
+ gl.uniform1f(uTime, effectiveTime);
245
+ gl.uniform1f(uDirection, getDirectionConstant(direction));
246
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
247
+ };
248
+ return {
249
+ clear,
250
+ cleanup,
251
+ draw,
252
+ };
253
+ };
254
+ exports.bookFlipShader = bookFlipShader;
255
+ exports.bookFlip = (0, html_in_canvas_presentation_1.makeHtmlInCanvasPresentation)(exports.bookFlipShader);
@@ -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,11 @@
1
+ export type CrosswarpProps = Record<string, never>;
2
+ export declare const crosswarpShader: (canvas: OffscreenCanvas) => {
3
+ clear: () => void;
4
+ cleanup: () => void;
5
+ draw: import("..").HtmlInCanvasShaderDraw<CrosswarpProps>;
6
+ };
7
+ export declare const crosswarp: (props: CrosswarpProps & {
8
+ effects?: import("remotion").EffectsProp | undefined;
9
+ }) => import("..").TransitionPresentation<CrosswarpProps & {
10
+ effects?: import("remotion").EffectsProp | undefined;
11
+ }>;
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.crosswarp = exports.crosswarpShader = void 0;
4
+ const html_in_canvas_presentation_1 = require("../html-in-canvas-presentation");
5
+ const VERTEX_SHADER = `#version 300 es
6
+ in vec2 a_pos;
7
+ out vec2 v_uv;
8
+ void main() {
9
+ v_uv = vec2(a_pos.x * 0.5 + 0.5, 0.5 - a_pos.y * 0.5);
10
+ gl_Position = vec4(a_pos, 0.0, 1.0);
11
+ }`;
12
+ // Adapted from https://gl-transitions.com/editor/crosswarp
13
+ // Author: Eke Péter · License: MIT
14
+ const FRAGMENT_SHADER = `#version 300 es
15
+ precision highp float;
16
+
17
+ uniform sampler2D u_prev;
18
+ uniform sampler2D u_next;
19
+ uniform float u_time;
20
+
21
+ in vec2 v_uv;
22
+ out vec4 outColor;
23
+
24
+ vec4 transition(vec2 uv, float progress) {
25
+ float x = progress;
26
+ x = smoothstep(0.0, 1.0, x * 2.0 + uv.x - 1.0);
27
+ return mix(
28
+ texture(u_next, (uv - 0.5) * (1.0 - x) + 0.5),
29
+ texture(u_prev, (uv - 0.5) * x + 0.5),
30
+ x
31
+ );
32
+ }
33
+
34
+ void main() {
35
+ // In Remotion's HTML-in-canvas convention, u_prev is bound to the incoming
36
+ // scene and u_next is bound to the outgoing scene, so the gl-transitions
37
+ // "from" → u_next and "to" → u_prev. With this binding, progress = u_time
38
+ // (no inversion) maps to the gl-transitions convention where progress = 0
39
+ // shows the outgoing scene and progress = 1 shows the incoming one.
40
+ float progress = u_time;
41
+ outColor = transition(v_uv, progress);
42
+ }`;
43
+ const compileShader = (gl, source, type) => {
44
+ const shader = gl.createShader(type);
45
+ if (!shader) {
46
+ throw new Error('Failed to create shader');
47
+ }
48
+ gl.shaderSource(shader, source);
49
+ gl.compileShader(shader);
50
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
51
+ const log = gl.getShaderInfoLog(shader);
52
+ gl.deleteShader(shader);
53
+ throw new Error(`Failed to compile shader: ${log}`);
54
+ }
55
+ return shader;
56
+ };
57
+ const createProgram = (gl) => {
58
+ const program = gl.createProgram();
59
+ if (!program) {
60
+ throw new Error('Failed to create WebGL program');
61
+ }
62
+ const vs = compileShader(gl, VERTEX_SHADER, gl.VERTEX_SHADER);
63
+ const fs = compileShader(gl, FRAGMENT_SHADER, gl.FRAGMENT_SHADER);
64
+ gl.attachShader(program, vs);
65
+ gl.attachShader(program, fs);
66
+ gl.linkProgram(program);
67
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
68
+ const log = gl.getProgramInfoLog(program);
69
+ gl.deleteProgram(program);
70
+ throw new Error(`Failed to link program: ${log}`);
71
+ }
72
+ return program;
73
+ };
74
+ const createTexture = (gl) => {
75
+ const tex = gl.createTexture();
76
+ if (!tex) {
77
+ throw new Error('Failed to create texture');
78
+ }
79
+ gl.bindTexture(gl.TEXTURE_2D, tex);
80
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
81
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
82
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
83
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
84
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 0]));
85
+ return tex;
86
+ };
87
+ const crosswarpShader = (canvas) => {
88
+ const gl = canvas.getContext('webgl2', { premultipliedAlpha: true });
89
+ if (!gl) {
90
+ throw new Error('Failed to create WebGL2 context');
91
+ }
92
+ const program = createProgram(gl);
93
+ const prevTex = createTexture(gl);
94
+ const nextTex = createTexture(gl);
95
+ const vao = gl.createVertexArray();
96
+ gl.bindVertexArray(vao);
97
+ const buffer = gl.createBuffer();
98
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
99
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);
100
+ const aPos = gl.getAttribLocation(program, 'a_pos');
101
+ gl.enableVertexAttribArray(aPos);
102
+ gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
103
+ const uTime = gl.getUniformLocation(program, 'u_time');
104
+ const uPrev = gl.getUniformLocation(program, 'u_prev');
105
+ const uNext = gl.getUniformLocation(program, 'u_next');
106
+ const cleanup = () => {
107
+ gl.deleteProgram(program);
108
+ gl.deleteTexture(prevTex);
109
+ gl.deleteTexture(nextTex);
110
+ };
111
+ const clear = () => {
112
+ gl.clearColor(0, 0, 0, 0);
113
+ gl.clear(gl.COLOR_BUFFER_BIT);
114
+ };
115
+ const draw = ({ prevImage, nextImage, width, height, time, }) => {
116
+ if (!prevImage && !nextImage) {
117
+ return;
118
+ }
119
+ if (prevImage && (prevImage.width === 0 || prevImage.height === 0)) {
120
+ return;
121
+ }
122
+ if (nextImage && (nextImage.width === 0 || nextImage.height === 0)) {
123
+ return;
124
+ }
125
+ // When one side is missing, force the mix to fully show the other.
126
+ // At time=0 the shader outputs nextImage. At time=1 the shader outputs prevImage.
127
+ const effectiveTime = !prevImage ? 0 : !nextImage ? 1 : time;
128
+ gl.viewport(0, 0, width, height);
129
+ gl.clearColor(0, 0, 0, 0);
130
+ gl.clear(gl.COLOR_BUFFER_BIT);
131
+ gl.useProgram(program);
132
+ gl.activeTexture(gl.TEXTURE0);
133
+ gl.bindTexture(gl.TEXTURE_2D, prevTex);
134
+ if (prevImage) {
135
+ gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, prevImage);
136
+ }
137
+ gl.uniform1i(uPrev, 0);
138
+ gl.activeTexture(gl.TEXTURE1);
139
+ gl.bindTexture(gl.TEXTURE_2D, nextTex);
140
+ if (nextImage) {
141
+ gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, nextImage);
142
+ }
143
+ gl.uniform1i(uNext, 1);
144
+ gl.uniform1f(uTime, effectiveTime);
145
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
146
+ };
147
+ return {
148
+ clear,
149
+ cleanup,
150
+ draw,
151
+ };
152
+ };
153
+ exports.crosswarpShader = crosswarpShader;
154
+ exports.crosswarp = (0, html_in_canvas_presentation_1.makeHtmlInCanvasPresentation)(exports.crosswarpShader);
@@ -0,0 +1,14 @@
1
+ export type DreamyZoomProps = {
2
+ rotation?: number;
3
+ scale?: number;
4
+ };
5
+ export declare const dreamyZoomShader: (canvas: OffscreenCanvas) => {
6
+ clear: () => void;
7
+ cleanup: () => void;
8
+ draw: import("..").HtmlInCanvasShaderDraw<DreamyZoomProps>;
9
+ };
10
+ export declare const dreamyZoom: (props: DreamyZoomProps & {
11
+ effects?: import("remotion").EffectsProp | undefined;
12
+ }) => import("..").TransitionPresentation<DreamyZoomProps & {
13
+ effects?: import("remotion").EffectsProp | undefined;
14
+ }>;