@remotion/web-renderer 4.0.387 → 4.0.390
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/compose.js +26 -1
- package/dist/drawing/calculate-transforms.d.ts +1 -0
- package/dist/drawing/calculate-transforms.js +8 -0
- package/dist/drawing/draw-element-to-canvas.d.ts +2 -1
- package/dist/drawing/draw-element-to-canvas.js +3 -14
- package/dist/drawing/text/find-line-breaks.text.d.ts +5 -0
- package/dist/drawing/text/find-line-breaks.text.js +67 -0
- package/dist/drawing/text/get-collapsed-text.d.ts +1 -0
- package/dist/drawing/text/get-collapsed-text.js +46 -0
- package/dist/drawing/text/handle-text-node.d.ts +1 -0
- package/dist/drawing/text/handle-text-node.js +81 -0
- package/dist/esm/index.mjs +240 -47
- package/package.json +5 -5
- package/dist/border-radius.d.ts +0 -31
- package/dist/border-radius.js +0 -152
- package/dist/calculate-transforms.d.ts +0 -11
- package/dist/calculate-transforms.js +0 -91
- package/dist/composable.d.ts +0 -4
- package/dist/composable.js +0 -1
- package/dist/compose-canvas.d.ts +0 -1
- package/dist/compose-canvas.js +0 -36
- package/dist/compose-svg.d.ts +0 -1
- package/dist/compose-svg.js +0 -34
- package/dist/drawing/compose-canvas.d.ts +0 -1
- package/dist/drawing/compose-canvas.js +0 -36
- package/dist/drawing/compose-svg.d.ts +0 -1
- package/dist/drawing/compose-svg.js +0 -34
- package/dist/drawing/compose.d.ts +0 -5
- package/dist/drawing/compose.js +0 -6
- package/dist/drawing/get-computed-style-cache.d.ts +0 -0
- package/dist/drawing/get-computed-style-cache.js +0 -1
- package/dist/drawing/text/draw-text.d.ts +0 -1
- package/dist/drawing/text/draw-text.js +0 -57
- package/dist/find-canvas-elements.d.ts +0 -1
- package/dist/find-canvas-elements.js +0 -13
- package/dist/find-capturable-elements.d.ts +0 -2
- package/dist/find-capturable-elements.js +0 -26
- package/dist/opacity.d.ts +0 -4
- package/dist/opacity.js +0 -7
- package/dist/parse-transform-origin.d.ts +0 -4
- package/dist/parse-transform-origin.js +0 -7
- package/dist/transform.d.ts +0 -4
- package/dist/transform.js +0 -6
package/dist/esm/index.mjs
CHANGED
|
@@ -8259,7 +8259,7 @@ class Output {
|
|
|
8259
8259
|
*/
|
|
8260
8260
|
|
|
8261
8261
|
// src/render-media-on-web.tsx
|
|
8262
|
-
import { Internals as
|
|
8262
|
+
import { Internals as Internals4 } from "remotion";
|
|
8263
8263
|
|
|
8264
8264
|
// src/add-sample.ts
|
|
8265
8265
|
var addVideoSampleAndCloseFrame = async (frameToEncode, videoSampleSource) => {
|
|
@@ -8826,12 +8826,16 @@ var calculateTransforms = (element) => {
|
|
|
8826
8826
|
const transforms = [];
|
|
8827
8827
|
const toReset = [];
|
|
8828
8828
|
let opacity = 1;
|
|
8829
|
+
let elementComputedStyle = null;
|
|
8829
8830
|
while (parent) {
|
|
8830
8831
|
const computedStyle = getComputedStyle(parent);
|
|
8831
8832
|
const parentOpacity = computedStyle.opacity;
|
|
8832
8833
|
if (parentOpacity && parentOpacity !== "") {
|
|
8833
8834
|
opacity *= parseFloat(parentOpacity);
|
|
8834
8835
|
}
|
|
8836
|
+
if (parent === element) {
|
|
8837
|
+
elementComputedStyle = computedStyle;
|
|
8838
|
+
}
|
|
8835
8839
|
if (computedStyle.transform && computedStyle.transform !== "none" || parent === element) {
|
|
8836
8840
|
const toParse = computedStyle.transform === "none" || computedStyle.transform === "" ? undefined : computedStyle.transform;
|
|
8837
8841
|
const matrix = new DOMMatrix(toParse);
|
|
@@ -8864,6 +8868,9 @@ var calculateTransforms = (element) => {
|
|
|
8864
8868
|
const transformMatrix = new DOMMatrix().translate(globalTransformOrigin.x, globalTransformOrigin.y).multiply(transform.matrix).translate(-globalTransformOrigin.x, -globalTransformOrigin.y);
|
|
8865
8869
|
totalMatrix.multiplySelf(transformMatrix);
|
|
8866
8870
|
}
|
|
8871
|
+
if (!elementComputedStyle) {
|
|
8872
|
+
throw new Error("Element computed style not found");
|
|
8873
|
+
}
|
|
8867
8874
|
return {
|
|
8868
8875
|
dimensions,
|
|
8869
8876
|
totalMatrix,
|
|
@@ -8873,7 +8880,8 @@ var calculateTransforms = (element) => {
|
|
|
8873
8880
|
}
|
|
8874
8881
|
},
|
|
8875
8882
|
nativeTransformOrigin,
|
|
8876
|
-
opacity
|
|
8883
|
+
opacity,
|
|
8884
|
+
computedStyle: elementComputedStyle
|
|
8877
8885
|
};
|
|
8878
8886
|
};
|
|
8879
8887
|
|
|
@@ -8987,46 +8995,13 @@ var setTransform = ({
|
|
|
8987
8995
|
};
|
|
8988
8996
|
};
|
|
8989
8997
|
|
|
8990
|
-
// src/drawing/turn-svg-into-drawable.ts
|
|
8991
|
-
var turnSvgIntoDrawable = (svg) => {
|
|
8992
|
-
const originalTransform = svg.style.transform;
|
|
8993
|
-
const originalTransformOrigin = svg.style.transformOrigin;
|
|
8994
|
-
const originalMarginLeft = svg.style.marginLeft;
|
|
8995
|
-
const originalMarginRight = svg.style.marginRight;
|
|
8996
|
-
const originalMarginTop = svg.style.marginTop;
|
|
8997
|
-
const originalMarginBottom = svg.style.marginBottom;
|
|
8998
|
-
svg.style.transform = "none";
|
|
8999
|
-
svg.style.transformOrigin = "";
|
|
9000
|
-
svg.style.marginLeft = "0";
|
|
9001
|
-
svg.style.marginRight = "0";
|
|
9002
|
-
svg.style.marginTop = "0";
|
|
9003
|
-
svg.style.marginBottom = "0";
|
|
9004
|
-
const svgData = new XMLSerializer().serializeToString(svg);
|
|
9005
|
-
svg.style.marginLeft = originalMarginLeft;
|
|
9006
|
-
svg.style.marginRight = originalMarginRight;
|
|
9007
|
-
svg.style.marginTop = originalMarginTop;
|
|
9008
|
-
svg.style.marginBottom = originalMarginBottom;
|
|
9009
|
-
svg.style.transform = originalTransform;
|
|
9010
|
-
svg.style.transformOrigin = originalTransformOrigin;
|
|
9011
|
-
return new Promise((resolve, reject) => {
|
|
9012
|
-
const image = new Image;
|
|
9013
|
-
const url2 = `data:image/svg+xml;base64,${btoa(svgData)}`;
|
|
9014
|
-
image.onload = function() {
|
|
9015
|
-
resolve(image);
|
|
9016
|
-
};
|
|
9017
|
-
image.onerror = () => {
|
|
9018
|
-
reject(new Error("Failed to convert SVG to image"));
|
|
9019
|
-
};
|
|
9020
|
-
image.src = url2;
|
|
9021
|
-
});
|
|
9022
|
-
};
|
|
9023
|
-
|
|
9024
8998
|
// src/drawing/draw-element-to-canvas.ts
|
|
9025
8999
|
var drawElementToCanvas = async ({
|
|
9026
9000
|
element,
|
|
9027
|
-
context
|
|
9001
|
+
context,
|
|
9002
|
+
draw
|
|
9028
9003
|
}) => {
|
|
9029
|
-
const { totalMatrix, reset, dimensions, opacity } = calculateTransforms(element);
|
|
9004
|
+
const { totalMatrix, reset, dimensions, opacity, computedStyle } = calculateTransforms(element);
|
|
9030
9005
|
if (opacity === 0) {
|
|
9031
9006
|
reset();
|
|
9032
9007
|
return;
|
|
@@ -9035,7 +9010,6 @@ var drawElementToCanvas = async ({
|
|
|
9035
9010
|
reset();
|
|
9036
9011
|
return;
|
|
9037
9012
|
}
|
|
9038
|
-
const computedStyle = getComputedStyle(element);
|
|
9039
9013
|
const background = computedStyle.backgroundColor;
|
|
9040
9014
|
const borderRadius = parseBorderRadius({
|
|
9041
9015
|
borderRadius: computedStyle.borderRadius,
|
|
@@ -9058,16 +9032,13 @@ var drawElementToCanvas = async ({
|
|
|
9058
9032
|
ctx: context,
|
|
9059
9033
|
opacity
|
|
9060
9034
|
});
|
|
9061
|
-
const drawable = element instanceof SVGSVGElement ? await turnSvgIntoDrawable(element) : element instanceof HTMLImageElement ? element : element instanceof HTMLCanvasElement ? element : null;
|
|
9062
9035
|
if (background && background !== "transparent" && !(background.startsWith("rgba") && (background.endsWith(", 0)") || background.endsWith(",0")))) {
|
|
9063
9036
|
const originalFillStyle = context.fillStyle;
|
|
9064
9037
|
context.fillStyle = background;
|
|
9065
9038
|
context.fillRect(dimensions.left, dimensions.top, dimensions.width, dimensions.height);
|
|
9066
9039
|
context.fillStyle = originalFillStyle;
|
|
9067
9040
|
}
|
|
9068
|
-
|
|
9069
|
-
context.drawImage(drawable, dimensions.left, dimensions.top, dimensions.width, dimensions.height);
|
|
9070
|
-
}
|
|
9041
|
+
await draw(dimensions, computedStyle);
|
|
9071
9042
|
drawBorder({
|
|
9072
9043
|
ctx: context,
|
|
9073
9044
|
x: dimensions.left,
|
|
@@ -9083,10 +9054,221 @@ var drawElementToCanvas = async ({
|
|
|
9083
9054
|
reset();
|
|
9084
9055
|
};
|
|
9085
9056
|
|
|
9057
|
+
// src/drawing/text/handle-text-node.ts
|
|
9058
|
+
import { Internals as Internals3 } from "remotion";
|
|
9059
|
+
|
|
9060
|
+
// src/drawing/text/get-collapsed-text.ts
|
|
9061
|
+
var getCollapsedText = (span) => {
|
|
9062
|
+
const textNode = span.firstChild;
|
|
9063
|
+
if (!textNode || textNode.nodeType !== Node.TEXT_NODE) {
|
|
9064
|
+
throw new Error("Span must contain a single text node");
|
|
9065
|
+
}
|
|
9066
|
+
const originalText = textNode.textContent || "";
|
|
9067
|
+
let collapsedText = originalText;
|
|
9068
|
+
const measureWidth = (text) => {
|
|
9069
|
+
textNode.textContent = text;
|
|
9070
|
+
return span.getBoundingClientRect().width;
|
|
9071
|
+
};
|
|
9072
|
+
const originalWidth = measureWidth(originalText);
|
|
9073
|
+
if (/^\s/.test(collapsedText)) {
|
|
9074
|
+
const trimmedLeading = collapsedText.replace(/^\s+/, "");
|
|
9075
|
+
const newWidth = measureWidth(trimmedLeading);
|
|
9076
|
+
if (newWidth === originalWidth) {
|
|
9077
|
+
collapsedText = trimmedLeading;
|
|
9078
|
+
}
|
|
9079
|
+
}
|
|
9080
|
+
if (/\s$/.test(collapsedText)) {
|
|
9081
|
+
const currentWidth = measureWidth(collapsedText);
|
|
9082
|
+
const trimmedTrailing = collapsedText.replace(/\s+$/, "");
|
|
9083
|
+
const newWidth = measureWidth(trimmedTrailing);
|
|
9084
|
+
if (newWidth === currentWidth) {
|
|
9085
|
+
collapsedText = trimmedTrailing;
|
|
9086
|
+
}
|
|
9087
|
+
}
|
|
9088
|
+
if (/\s\s/.test(collapsedText)) {
|
|
9089
|
+
const currentWidth = measureWidth(collapsedText);
|
|
9090
|
+
const collapsedInternal = collapsedText.replace(/\s\s+/g, " ");
|
|
9091
|
+
const newWidth = measureWidth(collapsedInternal);
|
|
9092
|
+
if (newWidth === currentWidth) {
|
|
9093
|
+
collapsedText = collapsedInternal;
|
|
9094
|
+
}
|
|
9095
|
+
}
|
|
9096
|
+
textNode.textContent = originalText;
|
|
9097
|
+
return collapsedText;
|
|
9098
|
+
};
|
|
9099
|
+
|
|
9100
|
+
// src/drawing/text/find-line-breaks.text.ts
|
|
9101
|
+
function findLineBreaks(span, rtl) {
|
|
9102
|
+
const textNode = span.childNodes[0];
|
|
9103
|
+
const originalText = textNode.textContent;
|
|
9104
|
+
const originalRect = span.getBoundingClientRect();
|
|
9105
|
+
const computedStyle = getComputedStyle(span);
|
|
9106
|
+
const segmenter = new Intl.Segmenter("en", { granularity: "word" });
|
|
9107
|
+
const segments = segmenter.segment(originalText);
|
|
9108
|
+
const words = Array.from(segments).map((s) => s.segment);
|
|
9109
|
+
const lines = [];
|
|
9110
|
+
let currentLine = "";
|
|
9111
|
+
let testText = "";
|
|
9112
|
+
let previousRect = originalRect;
|
|
9113
|
+
textNode.textContent = "";
|
|
9114
|
+
for (let i = 0;i < words.length; i += 1) {
|
|
9115
|
+
const word = words[i];
|
|
9116
|
+
testText += word;
|
|
9117
|
+
let wordsToAdd = word;
|
|
9118
|
+
while (typeof words[i + 1] !== "undefined" && words[i + 1].trim() === "") {
|
|
9119
|
+
testText += words[i + 1];
|
|
9120
|
+
wordsToAdd += words[i + 1];
|
|
9121
|
+
i++;
|
|
9122
|
+
}
|
|
9123
|
+
previousRect = span.getBoundingClientRect();
|
|
9124
|
+
textNode.textContent = testText;
|
|
9125
|
+
const collapsedText = getCollapsedText(span);
|
|
9126
|
+
textNode.textContent = collapsedText;
|
|
9127
|
+
const rect = span.getBoundingClientRect();
|
|
9128
|
+
const currentHeight = rect.height;
|
|
9129
|
+
if (previousRect && previousRect.height !== 0 && Math.abs(currentHeight - previousRect.height) > 2) {
|
|
9130
|
+
const offsetHorizontal = rtl ? previousRect.right - originalRect.right : previousRect.left - originalRect.left;
|
|
9131
|
+
const shouldCollapse = !computedStyle.whiteSpaceCollapse.includes("preserve");
|
|
9132
|
+
lines.push({
|
|
9133
|
+
text: shouldCollapse ? currentLine.trim() : currentLine,
|
|
9134
|
+
offsetTop: currentHeight - previousRect.height,
|
|
9135
|
+
offsetHorizontal
|
|
9136
|
+
});
|
|
9137
|
+
currentLine = wordsToAdd;
|
|
9138
|
+
} else {
|
|
9139
|
+
currentLine += wordsToAdd;
|
|
9140
|
+
}
|
|
9141
|
+
}
|
|
9142
|
+
if (currentLine) {
|
|
9143
|
+
textNode.textContent = testText;
|
|
9144
|
+
const rects = span.getClientRects();
|
|
9145
|
+
const rect = span.getBoundingClientRect();
|
|
9146
|
+
const lastRect = rects[rects.length - 1];
|
|
9147
|
+
const offsetHorizontal = rtl ? lastRect.right - originalRect.right : lastRect.left - originalRect.left;
|
|
9148
|
+
lines.push({
|
|
9149
|
+
text: currentLine,
|
|
9150
|
+
offsetTop: rect.height - previousRect.height,
|
|
9151
|
+
offsetHorizontal
|
|
9152
|
+
});
|
|
9153
|
+
}
|
|
9154
|
+
textNode.textContent = originalText;
|
|
9155
|
+
return lines;
|
|
9156
|
+
}
|
|
9157
|
+
|
|
9158
|
+
// src/drawing/text/handle-text-node.ts
|
|
9159
|
+
var applyTextTransform = (text, transform) => {
|
|
9160
|
+
if (transform === "uppercase") {
|
|
9161
|
+
return text.toUpperCase();
|
|
9162
|
+
}
|
|
9163
|
+
if (transform === "lowercase") {
|
|
9164
|
+
return text.toLowerCase();
|
|
9165
|
+
}
|
|
9166
|
+
if (transform === "capitalize") {
|
|
9167
|
+
return text.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
9168
|
+
}
|
|
9169
|
+
return text;
|
|
9170
|
+
};
|
|
9171
|
+
var handleTextNode = async (node, context) => {
|
|
9172
|
+
const span = document.createElement("span");
|
|
9173
|
+
const parent = node.parentNode;
|
|
9174
|
+
if (!parent) {
|
|
9175
|
+
throw new Error("Text node has no parent");
|
|
9176
|
+
}
|
|
9177
|
+
parent.insertBefore(span, node);
|
|
9178
|
+
span.appendChild(node);
|
|
9179
|
+
await drawElementToCanvas({
|
|
9180
|
+
context,
|
|
9181
|
+
element: span,
|
|
9182
|
+
draw(rect, style) {
|
|
9183
|
+
const {
|
|
9184
|
+
fontFamily,
|
|
9185
|
+
fontSize,
|
|
9186
|
+
fontWeight,
|
|
9187
|
+
color,
|
|
9188
|
+
lineHeight,
|
|
9189
|
+
direction,
|
|
9190
|
+
writingMode,
|
|
9191
|
+
letterSpacing,
|
|
9192
|
+
textTransform
|
|
9193
|
+
} = style;
|
|
9194
|
+
const isVertical = writingMode !== "horizontal-tb";
|
|
9195
|
+
if (isVertical) {
|
|
9196
|
+
Internals3.Log.warn({
|
|
9197
|
+
logLevel: "warn",
|
|
9198
|
+
tag: "@remotion/web-renderer"
|
|
9199
|
+
}, 'Detected "writing-mode" CSS property. Vertical text is not yet supported in @remotion/web-renderer');
|
|
9200
|
+
return;
|
|
9201
|
+
}
|
|
9202
|
+
context.save();
|
|
9203
|
+
context.font = `${fontWeight} ${fontSize} ${fontFamily}`;
|
|
9204
|
+
context.fillStyle = color;
|
|
9205
|
+
context.letterSpacing = letterSpacing;
|
|
9206
|
+
const fontSizePx = parseFloat(fontSize);
|
|
9207
|
+
const lineHeightPx = lineHeight === "normal" ? 1.2 * fontSizePx : parseFloat(lineHeight);
|
|
9208
|
+
const baselineOffset = (lineHeightPx - fontSizePx) / 2;
|
|
9209
|
+
const isRTL = direction === "rtl";
|
|
9210
|
+
context.textAlign = isRTL ? "right" : "left";
|
|
9211
|
+
context.textBaseline = "top";
|
|
9212
|
+
const originalText = span.textContent;
|
|
9213
|
+
const collapsedText = getCollapsedText(span);
|
|
9214
|
+
const transformedText = applyTextTransform(collapsedText, textTransform);
|
|
9215
|
+
span.textContent = transformedText;
|
|
9216
|
+
const xPosition = isRTL ? rect.right : rect.left;
|
|
9217
|
+
const lines = findLineBreaks(span, isRTL);
|
|
9218
|
+
let offsetTop = 0;
|
|
9219
|
+
for (const line of lines) {
|
|
9220
|
+
context.fillText(line.text, xPosition + line.offsetHorizontal, rect.top + baselineOffset + offsetTop);
|
|
9221
|
+
offsetTop += line.offsetTop;
|
|
9222
|
+
}
|
|
9223
|
+
span.textContent = originalText;
|
|
9224
|
+
context.restore();
|
|
9225
|
+
}
|
|
9226
|
+
});
|
|
9227
|
+
parent.insertBefore(node, span);
|
|
9228
|
+
parent.removeChild(span);
|
|
9229
|
+
};
|
|
9230
|
+
|
|
9231
|
+
// src/drawing/turn-svg-into-drawable.ts
|
|
9232
|
+
var turnSvgIntoDrawable = (svg) => {
|
|
9233
|
+
const originalTransform = svg.style.transform;
|
|
9234
|
+
const originalTransformOrigin = svg.style.transformOrigin;
|
|
9235
|
+
const originalMarginLeft = svg.style.marginLeft;
|
|
9236
|
+
const originalMarginRight = svg.style.marginRight;
|
|
9237
|
+
const originalMarginTop = svg.style.marginTop;
|
|
9238
|
+
const originalMarginBottom = svg.style.marginBottom;
|
|
9239
|
+
svg.style.transform = "none";
|
|
9240
|
+
svg.style.transformOrigin = "";
|
|
9241
|
+
svg.style.marginLeft = "0";
|
|
9242
|
+
svg.style.marginRight = "0";
|
|
9243
|
+
svg.style.marginTop = "0";
|
|
9244
|
+
svg.style.marginBottom = "0";
|
|
9245
|
+
const svgData = new XMLSerializer().serializeToString(svg);
|
|
9246
|
+
svg.style.marginLeft = originalMarginLeft;
|
|
9247
|
+
svg.style.marginRight = originalMarginRight;
|
|
9248
|
+
svg.style.marginTop = originalMarginTop;
|
|
9249
|
+
svg.style.marginBottom = originalMarginBottom;
|
|
9250
|
+
svg.style.transform = originalTransform;
|
|
9251
|
+
svg.style.transformOrigin = originalTransformOrigin;
|
|
9252
|
+
return new Promise((resolve, reject) => {
|
|
9253
|
+
const image = new Image;
|
|
9254
|
+
const url2 = `data:image/svg+xml;base64,${btoa(svgData)}`;
|
|
9255
|
+
image.onload = function() {
|
|
9256
|
+
resolve(image);
|
|
9257
|
+
};
|
|
9258
|
+
image.onerror = () => {
|
|
9259
|
+
reject(new Error("Failed to convert SVG to image"));
|
|
9260
|
+
};
|
|
9261
|
+
image.src = url2;
|
|
9262
|
+
});
|
|
9263
|
+
};
|
|
9264
|
+
|
|
9086
9265
|
// src/compose.ts
|
|
9087
9266
|
var compose = async (element, context) => {
|
|
9088
9267
|
const treeWalker = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, (node) => {
|
|
9089
9268
|
if (node instanceof Element) {
|
|
9269
|
+
if (node.parentElement instanceof SVGSVGElement) {
|
|
9270
|
+
return NodeFilter.FILTER_REJECT;
|
|
9271
|
+
}
|
|
9090
9272
|
const computedStyle = getComputedStyle(node);
|
|
9091
9273
|
return computedStyle.display === "none" ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT;
|
|
9092
9274
|
}
|
|
@@ -9095,7 +9277,18 @@ var compose = async (element, context) => {
|
|
|
9095
9277
|
while (treeWalker.nextNode()) {
|
|
9096
9278
|
const node = treeWalker.currentNode;
|
|
9097
9279
|
if (node instanceof HTMLElement || node instanceof SVGElement) {
|
|
9098
|
-
await drawElementToCanvas({
|
|
9280
|
+
await drawElementToCanvas({
|
|
9281
|
+
element: node,
|
|
9282
|
+
context,
|
|
9283
|
+
draw: async (dimensions) => {
|
|
9284
|
+
const drawable = await (node instanceof SVGSVGElement ? turnSvgIntoDrawable(node) : node instanceof HTMLImageElement ? node : node instanceof HTMLCanvasElement ? node : null);
|
|
9285
|
+
if (drawable) {
|
|
9286
|
+
context.drawImage(drawable, dimensions.left, dimensions.top, dimensions.width, dimensions.height);
|
|
9287
|
+
}
|
|
9288
|
+
}
|
|
9289
|
+
});
|
|
9290
|
+
} else if (node instanceof Text) {
|
|
9291
|
+
await handleTextNode(node, context);
|
|
9099
9292
|
}
|
|
9100
9293
|
}
|
|
9101
9294
|
};
|
|
@@ -9256,7 +9449,7 @@ var internalRenderMediaOnWeb = async ({
|
|
|
9256
9449
|
if (codec && !format.getSupportedCodecs().includes(codecToMediabunnyCodec(codec))) {
|
|
9257
9450
|
return Promise.reject(new Error(`Codec ${codec} is not supported for container ${container}`));
|
|
9258
9451
|
}
|
|
9259
|
-
const resolved = await
|
|
9452
|
+
const resolved = await Internals4.resolveVideoConfig({
|
|
9260
9453
|
calculateMetadata: composition.calculateMetadata ?? null,
|
|
9261
9454
|
signal: signal ?? new AbortController().signal,
|
|
9262
9455
|
defaultProps: composition.defaultProps ?? {},
|
|
@@ -9445,7 +9638,7 @@ var renderMediaOnWeb = (options) => {
|
|
|
9445
9638
|
};
|
|
9446
9639
|
// src/render-still-on-web.tsx
|
|
9447
9640
|
import {
|
|
9448
|
-
Internals as
|
|
9641
|
+
Internals as Internals5
|
|
9449
9642
|
} from "remotion";
|
|
9450
9643
|
async function internalRenderStillOnWeb({
|
|
9451
9644
|
frame,
|
|
@@ -9459,7 +9652,7 @@ async function internalRenderStillOnWeb({
|
|
|
9459
9652
|
signal,
|
|
9460
9653
|
onArtifact
|
|
9461
9654
|
}) {
|
|
9462
|
-
const resolved = await
|
|
9655
|
+
const resolved = await Internals5.resolveVideoConfig({
|
|
9463
9656
|
calculateMetadata: composition.calculateMetadata ?? null,
|
|
9464
9657
|
signal: signal ?? new AbortController().signal,
|
|
9465
9658
|
defaultProps: composition.defaultProps ?? {},
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/web-renderer"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/web-renderer",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.390",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"scripts": {
|
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
"author": "Remotion <jonny@remotion.dev>",
|
|
17
17
|
"license": "UNLICENSED",
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"remotion": "4.0.
|
|
19
|
+
"remotion": "4.0.390",
|
|
20
20
|
"mediabunny": "1.25.8"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
24
|
-
"@remotion/player": "4.0.
|
|
25
|
-
"@remotion/media": "4.0.
|
|
23
|
+
"@remotion/eslint-config-internal": "4.0.390",
|
|
24
|
+
"@remotion/player": "4.0.390",
|
|
25
|
+
"@remotion/media": "4.0.390",
|
|
26
26
|
"@vitejs/plugin-react": "4.1.0",
|
|
27
27
|
"@vitest/browser-playwright": "4.0.9",
|
|
28
28
|
"playwright": "1.55.1",
|
package/dist/border-radius.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export type BorderRadiusCorners = {
|
|
2
|
-
topLeft: {
|
|
3
|
-
horizontal: number;
|
|
4
|
-
vertical: number;
|
|
5
|
-
};
|
|
6
|
-
topRight: {
|
|
7
|
-
horizontal: number;
|
|
8
|
-
vertical: number;
|
|
9
|
-
};
|
|
10
|
-
bottomRight: {
|
|
11
|
-
horizontal: number;
|
|
12
|
-
vertical: number;
|
|
13
|
-
};
|
|
14
|
-
bottomLeft: {
|
|
15
|
-
horizontal: number;
|
|
16
|
-
vertical: number;
|
|
17
|
-
};
|
|
18
|
-
};
|
|
19
|
-
export declare function parseBorderRadius({ borderRadius, width, height, }: {
|
|
20
|
-
borderRadius: string;
|
|
21
|
-
width: number;
|
|
22
|
-
height: number;
|
|
23
|
-
}): BorderRadiusCorners;
|
|
24
|
-
export declare function setBorderRadius({ ctx, x, y, width, height, borderRadius, }: {
|
|
25
|
-
ctx: OffscreenCanvasRenderingContext2D;
|
|
26
|
-
x: number;
|
|
27
|
-
y: number;
|
|
28
|
-
width: number;
|
|
29
|
-
height: number;
|
|
30
|
-
borderRadius: BorderRadiusCorners;
|
|
31
|
-
}): () => void;
|
package/dist/border-radius.js
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
function parseValue({ value, reference, }) {
|
|
2
|
-
value = value.trim();
|
|
3
|
-
if (value.endsWith('%')) {
|
|
4
|
-
const percentage = parseFloat(value);
|
|
5
|
-
return (percentage / 100) * reference;
|
|
6
|
-
}
|
|
7
|
-
if (value.endsWith('px')) {
|
|
8
|
-
return parseFloat(value);
|
|
9
|
-
}
|
|
10
|
-
// If no unit, assume pixels
|
|
11
|
-
return parseFloat(value);
|
|
12
|
-
}
|
|
13
|
-
function expandShorthand(values) {
|
|
14
|
-
if (values.length === 1) {
|
|
15
|
-
// All corners the same
|
|
16
|
-
return [values[0], values[0], values[0], values[0]];
|
|
17
|
-
}
|
|
18
|
-
if (values.length === 2) {
|
|
19
|
-
// [0] = top-left & bottom-right, [1] = top-right & bottom-left
|
|
20
|
-
return [values[0], values[1], values[0], values[1]];
|
|
21
|
-
}
|
|
22
|
-
if (values.length === 3) {
|
|
23
|
-
// [0] = top-left, [1] = top-right & bottom-left, [2] = bottom-right
|
|
24
|
-
return [values[0], values[1], values[2], values[1]];
|
|
25
|
-
}
|
|
26
|
-
// 4 values: top-left, top-right, bottom-right, bottom-left
|
|
27
|
-
return [values[0], values[1], values[2], values[3]];
|
|
28
|
-
}
|
|
29
|
-
function clampBorderRadius({ borderRadius, width, height, }) {
|
|
30
|
-
// According to CSS spec, if the sum of border radii on adjacent corners
|
|
31
|
-
// exceeds the length of the edge, they should be proportionally reduced
|
|
32
|
-
const clamped = {
|
|
33
|
-
topLeft: { ...borderRadius.topLeft },
|
|
34
|
-
topRight: { ...borderRadius.topRight },
|
|
35
|
-
bottomRight: { ...borderRadius.bottomRight },
|
|
36
|
-
bottomLeft: { ...borderRadius.bottomLeft },
|
|
37
|
-
};
|
|
38
|
-
// Check top edge
|
|
39
|
-
const topSum = clamped.topLeft.horizontal + clamped.topRight.horizontal;
|
|
40
|
-
if (topSum > width) {
|
|
41
|
-
const factor = width / topSum;
|
|
42
|
-
clamped.topLeft.horizontal *= factor;
|
|
43
|
-
clamped.topRight.horizontal *= factor;
|
|
44
|
-
}
|
|
45
|
-
// Check right edge
|
|
46
|
-
const rightSum = clamped.topRight.vertical + clamped.bottomRight.vertical;
|
|
47
|
-
if (rightSum > height) {
|
|
48
|
-
const factor = height / rightSum;
|
|
49
|
-
clamped.topRight.vertical *= factor;
|
|
50
|
-
clamped.bottomRight.vertical *= factor;
|
|
51
|
-
}
|
|
52
|
-
// Check bottom edge
|
|
53
|
-
const bottomSum = clamped.bottomRight.horizontal + clamped.bottomLeft.horizontal;
|
|
54
|
-
if (bottomSum > width) {
|
|
55
|
-
const factor = width / bottomSum;
|
|
56
|
-
clamped.bottomRight.horizontal *= factor;
|
|
57
|
-
clamped.bottomLeft.horizontal *= factor;
|
|
58
|
-
}
|
|
59
|
-
// Check left edge
|
|
60
|
-
const leftSum = clamped.bottomLeft.vertical + clamped.topLeft.vertical;
|
|
61
|
-
if (leftSum > height) {
|
|
62
|
-
const factor = height / leftSum;
|
|
63
|
-
clamped.bottomLeft.vertical *= factor;
|
|
64
|
-
clamped.topLeft.vertical *= factor;
|
|
65
|
-
}
|
|
66
|
-
return clamped;
|
|
67
|
-
}
|
|
68
|
-
export function parseBorderRadius({ borderRadius, width, height, }) {
|
|
69
|
-
// Split by '/' to separate horizontal and vertical radii
|
|
70
|
-
const parts = borderRadius.split('/').map((part) => part.trim());
|
|
71
|
-
const horizontalPart = parts[0];
|
|
72
|
-
const verticalPart = parts[1];
|
|
73
|
-
// Split each part into individual values
|
|
74
|
-
const horizontalValues = horizontalPart.split(/\s+/).filter((v) => v);
|
|
75
|
-
const verticalValues = verticalPart
|
|
76
|
-
? verticalPart.split(/\s+/).filter((v) => v)
|
|
77
|
-
: horizontalValues; // If no '/', use horizontal values for vertical
|
|
78
|
-
// Expand shorthand to 4 values
|
|
79
|
-
const [hTopLeft, hTopRight, hBottomRight, hBottomLeft] = expandShorthand(horizontalValues);
|
|
80
|
-
const [vTopLeft, vTopRight, vBottomRight, vBottomLeft] = expandShorthand(verticalValues);
|
|
81
|
-
return clampBorderRadius({
|
|
82
|
-
borderRadius: {
|
|
83
|
-
topLeft: {
|
|
84
|
-
horizontal: parseValue({ value: hTopLeft, reference: width }),
|
|
85
|
-
vertical: parseValue({ value: vTopLeft, reference: height }),
|
|
86
|
-
},
|
|
87
|
-
topRight: {
|
|
88
|
-
horizontal: parseValue({ value: hTopRight, reference: width }),
|
|
89
|
-
vertical: parseValue({ value: vTopRight, reference: height }),
|
|
90
|
-
},
|
|
91
|
-
bottomRight: {
|
|
92
|
-
horizontal: parseValue({ value: hBottomRight, reference: width }),
|
|
93
|
-
vertical: parseValue({ value: vBottomRight, reference: height }),
|
|
94
|
-
},
|
|
95
|
-
bottomLeft: {
|
|
96
|
-
horizontal: parseValue({ value: hBottomLeft, reference: width }),
|
|
97
|
-
vertical: parseValue({ value: vBottomLeft, reference: height }),
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
width,
|
|
101
|
-
height,
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
export function setBorderRadius({ ctx, x, y, width, height, borderRadius, }) {
|
|
105
|
-
if (borderRadius.topLeft.horizontal === 0 &&
|
|
106
|
-
borderRadius.topLeft.vertical === 0 &&
|
|
107
|
-
borderRadius.topRight.horizontal === 0 &&
|
|
108
|
-
borderRadius.topRight.vertical === 0 &&
|
|
109
|
-
borderRadius.bottomRight.horizontal === 0 &&
|
|
110
|
-
borderRadius.bottomRight.vertical === 0 &&
|
|
111
|
-
borderRadius.bottomLeft.horizontal === 0 &&
|
|
112
|
-
borderRadius.bottomLeft.vertical === 0) {
|
|
113
|
-
return () => { };
|
|
114
|
-
}
|
|
115
|
-
ctx.save();
|
|
116
|
-
ctx.beginPath();
|
|
117
|
-
// Start at top-left corner, after the horizontal radius
|
|
118
|
-
ctx.moveTo(x + borderRadius.topLeft.horizontal, y);
|
|
119
|
-
// Top edge to top-right corner
|
|
120
|
-
ctx.lineTo(x + width - borderRadius.topRight.horizontal, y);
|
|
121
|
-
// Top-right corner (elliptical arc)
|
|
122
|
-
if (borderRadius.topRight.horizontal > 0 ||
|
|
123
|
-
borderRadius.topRight.vertical > 0) {
|
|
124
|
-
ctx.ellipse(x + width - borderRadius.topRight.horizontal, y + borderRadius.topRight.vertical, borderRadius.topRight.horizontal, borderRadius.topRight.vertical, 0, -Math.PI / 2, 0);
|
|
125
|
-
}
|
|
126
|
-
// Right edge to bottom-right corner
|
|
127
|
-
ctx.lineTo(x + width, y + height - borderRadius.bottomRight.vertical);
|
|
128
|
-
// Bottom-right corner (elliptical arc)
|
|
129
|
-
if (borderRadius.bottomRight.horizontal > 0 ||
|
|
130
|
-
borderRadius.bottomRight.vertical > 0) {
|
|
131
|
-
ctx.ellipse(x + width - borderRadius.bottomRight.horizontal, y + height - borderRadius.bottomRight.vertical, borderRadius.bottomRight.horizontal, borderRadius.bottomRight.vertical, 0, 0, Math.PI / 2);
|
|
132
|
-
}
|
|
133
|
-
// Bottom edge to bottom-left corner
|
|
134
|
-
ctx.lineTo(x + borderRadius.bottomLeft.horizontal, y + height);
|
|
135
|
-
// Bottom-left corner (elliptical arc)
|
|
136
|
-
if (borderRadius.bottomLeft.horizontal > 0 ||
|
|
137
|
-
borderRadius.bottomLeft.vertical > 0) {
|
|
138
|
-
ctx.ellipse(x + borderRadius.bottomLeft.horizontal, y + height - borderRadius.bottomLeft.vertical, borderRadius.bottomLeft.horizontal, borderRadius.bottomLeft.vertical, 0, Math.PI / 2, Math.PI);
|
|
139
|
-
}
|
|
140
|
-
// Left edge to top-left corner
|
|
141
|
-
ctx.lineTo(x, y + borderRadius.topLeft.vertical);
|
|
142
|
-
// Top-left corner (elliptical arc)
|
|
143
|
-
if (borderRadius.topLeft.horizontal > 0 ||
|
|
144
|
-
borderRadius.topLeft.vertical > 0) {
|
|
145
|
-
ctx.ellipse(x + borderRadius.topLeft.horizontal, y + borderRadius.topLeft.vertical, borderRadius.topLeft.horizontal, borderRadius.topLeft.vertical, 0, Math.PI, (Math.PI * 3) / 2);
|
|
146
|
-
}
|
|
147
|
-
ctx.closePath();
|
|
148
|
-
ctx.clip();
|
|
149
|
-
return () => {
|
|
150
|
-
ctx.restore();
|
|
151
|
-
};
|
|
152
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export declare const calculateTransforms: (element: HTMLElement | SVGSVGElement) => {
|
|
2
|
-
dimensions: DOMRect;
|
|
3
|
-
totalMatrix: DOMMatrix;
|
|
4
|
-
reset: () => void;
|
|
5
|
-
nativeTransformOrigin: {
|
|
6
|
-
x: number;
|
|
7
|
-
y: number;
|
|
8
|
-
};
|
|
9
|
-
borderRadius: import("./drawing/border-radius").BorderRadiusCorners;
|
|
10
|
-
opacity: number;
|
|
11
|
-
};
|