@remotion/web-renderer 4.0.390 → 4.0.392
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/audio.js +5 -1
- package/dist/border-radius.d.ts +31 -0
- package/dist/border-radius.js +152 -0
- package/dist/calculate-transforms.d.ts +11 -0
- package/dist/calculate-transforms.js +91 -0
- package/dist/composable.d.ts +4 -0
- package/dist/composable.js +1 -0
- package/dist/compose-canvas.d.ts +1 -0
- package/dist/compose-canvas.js +36 -0
- package/dist/compose-svg.d.ts +1 -0
- package/dist/compose-svg.js +34 -0
- package/dist/create-scaffold.js +1 -0
- package/dist/drawing/calculate-transforms.js +27 -8
- package/dist/drawing/compose-canvas.d.ts +1 -0
- package/dist/drawing/compose-canvas.js +36 -0
- package/dist/drawing/compose-svg.d.ts +1 -0
- package/dist/drawing/compose-svg.js +34 -0
- package/dist/drawing/compose.d.ts +5 -0
- package/dist/drawing/compose.js +6 -0
- package/dist/drawing/draw-element-to-canvas.js +40 -47
- package/dist/drawing/draw-element.d.ts +8 -0
- package/dist/drawing/draw-element.js +50 -0
- package/dist/drawing/get-computed-style-cache.d.ts +0 -0
- package/dist/drawing/get-computed-style-cache.js +1 -0
- package/dist/drawing/text/draw-text.d.ts +1 -0
- package/dist/drawing/text/draw-text.js +57 -0
- package/dist/drawing/text/handle-text-node.js +0 -12
- package/dist/drawing/transform-in-3d.d.ts +8 -0
- package/dist/drawing/transform-in-3d.js +125 -0
- package/dist/esm/index.mjs +308 -105
- package/dist/find-canvas-elements.d.ts +1 -0
- package/dist/find-canvas-elements.js +13 -0
- package/dist/find-capturable-elements.d.ts +2 -0
- package/dist/find-capturable-elements.js +26 -0
- package/dist/opacity.d.ts +4 -0
- package/dist/opacity.js +7 -0
- package/dist/parse-transform-origin.d.ts +4 -0
- package/dist/parse-transform-origin.js +7 -0
- package/dist/transform.d.ts +4 -0
- package/dist/transform.js +6 -0
- package/package.json +5 -5
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { parseBorderRadius, setBorderRadius } from './border-radius';
|
|
2
|
+
import { drawBorder } from './draw-border';
|
|
3
|
+
import { setOpacity } from './opacity';
|
|
4
|
+
import { setTransform } from './transform';
|
|
5
|
+
export const drawElement = async ({ dimensions, computedStyle, context, draw, opacity, totalMatrix, }) => {
|
|
6
|
+
const background = computedStyle.backgroundColor;
|
|
7
|
+
const borderRadius = parseBorderRadius({
|
|
8
|
+
borderRadius: computedStyle.borderRadius,
|
|
9
|
+
width: dimensions.width,
|
|
10
|
+
height: dimensions.height,
|
|
11
|
+
});
|
|
12
|
+
const finishTransform = setTransform({
|
|
13
|
+
ctx: context,
|
|
14
|
+
transform: totalMatrix,
|
|
15
|
+
});
|
|
16
|
+
const finishBorderRadius = setBorderRadius({
|
|
17
|
+
ctx: context,
|
|
18
|
+
x: dimensions.left,
|
|
19
|
+
y: dimensions.top,
|
|
20
|
+
width: dimensions.width,
|
|
21
|
+
height: dimensions.height,
|
|
22
|
+
borderRadius,
|
|
23
|
+
});
|
|
24
|
+
const finishOpacity = setOpacity({
|
|
25
|
+
ctx: context,
|
|
26
|
+
opacity,
|
|
27
|
+
});
|
|
28
|
+
if (background &&
|
|
29
|
+
background !== 'transparent' &&
|
|
30
|
+
!(background.startsWith('rgba') &&
|
|
31
|
+
(background.endsWith(', 0)') || background.endsWith(',0')))) {
|
|
32
|
+
const originalFillStyle = context.fillStyle;
|
|
33
|
+
context.fillStyle = background;
|
|
34
|
+
context.fillRect(dimensions.left, dimensions.top, dimensions.width, dimensions.height);
|
|
35
|
+
context.fillStyle = originalFillStyle;
|
|
36
|
+
}
|
|
37
|
+
await draw(dimensions, computedStyle);
|
|
38
|
+
drawBorder({
|
|
39
|
+
ctx: context,
|
|
40
|
+
x: dimensions.left,
|
|
41
|
+
y: dimensions.top,
|
|
42
|
+
width: dimensions.width,
|
|
43
|
+
height: dimensions.height,
|
|
44
|
+
borderRadius,
|
|
45
|
+
computedStyle,
|
|
46
|
+
});
|
|
47
|
+
finishOpacity();
|
|
48
|
+
finishBorderRadius();
|
|
49
|
+
finishTransform();
|
|
50
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const drawTextToCanvas: (parentElement: HTMLElement, context: OffscreenCanvasRenderingContext2D) => Promise<void>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { withResolvers } from '../../with-resolvers';
|
|
2
|
+
export const drawTextToCanvas = async (parentElement, context) => {
|
|
3
|
+
const clientRect = parentElement.getBoundingClientRect();
|
|
4
|
+
const computedStyle = getComputedStyle(parentElement);
|
|
5
|
+
const clonedNode = parentElement.cloneNode(true);
|
|
6
|
+
for (let i = 0; i < computedStyle.length; i++) {
|
|
7
|
+
const propertyName = computedStyle[i];
|
|
8
|
+
const value = computedStyle.getPropertyValue(propertyName);
|
|
9
|
+
if (propertyName === 'margin-top' ||
|
|
10
|
+
propertyName === 'margin-bottom' ||
|
|
11
|
+
propertyName === 'margin-left' ||
|
|
12
|
+
propertyName === 'margin-right' ||
|
|
13
|
+
propertyName === 'margin') {
|
|
14
|
+
// @ts-expect-error - propertyName is a valid CSS property
|
|
15
|
+
clonedNode.style[propertyName] = '0px';
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
// @ts-expect-error - propertyName is a valid CSS property
|
|
19
|
+
clonedNode.style[propertyName] = value;
|
|
20
|
+
}
|
|
21
|
+
// Create an SVG that contains the cloned node via a foreignObject
|
|
22
|
+
const svgNS = 'http://www.w3.org/2000/svg';
|
|
23
|
+
const svg = document.createElementNS(svgNS, 'svg');
|
|
24
|
+
svg.setAttribute('width', `${clientRect.width}`);
|
|
25
|
+
svg.setAttribute('height', `${clientRect.height}`);
|
|
26
|
+
const foreignObject = document.createElementNS(svgNS, 'foreignObject');
|
|
27
|
+
foreignObject.setAttribute('x', '0');
|
|
28
|
+
foreignObject.setAttribute('y', '0');
|
|
29
|
+
foreignObject.setAttribute('width', `${clientRect.width}`);
|
|
30
|
+
foreignObject.setAttribute('height', `${clientRect.height}`);
|
|
31
|
+
// The cloned node must be in XHTML namespace to render properly
|
|
32
|
+
const xhtmlNS = 'http://www.w3.org/1999/xhtml';
|
|
33
|
+
const wrappedDiv = document.createElementNS(xhtmlNS, 'div');
|
|
34
|
+
wrappedDiv.style.width = `${clientRect.width}px`;
|
|
35
|
+
wrappedDiv.style.height = `${clientRect.height}px`;
|
|
36
|
+
wrappedDiv.appendChild(clonedNode);
|
|
37
|
+
foreignObject.appendChild(wrappedDiv);
|
|
38
|
+
svg.appendChild(foreignObject);
|
|
39
|
+
// Convert SVG to data URL
|
|
40
|
+
const serializer = new XMLSerializer();
|
|
41
|
+
const svgString = serializer.serializeToString(svg);
|
|
42
|
+
const svgDataUrl = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`;
|
|
43
|
+
const { promise, resolve, reject } = withResolvers();
|
|
44
|
+
// Create image and draw when loaded
|
|
45
|
+
const img = new window.Image();
|
|
46
|
+
img.onload = function () {
|
|
47
|
+
resolve(img);
|
|
48
|
+
};
|
|
49
|
+
img.onerror = function (err) {
|
|
50
|
+
// We may want to add robust error handling here
|
|
51
|
+
reject(err);
|
|
52
|
+
};
|
|
53
|
+
img.src = svgDataUrl;
|
|
54
|
+
await promise;
|
|
55
|
+
console.log(clientRect);
|
|
56
|
+
context.drawImage(img, clientRect.left, clientRect.top, clientRect.width, clientRect.height);
|
|
57
|
+
};
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
// Supported:
|
|
2
|
-
// - fontFamily
|
|
3
|
-
// - fontSize
|
|
4
|
-
// - fontWeight
|
|
5
|
-
// - color
|
|
6
|
-
// - lineHeight
|
|
7
|
-
// - direction
|
|
8
|
-
// - letterSpacing
|
|
9
|
-
// - textTransform
|
|
10
|
-
// Not supported:
|
|
11
|
-
// - writingMode
|
|
12
|
-
// - textDecoration
|
|
13
1
|
import { Internals } from 'remotion';
|
|
14
2
|
import { drawElementToCanvas } from '../draw-element-to-canvas';
|
|
15
3
|
import { findLineBreaks } from './find-line-breaks.text';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const transformIn3d: ({ canvasWidth, canvasHeight, matrix, sourceCanvas, offsetLeft, offsetTop, }: {
|
|
2
|
+
canvasWidth: number;
|
|
3
|
+
canvasHeight: number;
|
|
4
|
+
offsetLeft: number;
|
|
5
|
+
offsetTop: number;
|
|
6
|
+
matrix: DOMMatrix;
|
|
7
|
+
sourceCanvas: HTMLCanvasElement | OffscreenCanvas;
|
|
8
|
+
}) => OffscreenCanvas;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
function compileShader(shaderGl, source, type) {
|
|
2
|
+
const shader = shaderGl.createShader(type);
|
|
3
|
+
if (!shader) {
|
|
4
|
+
throw new Error('Could not create shader');
|
|
5
|
+
}
|
|
6
|
+
shaderGl.shaderSource(shader, source);
|
|
7
|
+
shaderGl.compileShader(shader);
|
|
8
|
+
if (!shaderGl.getShaderParameter(shader, shaderGl.COMPILE_STATUS)) {
|
|
9
|
+
const log = shaderGl.getShaderInfoLog(shader);
|
|
10
|
+
shaderGl.deleteShader(shader);
|
|
11
|
+
throw new Error('Shader compile error: ' + log);
|
|
12
|
+
}
|
|
13
|
+
return shader;
|
|
14
|
+
}
|
|
15
|
+
export const transformIn3d = ({ canvasWidth, canvasHeight, matrix, sourceCanvas, offsetLeft, offsetTop, }) => {
|
|
16
|
+
const canvas = new OffscreenCanvas(canvasWidth, canvasHeight);
|
|
17
|
+
const gl = canvas.getContext('webgl');
|
|
18
|
+
if (!gl) {
|
|
19
|
+
throw new Error('WebGL not supported');
|
|
20
|
+
}
|
|
21
|
+
// Vertex shader - now includes texture coordinates
|
|
22
|
+
const vsSource = `
|
|
23
|
+
attribute vec2 aPosition;
|
|
24
|
+
attribute vec2 aTexCoord;
|
|
25
|
+
uniform mat4 uTransform;
|
|
26
|
+
uniform mat4 uProjection;
|
|
27
|
+
varying vec2 vTexCoord;
|
|
28
|
+
|
|
29
|
+
void main() {
|
|
30
|
+
gl_Position = uProjection * uTransform * vec4(aPosition, 0.0, 1.0);
|
|
31
|
+
vTexCoord = aTexCoord;
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
34
|
+
// Fragment shader - now samples from texture
|
|
35
|
+
const fsSource = `
|
|
36
|
+
precision mediump float;
|
|
37
|
+
uniform sampler2D uTexture;
|
|
38
|
+
varying vec2 vTexCoord;
|
|
39
|
+
|
|
40
|
+
void main() {
|
|
41
|
+
gl_FragColor = texture2D(uTexture, vTexCoord);
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
44
|
+
// Create program
|
|
45
|
+
const vertexShader = compileShader(gl, vsSource, gl.VERTEX_SHADER);
|
|
46
|
+
const fragmentShader = compileShader(gl, fsSource, gl.FRAGMENT_SHADER);
|
|
47
|
+
const program = gl.createProgram();
|
|
48
|
+
gl.attachShader(program, vertexShader);
|
|
49
|
+
gl.attachShader(program, fragmentShader);
|
|
50
|
+
gl.linkProgram(program);
|
|
51
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
52
|
+
throw new Error('Program link error: ' + gl.getProgramInfoLog(program));
|
|
53
|
+
}
|
|
54
|
+
gl.useProgram(program);
|
|
55
|
+
// Create a quad (two triangles) with texture coordinates
|
|
56
|
+
// prettier-ignore
|
|
57
|
+
const vertices = new Float32Array([
|
|
58
|
+
// Position (x, y) + TexCoord (u, v)
|
|
59
|
+
// First:
|
|
60
|
+
offsetLeft, offsetTop, 0, 0, // bottom-left
|
|
61
|
+
canvasWidth + offsetLeft, offsetTop, 1, 0, // bottom-right
|
|
62
|
+
offsetLeft, canvasHeight + offsetTop, 0, 1, // top-left
|
|
63
|
+
// Second:
|
|
64
|
+
offsetLeft, canvasHeight + offsetTop, 0, 1, // top-left
|
|
65
|
+
canvasWidth + offsetLeft, offsetTop, 1, 0, // bottom-right
|
|
66
|
+
canvasWidth + offsetLeft, canvasHeight + offsetTop, 1, 1, // top-right
|
|
67
|
+
]);
|
|
68
|
+
const vertexBuffer = gl.createBuffer();
|
|
69
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
|
|
70
|
+
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
|
|
71
|
+
const aPosition = gl.getAttribLocation(program, 'aPosition');
|
|
72
|
+
const aTexCoord = gl.getAttribLocation(program, 'aTexCoord');
|
|
73
|
+
// Position attribute (2 floats, stride 4 floats, offset 0)
|
|
74
|
+
gl.enableVertexAttribArray(aPosition);
|
|
75
|
+
gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 4 * 4, 0);
|
|
76
|
+
// Texture coordinate attribute (2 floats, stride 4 floats, offset 2)
|
|
77
|
+
gl.enableVertexAttribArray(aTexCoord);
|
|
78
|
+
gl.vertexAttribPointer(aTexCoord, 2, gl.FLOAT, false, 4 * 4, 2 * 4);
|
|
79
|
+
// Create and configure texture
|
|
80
|
+
const texture = gl.createTexture();
|
|
81
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
82
|
+
// Set texture parameters
|
|
83
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
84
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
85
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
86
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
87
|
+
// Upload the source canvas as a texture
|
|
88
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, sourceCanvas);
|
|
89
|
+
// The transform matrix
|
|
90
|
+
const transformMatrix = matrix.toFloat32Array();
|
|
91
|
+
const zScale = 1000000000; // By default infinite in chrome
|
|
92
|
+
// Create orthographic projection matrix for pixel coordinates
|
|
93
|
+
const projectionMatrix = new Float32Array([
|
|
94
|
+
2 / canvasWidth,
|
|
95
|
+
0,
|
|
96
|
+
0,
|
|
97
|
+
0,
|
|
98
|
+
0,
|
|
99
|
+
-2 / canvasHeight,
|
|
100
|
+
0,
|
|
101
|
+
0,
|
|
102
|
+
0,
|
|
103
|
+
0,
|
|
104
|
+
-2 / zScale,
|
|
105
|
+
0,
|
|
106
|
+
-1,
|
|
107
|
+
1,
|
|
108
|
+
0,
|
|
109
|
+
1,
|
|
110
|
+
]);
|
|
111
|
+
const uTransform = gl.getUniformLocation(program, 'uTransform');
|
|
112
|
+
const uProjection = gl.getUniformLocation(program, 'uProjection');
|
|
113
|
+
const uTexture = gl.getUniformLocation(program, 'uTexture');
|
|
114
|
+
gl.uniformMatrix4fv(uTransform, false, transformMatrix);
|
|
115
|
+
gl.uniformMatrix4fv(uProjection, false, projectionMatrix);
|
|
116
|
+
gl.uniform1i(uTexture, 0); // Use texture unit 0
|
|
117
|
+
// Clear and draw
|
|
118
|
+
gl.clearColor(0, 0, 0, 0); // Transparent background
|
|
119
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
120
|
+
// Enable blending for transparency
|
|
121
|
+
gl.enable(gl.BLEND);
|
|
122
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
123
|
+
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
124
|
+
return canvas;
|
|
125
|
+
};
|