@remotion/web-renderer 4.0.384 → 4.0.386
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.d.ts +5 -1
- package/dist/audio.js +12 -19
- package/dist/border-radius.d.ts +31 -0
- package/dist/border-radius.js +152 -0
- package/dist/calculate-transforms.d.ts +2 -0
- package/dist/calculate-transforms.js +17 -0
- package/dist/composable.d.ts +2 -8
- package/dist/compose-canvas.js +28 -4
- package/dist/compose.d.ts +1 -6
- package/dist/compose.js +16 -11
- package/dist/drawing/border-radius.d.ts +31 -0
- package/dist/drawing/border-radius.js +152 -0
- package/dist/drawing/calculate-transforms.d.ts +10 -0
- package/dist/drawing/calculate-transforms.js +81 -0
- 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-border.d.ts +10 -0
- package/dist/drawing/draw-border.js +101 -0
- package/dist/drawing/draw-element-to-canvas.d.ts +4 -0
- package/dist/drawing/draw-element-to-canvas.js +72 -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/opacity.d.ts +4 -0
- package/dist/drawing/opacity.js +7 -0
- package/dist/drawing/parse-transform-origin.d.ts +4 -0
- package/dist/drawing/parse-transform-origin.js +7 -0
- package/dist/drawing/transform.d.ts +4 -0
- package/dist/drawing/transform.js +6 -0
- package/dist/drawing/turn-svg-into-drawable.d.ts +1 -0
- package/dist/drawing/turn-svg-into-drawable.js +34 -0
- package/dist/esm/index.mjs +363 -79
- package/dist/find-capturable-elements.d.ts +1 -1
- package/dist/find-capturable-elements.js +20 -22
- package/dist/opacity.d.ts +4 -0
- package/dist/opacity.js +7 -0
- package/dist/render-media-on-web.js +14 -5
- package/dist/take-screenshot.js +7 -8
- package/dist/transform.d.ts +4 -0
- package/dist/transform.js +6 -0
- package/package.json +5 -5
package/dist/esm/index.mjs
CHANGED
|
@@ -8350,37 +8350,36 @@ function mixAudio(waves, length) {
|
|
|
8350
8350
|
}
|
|
8351
8351
|
const mixed = new Int16Array(length);
|
|
8352
8352
|
for (let i = 0;i < length; i++) {
|
|
8353
|
-
const sum = waves.reduce((acc, wave2) =>
|
|
8353
|
+
const sum = waves.reduce((acc, wave2) => {
|
|
8354
|
+
return acc + (wave2[i] ?? 0);
|
|
8355
|
+
}, 0);
|
|
8354
8356
|
mixed[i] = Math.max(-32768, Math.min(32767, sum));
|
|
8355
8357
|
}
|
|
8356
8358
|
return mixed;
|
|
8357
8359
|
}
|
|
8358
|
-
var onlyInlineAudio = (
|
|
8360
|
+
var onlyInlineAudio = ({
|
|
8361
|
+
assets,
|
|
8362
|
+
fps,
|
|
8363
|
+
frame
|
|
8364
|
+
}) => {
|
|
8359
8365
|
const inlineAudio = assets.filter((asset) => asset.type === "inline-audio");
|
|
8360
|
-
|
|
8366
|
+
if (inlineAudio.length === 0) {
|
|
8367
|
+
return null;
|
|
8368
|
+
}
|
|
8369
|
+
const expectedLength = Math.round(TARGET_NUMBER_OF_CHANNELS * TARGET_SAMPLE_RATE / fps);
|
|
8361
8370
|
for (const asset of inlineAudio) {
|
|
8362
8371
|
if (asset.toneFrequency !== 1) {
|
|
8363
8372
|
throw new Error("Setting the toneFrequency is not supported yet in web rendering.");
|
|
8364
8373
|
}
|
|
8365
|
-
if (length === null) {
|
|
8366
|
-
length = asset.audio.length;
|
|
8367
|
-
} else if (Math.abs(length - asset.audio.length) > TARGET_NUMBER_OF_CHANNELS) {
|
|
8368
|
-
throw new Error("All inline audio must have the same length");
|
|
8369
|
-
} else {
|
|
8370
|
-
length = Math.min(length, asset.audio.length);
|
|
8371
|
-
}
|
|
8372
8374
|
}
|
|
8373
|
-
|
|
8374
|
-
return null;
|
|
8375
|
-
}
|
|
8376
|
-
const mixedAudio = mixAudio(inlineAudio.map((asset) => asset.audio), length);
|
|
8375
|
+
const mixedAudio = mixAudio(inlineAudio.map((asset) => asset.audio), expectedLength);
|
|
8377
8376
|
return new AudioData({
|
|
8378
8377
|
data: mixedAudio,
|
|
8379
8378
|
format: "s16",
|
|
8380
8379
|
numberOfChannels: TARGET_NUMBER_OF_CHANNELS,
|
|
8381
|
-
numberOfFrames:
|
|
8380
|
+
numberOfFrames: expectedLength / TARGET_NUMBER_OF_CHANNELS,
|
|
8382
8381
|
sampleRate: TARGET_SAMPLE_RATE,
|
|
8383
|
-
timestamp:
|
|
8382
|
+
timestamp: frame / fps * 1e6
|
|
8384
8383
|
});
|
|
8385
8384
|
};
|
|
8386
8385
|
|
|
@@ -8656,7 +8655,143 @@ var getQualityForWebRendererQuality = (quality) => {
|
|
|
8656
8655
|
}
|
|
8657
8656
|
};
|
|
8658
8657
|
|
|
8659
|
-
// src/
|
|
8658
|
+
// src/drawing/border-radius.ts
|
|
8659
|
+
function parseValue({
|
|
8660
|
+
value,
|
|
8661
|
+
reference
|
|
8662
|
+
}) {
|
|
8663
|
+
value = value.trim();
|
|
8664
|
+
if (value.endsWith("%")) {
|
|
8665
|
+
const percentage = parseFloat(value);
|
|
8666
|
+
return percentage / 100 * reference;
|
|
8667
|
+
}
|
|
8668
|
+
if (value.endsWith("px")) {
|
|
8669
|
+
return parseFloat(value);
|
|
8670
|
+
}
|
|
8671
|
+
return parseFloat(value);
|
|
8672
|
+
}
|
|
8673
|
+
function expandShorthand(values) {
|
|
8674
|
+
if (values.length === 1) {
|
|
8675
|
+
return [values[0], values[0], values[0], values[0]];
|
|
8676
|
+
}
|
|
8677
|
+
if (values.length === 2) {
|
|
8678
|
+
return [values[0], values[1], values[0], values[1]];
|
|
8679
|
+
}
|
|
8680
|
+
if (values.length === 3) {
|
|
8681
|
+
return [values[0], values[1], values[2], values[1]];
|
|
8682
|
+
}
|
|
8683
|
+
return [values[0], values[1], values[2], values[3]];
|
|
8684
|
+
}
|
|
8685
|
+
function clampBorderRadius({
|
|
8686
|
+
borderRadius,
|
|
8687
|
+
width,
|
|
8688
|
+
height
|
|
8689
|
+
}) {
|
|
8690
|
+
const clamped = {
|
|
8691
|
+
topLeft: { ...borderRadius.topLeft },
|
|
8692
|
+
topRight: { ...borderRadius.topRight },
|
|
8693
|
+
bottomRight: { ...borderRadius.bottomRight },
|
|
8694
|
+
bottomLeft: { ...borderRadius.bottomLeft }
|
|
8695
|
+
};
|
|
8696
|
+
const topSum = clamped.topLeft.horizontal + clamped.topRight.horizontal;
|
|
8697
|
+
if (topSum > width) {
|
|
8698
|
+
const factor = width / topSum;
|
|
8699
|
+
clamped.topLeft.horizontal *= factor;
|
|
8700
|
+
clamped.topRight.horizontal *= factor;
|
|
8701
|
+
}
|
|
8702
|
+
const rightSum = clamped.topRight.vertical + clamped.bottomRight.vertical;
|
|
8703
|
+
if (rightSum > height) {
|
|
8704
|
+
const factor = height / rightSum;
|
|
8705
|
+
clamped.topRight.vertical *= factor;
|
|
8706
|
+
clamped.bottomRight.vertical *= factor;
|
|
8707
|
+
}
|
|
8708
|
+
const bottomSum = clamped.bottomRight.horizontal + clamped.bottomLeft.horizontal;
|
|
8709
|
+
if (bottomSum > width) {
|
|
8710
|
+
const factor = width / bottomSum;
|
|
8711
|
+
clamped.bottomRight.horizontal *= factor;
|
|
8712
|
+
clamped.bottomLeft.horizontal *= factor;
|
|
8713
|
+
}
|
|
8714
|
+
const leftSum = clamped.bottomLeft.vertical + clamped.topLeft.vertical;
|
|
8715
|
+
if (leftSum > height) {
|
|
8716
|
+
const factor = height / leftSum;
|
|
8717
|
+
clamped.bottomLeft.vertical *= factor;
|
|
8718
|
+
clamped.topLeft.vertical *= factor;
|
|
8719
|
+
}
|
|
8720
|
+
return clamped;
|
|
8721
|
+
}
|
|
8722
|
+
function parseBorderRadius({
|
|
8723
|
+
borderRadius,
|
|
8724
|
+
width,
|
|
8725
|
+
height
|
|
8726
|
+
}) {
|
|
8727
|
+
const parts = borderRadius.split("/").map((part) => part.trim());
|
|
8728
|
+
const horizontalPart = parts[0];
|
|
8729
|
+
const verticalPart = parts[1];
|
|
8730
|
+
const horizontalValues = horizontalPart.split(/\s+/).filter((v) => v);
|
|
8731
|
+
const verticalValues = verticalPart ? verticalPart.split(/\s+/).filter((v) => v) : horizontalValues;
|
|
8732
|
+
const [hTopLeft, hTopRight, hBottomRight, hBottomLeft] = expandShorthand(horizontalValues);
|
|
8733
|
+
const [vTopLeft, vTopRight, vBottomRight, vBottomLeft] = expandShorthand(verticalValues);
|
|
8734
|
+
return clampBorderRadius({
|
|
8735
|
+
borderRadius: {
|
|
8736
|
+
topLeft: {
|
|
8737
|
+
horizontal: parseValue({ value: hTopLeft, reference: width }),
|
|
8738
|
+
vertical: parseValue({ value: vTopLeft, reference: height })
|
|
8739
|
+
},
|
|
8740
|
+
topRight: {
|
|
8741
|
+
horizontal: parseValue({ value: hTopRight, reference: width }),
|
|
8742
|
+
vertical: parseValue({ value: vTopRight, reference: height })
|
|
8743
|
+
},
|
|
8744
|
+
bottomRight: {
|
|
8745
|
+
horizontal: parseValue({ value: hBottomRight, reference: width }),
|
|
8746
|
+
vertical: parseValue({ value: vBottomRight, reference: height })
|
|
8747
|
+
},
|
|
8748
|
+
bottomLeft: {
|
|
8749
|
+
horizontal: parseValue({ value: hBottomLeft, reference: width }),
|
|
8750
|
+
vertical: parseValue({ value: vBottomLeft, reference: height })
|
|
8751
|
+
}
|
|
8752
|
+
},
|
|
8753
|
+
width,
|
|
8754
|
+
height
|
|
8755
|
+
});
|
|
8756
|
+
}
|
|
8757
|
+
function setBorderRadius({
|
|
8758
|
+
ctx,
|
|
8759
|
+
x,
|
|
8760
|
+
y,
|
|
8761
|
+
width,
|
|
8762
|
+
height,
|
|
8763
|
+
borderRadius
|
|
8764
|
+
}) {
|
|
8765
|
+
if (borderRadius.topLeft.horizontal === 0 && borderRadius.topLeft.vertical === 0 && borderRadius.topRight.horizontal === 0 && borderRadius.topRight.vertical === 0 && borderRadius.bottomRight.horizontal === 0 && borderRadius.bottomRight.vertical === 0 && borderRadius.bottomLeft.horizontal === 0 && borderRadius.bottomLeft.vertical === 0) {
|
|
8766
|
+
return () => {};
|
|
8767
|
+
}
|
|
8768
|
+
ctx.save();
|
|
8769
|
+
ctx.beginPath();
|
|
8770
|
+
ctx.moveTo(x + borderRadius.topLeft.horizontal, y);
|
|
8771
|
+
ctx.lineTo(x + width - borderRadius.topRight.horizontal, y);
|
|
8772
|
+
if (borderRadius.topRight.horizontal > 0 || borderRadius.topRight.vertical > 0) {
|
|
8773
|
+
ctx.ellipse(x + width - borderRadius.topRight.horizontal, y + borderRadius.topRight.vertical, borderRadius.topRight.horizontal, borderRadius.topRight.vertical, 0, -Math.PI / 2, 0);
|
|
8774
|
+
}
|
|
8775
|
+
ctx.lineTo(x + width, y + height - borderRadius.bottomRight.vertical);
|
|
8776
|
+
if (borderRadius.bottomRight.horizontal > 0 || borderRadius.bottomRight.vertical > 0) {
|
|
8777
|
+
ctx.ellipse(x + width - borderRadius.bottomRight.horizontal, y + height - borderRadius.bottomRight.vertical, borderRadius.bottomRight.horizontal, borderRadius.bottomRight.vertical, 0, 0, Math.PI / 2);
|
|
8778
|
+
}
|
|
8779
|
+
ctx.lineTo(x + borderRadius.bottomLeft.horizontal, y + height);
|
|
8780
|
+
if (borderRadius.bottomLeft.horizontal > 0 || borderRadius.bottomLeft.vertical > 0) {
|
|
8781
|
+
ctx.ellipse(x + borderRadius.bottomLeft.horizontal, y + height - borderRadius.bottomLeft.vertical, borderRadius.bottomLeft.horizontal, borderRadius.bottomLeft.vertical, 0, Math.PI / 2, Math.PI);
|
|
8782
|
+
}
|
|
8783
|
+
ctx.lineTo(x, y + borderRadius.topLeft.vertical);
|
|
8784
|
+
if (borderRadius.topLeft.horizontal > 0 || borderRadius.topLeft.vertical > 0) {
|
|
8785
|
+
ctx.ellipse(x + borderRadius.topLeft.horizontal, y + borderRadius.topLeft.vertical, borderRadius.topLeft.horizontal, borderRadius.topLeft.vertical, 0, Math.PI, Math.PI * 3 / 2);
|
|
8786
|
+
}
|
|
8787
|
+
ctx.closePath();
|
|
8788
|
+
ctx.clip();
|
|
8789
|
+
return () => {
|
|
8790
|
+
ctx.restore();
|
|
8791
|
+
};
|
|
8792
|
+
}
|
|
8793
|
+
|
|
8794
|
+
// src/drawing/parse-transform-origin.ts
|
|
8660
8795
|
var parseTransformOrigin = (transformOrigin) => {
|
|
8661
8796
|
if (transformOrigin.trim() === "") {
|
|
8662
8797
|
return null;
|
|
@@ -8665,7 +8800,7 @@ var parseTransformOrigin = (transformOrigin) => {
|
|
|
8665
8800
|
return { x: parseFloat(x), y: parseFloat(y) };
|
|
8666
8801
|
};
|
|
8667
8802
|
|
|
8668
|
-
// src/calculate-transforms.ts
|
|
8803
|
+
// src/drawing/calculate-transforms.ts
|
|
8669
8804
|
var getInternalTransformOrigin = (transform) => {
|
|
8670
8805
|
const centerX = transform.boundingClientRect.width / 2;
|
|
8671
8806
|
const centerY = transform.boundingClientRect.height / 2;
|
|
@@ -8686,8 +8821,13 @@ var calculateTransforms = (element) => {
|
|
|
8686
8821
|
let parent = element;
|
|
8687
8822
|
const transforms = [];
|
|
8688
8823
|
const toReset = [];
|
|
8824
|
+
let opacity = 1;
|
|
8689
8825
|
while (parent) {
|
|
8690
8826
|
const computedStyle = getComputedStyle(parent);
|
|
8827
|
+
const parentOpacity = computedStyle.opacity;
|
|
8828
|
+
if (parentOpacity && parentOpacity !== "") {
|
|
8829
|
+
opacity *= parseFloat(parentOpacity);
|
|
8830
|
+
}
|
|
8691
8831
|
if (computedStyle.transform && computedStyle.transform !== "none" || parent === element) {
|
|
8692
8832
|
const toParse = computedStyle.transform === "none" || computedStyle.transform === "" ? undefined : computedStyle.transform;
|
|
8693
8833
|
const matrix = new DOMMatrix(toParse);
|
|
@@ -8728,11 +8868,122 @@ var calculateTransforms = (element) => {
|
|
|
8728
8868
|
reset();
|
|
8729
8869
|
}
|
|
8730
8870
|
},
|
|
8731
|
-
nativeTransformOrigin
|
|
8871
|
+
nativeTransformOrigin,
|
|
8872
|
+
opacity
|
|
8873
|
+
};
|
|
8874
|
+
};
|
|
8875
|
+
|
|
8876
|
+
// src/drawing/draw-border.ts
|
|
8877
|
+
var drawBorder = ({
|
|
8878
|
+
ctx,
|
|
8879
|
+
x,
|
|
8880
|
+
y,
|
|
8881
|
+
width,
|
|
8882
|
+
height,
|
|
8883
|
+
borderRadius,
|
|
8884
|
+
computedStyle
|
|
8885
|
+
}) => {
|
|
8886
|
+
const {
|
|
8887
|
+
borderStyle,
|
|
8888
|
+
borderColor,
|
|
8889
|
+
borderWidth: computedBorderWidth
|
|
8890
|
+
} = computedStyle;
|
|
8891
|
+
const borderWidths = computedBorderWidth.split(/\s+/).map((w) => parseFloat(w));
|
|
8892
|
+
const borderTop = borderWidths[0] || 0;
|
|
8893
|
+
const borderRight = borderWidths[1] || borderTop;
|
|
8894
|
+
const borderBottom = borderWidths[2] || borderTop;
|
|
8895
|
+
const borderLeft = borderWidths[3] || borderRight;
|
|
8896
|
+
const hasBorder = borderStyle && borderStyle !== "none" && borderStyle !== "hidden" && (borderTop > 0 || borderRight > 0 || borderBottom > 0 || borderLeft > 0);
|
|
8897
|
+
if (!hasBorder) {
|
|
8898
|
+
return;
|
|
8899
|
+
}
|
|
8900
|
+
const originalStrokeStyle = ctx.strokeStyle;
|
|
8901
|
+
const originalLineWidth = ctx.lineWidth;
|
|
8902
|
+
const originalLineDash = ctx.getLineDash();
|
|
8903
|
+
ctx.strokeStyle = borderColor;
|
|
8904
|
+
if (borderStyle === "dashed") {
|
|
8905
|
+
const max = Math.max(borderTop, borderRight, borderBottom, borderLeft);
|
|
8906
|
+
ctx.setLineDash([max * 2, max]);
|
|
8907
|
+
} else if (borderStyle === "dotted") {
|
|
8908
|
+
ctx.setLineDash([
|
|
8909
|
+
Math.max(borderTop, borderRight, borderBottom, borderLeft)
|
|
8910
|
+
]);
|
|
8911
|
+
} else {
|
|
8912
|
+
ctx.setLineDash([]);
|
|
8913
|
+
}
|
|
8914
|
+
const maxBorderWidth = Math.max(borderTop, borderRight, borderBottom, borderLeft);
|
|
8915
|
+
ctx.beginPath();
|
|
8916
|
+
const borderX = x + maxBorderWidth / 2;
|
|
8917
|
+
const borderY = y + maxBorderWidth / 2;
|
|
8918
|
+
const borderWidth = width - maxBorderWidth;
|
|
8919
|
+
const borderHeight = height - maxBorderWidth;
|
|
8920
|
+
const adjustedBorderRadius = {
|
|
8921
|
+
topLeft: {
|
|
8922
|
+
horizontal: Math.max(0, borderRadius.topLeft.horizontal - maxBorderWidth / 2),
|
|
8923
|
+
vertical: Math.max(0, borderRadius.topLeft.vertical - maxBorderWidth / 2)
|
|
8924
|
+
},
|
|
8925
|
+
topRight: {
|
|
8926
|
+
horizontal: Math.max(0, borderRadius.topRight.horizontal - maxBorderWidth / 2),
|
|
8927
|
+
vertical: Math.max(0, borderRadius.topRight.vertical - maxBorderWidth / 2)
|
|
8928
|
+
},
|
|
8929
|
+
bottomRight: {
|
|
8930
|
+
horizontal: Math.max(0, borderRadius.bottomRight.horizontal - maxBorderWidth / 2),
|
|
8931
|
+
vertical: Math.max(0, borderRadius.bottomRight.vertical - maxBorderWidth / 2)
|
|
8932
|
+
},
|
|
8933
|
+
bottomLeft: {
|
|
8934
|
+
horizontal: Math.max(0, borderRadius.bottomLeft.horizontal - maxBorderWidth / 2),
|
|
8935
|
+
vertical: Math.max(0, borderRadius.bottomLeft.vertical - maxBorderWidth / 2)
|
|
8936
|
+
}
|
|
8937
|
+
};
|
|
8938
|
+
ctx.moveTo(borderX + adjustedBorderRadius.topLeft.horizontal, borderY);
|
|
8939
|
+
ctx.lineTo(borderX + borderWidth - adjustedBorderRadius.topRight.horizontal, borderY);
|
|
8940
|
+
if (adjustedBorderRadius.topRight.horizontal > 0 || adjustedBorderRadius.topRight.vertical > 0) {
|
|
8941
|
+
ctx.ellipse(borderX + borderWidth - adjustedBorderRadius.topRight.horizontal, borderY + adjustedBorderRadius.topRight.vertical, adjustedBorderRadius.topRight.horizontal, adjustedBorderRadius.topRight.vertical, 0, -Math.PI / 2, 0);
|
|
8942
|
+
}
|
|
8943
|
+
ctx.lineTo(borderX + borderWidth, borderY + borderHeight - adjustedBorderRadius.bottomRight.vertical);
|
|
8944
|
+
if (adjustedBorderRadius.bottomRight.horizontal > 0 || adjustedBorderRadius.bottomRight.vertical > 0) {
|
|
8945
|
+
ctx.ellipse(borderX + borderWidth - adjustedBorderRadius.bottomRight.horizontal, borderY + borderHeight - adjustedBorderRadius.bottomRight.vertical, adjustedBorderRadius.bottomRight.horizontal, adjustedBorderRadius.bottomRight.vertical, 0, 0, Math.PI / 2);
|
|
8946
|
+
}
|
|
8947
|
+
ctx.lineTo(borderX + adjustedBorderRadius.bottomLeft.horizontal, borderY + borderHeight);
|
|
8948
|
+
if (adjustedBorderRadius.bottomLeft.horizontal > 0 || adjustedBorderRadius.bottomLeft.vertical > 0) {
|
|
8949
|
+
ctx.ellipse(borderX + adjustedBorderRadius.bottomLeft.horizontal, borderY + borderHeight - adjustedBorderRadius.bottomLeft.vertical, adjustedBorderRadius.bottomLeft.horizontal, adjustedBorderRadius.bottomLeft.vertical, 0, Math.PI / 2, Math.PI);
|
|
8950
|
+
}
|
|
8951
|
+
ctx.lineTo(borderX, borderY + adjustedBorderRadius.topLeft.vertical);
|
|
8952
|
+
if (adjustedBorderRadius.topLeft.horizontal > 0 || adjustedBorderRadius.topLeft.vertical > 0) {
|
|
8953
|
+
ctx.ellipse(borderX + adjustedBorderRadius.topLeft.horizontal, borderY + adjustedBorderRadius.topLeft.vertical, adjustedBorderRadius.topLeft.horizontal, adjustedBorderRadius.topLeft.vertical, 0, Math.PI, Math.PI * 3 / 2);
|
|
8954
|
+
}
|
|
8955
|
+
ctx.closePath();
|
|
8956
|
+
ctx.lineWidth = maxBorderWidth;
|
|
8957
|
+
ctx.stroke();
|
|
8958
|
+
ctx.strokeStyle = originalStrokeStyle;
|
|
8959
|
+
ctx.lineWidth = originalLineWidth;
|
|
8960
|
+
ctx.setLineDash(originalLineDash);
|
|
8961
|
+
};
|
|
8962
|
+
|
|
8963
|
+
// src/drawing/opacity.ts
|
|
8964
|
+
var setOpacity = ({
|
|
8965
|
+
ctx,
|
|
8966
|
+
opacity
|
|
8967
|
+
}) => {
|
|
8968
|
+
const previousAlpha = ctx.globalAlpha;
|
|
8969
|
+
ctx.globalAlpha = previousAlpha * opacity;
|
|
8970
|
+
return () => {
|
|
8971
|
+
ctx.globalAlpha = previousAlpha;
|
|
8732
8972
|
};
|
|
8733
8973
|
};
|
|
8734
8974
|
|
|
8735
|
-
// src/
|
|
8975
|
+
// src/drawing/transform.ts
|
|
8976
|
+
var setTransform = ({
|
|
8977
|
+
ctx,
|
|
8978
|
+
transform
|
|
8979
|
+
}) => {
|
|
8980
|
+
ctx.setTransform(transform);
|
|
8981
|
+
return () => {
|
|
8982
|
+
ctx.setTransform(new DOMMatrix);
|
|
8983
|
+
};
|
|
8984
|
+
};
|
|
8985
|
+
|
|
8986
|
+
// src/drawing/turn-svg-into-drawable.ts
|
|
8736
8987
|
var turnSvgIntoDrawable = (svg) => {
|
|
8737
8988
|
const originalTransform = svg.style.transform;
|
|
8738
8989
|
const originalTransformOrigin = svg.style.transformOrigin;
|
|
@@ -8766,59 +9017,83 @@ var turnSvgIntoDrawable = (svg) => {
|
|
|
8766
9017
|
});
|
|
8767
9018
|
};
|
|
8768
9019
|
|
|
8769
|
-
// src/
|
|
8770
|
-
var
|
|
8771
|
-
|
|
8772
|
-
context
|
|
8773
|
-
|
|
8774
|
-
|
|
8775
|
-
|
|
9020
|
+
// src/drawing/draw-element-to-canvas.ts
|
|
9021
|
+
var drawElementToCanvas = async ({
|
|
9022
|
+
element,
|
|
9023
|
+
context
|
|
9024
|
+
}) => {
|
|
9025
|
+
const { totalMatrix, reset, dimensions, opacity } = calculateTransforms(element);
|
|
9026
|
+
if (opacity === 0) {
|
|
9027
|
+
reset();
|
|
9028
|
+
return;
|
|
9029
|
+
}
|
|
9030
|
+
if (dimensions.width <= 0 || dimensions.height <= 0) {
|
|
9031
|
+
reset();
|
|
9032
|
+
return;
|
|
9033
|
+
}
|
|
9034
|
+
const computedStyle = getComputedStyle(element);
|
|
9035
|
+
const background = computedStyle.backgroundColor;
|
|
9036
|
+
const borderRadius = parseBorderRadius({
|
|
9037
|
+
borderRadius: computedStyle.borderRadius,
|
|
9038
|
+
width: dimensions.width,
|
|
9039
|
+
height: dimensions.height
|
|
9040
|
+
});
|
|
9041
|
+
const finishTransform = setTransform({
|
|
9042
|
+
ctx: context,
|
|
9043
|
+
transform: totalMatrix
|
|
9044
|
+
});
|
|
9045
|
+
const finishBorderRadius = setBorderRadius({
|
|
9046
|
+
ctx: context,
|
|
9047
|
+
x: dimensions.left,
|
|
9048
|
+
y: dimensions.top,
|
|
9049
|
+
width: dimensions.width,
|
|
9050
|
+
height: dimensions.height,
|
|
9051
|
+
borderRadius
|
|
9052
|
+
});
|
|
9053
|
+
const finishOpacity = setOpacity({
|
|
9054
|
+
ctx: context,
|
|
9055
|
+
opacity
|
|
9056
|
+
});
|
|
9057
|
+
const drawable = element instanceof SVGSVGElement ? await turnSvgIntoDrawable(element) : element instanceof HTMLImageElement ? element : element instanceof HTMLCanvasElement ? element : null;
|
|
9058
|
+
if (background && background !== "transparent" && !(background.startsWith("rgba") && (background.endsWith(", 0)") || background.endsWith(",0")))) {
|
|
9059
|
+
const originalFillStyle = context.fillStyle;
|
|
9060
|
+
context.fillStyle = background;
|
|
9061
|
+
context.fillRect(dimensions.left, dimensions.top, dimensions.width, dimensions.height);
|
|
9062
|
+
context.fillStyle = originalFillStyle;
|
|
9063
|
+
}
|
|
9064
|
+
if (drawable) {
|
|
9065
|
+
context.drawImage(drawable, dimensions.left, dimensions.top, dimensions.width, dimensions.height);
|
|
9066
|
+
}
|
|
9067
|
+
drawBorder({
|
|
9068
|
+
ctx: context,
|
|
9069
|
+
x: dimensions.left,
|
|
9070
|
+
y: dimensions.top,
|
|
9071
|
+
width: dimensions.width,
|
|
9072
|
+
height: dimensions.height,
|
|
9073
|
+
borderRadius,
|
|
9074
|
+
computedStyle
|
|
9075
|
+
});
|
|
9076
|
+
finishOpacity();
|
|
9077
|
+
finishBorderRadius();
|
|
9078
|
+
finishTransform();
|
|
8776
9079
|
reset();
|
|
8777
9080
|
};
|
|
8778
9081
|
|
|
8779
9082
|
// src/compose.ts
|
|
8780
|
-
var compose = async ({
|
|
8781
|
-
|
|
8782
|
-
|
|
8783
|
-
|
|
8784
|
-
|
|
8785
|
-
const canvas = new OffscreenCanvas(width, height);
|
|
8786
|
-
const context = canvas.getContext("2d");
|
|
8787
|
-
if (!context) {
|
|
8788
|
-
throw new Error("Could not get context");
|
|
8789
|
-
}
|
|
8790
|
-
for (const composable of composables) {
|
|
8791
|
-
await composeCanvas(composable.element, context);
|
|
8792
|
-
}
|
|
8793
|
-
return canvas;
|
|
8794
|
-
};
|
|
8795
|
-
|
|
8796
|
-
// src/find-capturable-elements.ts
|
|
8797
|
-
var findCapturableElements = (element) => {
|
|
8798
|
-
const canvasAndSvgElements = element.querySelectorAll("svg,canvas,img");
|
|
8799
|
-
const composables = [];
|
|
8800
|
-
Array.from(canvasAndSvgElements).forEach((capturableElement) => {
|
|
8801
|
-
if (capturableElement.tagName.toLocaleLowerCase() === "canvas") {
|
|
8802
|
-
const canvas = capturableElement;
|
|
8803
|
-
composables.push({
|
|
8804
|
-
type: "canvas",
|
|
8805
|
-
element: canvas
|
|
8806
|
-
});
|
|
8807
|
-
} else if (capturableElement.tagName.toLocaleLowerCase() === "svg") {
|
|
8808
|
-
const svg = capturableElement;
|
|
8809
|
-
composables.push({
|
|
8810
|
-
type: "svg",
|
|
8811
|
-
element: svg
|
|
8812
|
-
});
|
|
8813
|
-
} else if (capturableElement.tagName.toLocaleLowerCase() === "img") {
|
|
8814
|
-
const img = capturableElement;
|
|
8815
|
-
composables.push({
|
|
8816
|
-
type: "img",
|
|
8817
|
-
element: img
|
|
8818
|
-
});
|
|
9083
|
+
var compose = async (element, context) => {
|
|
9084
|
+
const treeWalker = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, (node) => {
|
|
9085
|
+
if (node instanceof Element) {
|
|
9086
|
+
const computedStyle = getComputedStyle(node);
|
|
9087
|
+
return computedStyle.display === "none" ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT;
|
|
8819
9088
|
}
|
|
9089
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
8820
9090
|
});
|
|
8821
|
-
|
|
9091
|
+
while (treeWalker.nextNode()) {
|
|
9092
|
+
const node = treeWalker.currentNode;
|
|
9093
|
+
if (node instanceof HTMLElement || node instanceof SVGElement) {
|
|
9094
|
+
await drawElementToCanvas({ element: node, context });
|
|
9095
|
+
}
|
|
9096
|
+
}
|
|
8822
9097
|
};
|
|
8823
9098
|
|
|
8824
9099
|
// src/take-screenshot.ts
|
|
@@ -8827,13 +9102,13 @@ var createFrame = async ({
|
|
|
8827
9102
|
width,
|
|
8828
9103
|
height
|
|
8829
9104
|
}) => {
|
|
8830
|
-
const
|
|
8831
|
-
const
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
|
|
8835
|
-
|
|
8836
|
-
return
|
|
9105
|
+
const canvas = new OffscreenCanvas(width, height);
|
|
9106
|
+
const context = canvas.getContext("2d");
|
|
9107
|
+
if (!context) {
|
|
9108
|
+
throw new Error("Could not get context");
|
|
9109
|
+
}
|
|
9110
|
+
await compose(div, context);
|
|
9111
|
+
return canvas;
|
|
8837
9112
|
};
|
|
8838
9113
|
var takeScreenshot = async ({
|
|
8839
9114
|
div,
|
|
@@ -9068,8 +9343,11 @@ var internalRenderMediaOnWeb = async ({
|
|
|
9068
9343
|
encodedFrames: 0
|
|
9069
9344
|
};
|
|
9070
9345
|
const throttledOnProgress = createThrottledProgressCallback(onProgress);
|
|
9071
|
-
for (let
|
|
9072
|
-
|
|
9346
|
+
for (let frame = realFrameRange[0];frame <= realFrameRange[1]; frame++) {
|
|
9347
|
+
if (signal?.aborted) {
|
|
9348
|
+
throw new Error("renderMediaOnWeb() was cancelled");
|
|
9349
|
+
}
|
|
9350
|
+
timeUpdater.current?.update(frame);
|
|
9073
9351
|
await waitForReady({
|
|
9074
9352
|
timeoutInMilliseconds: delayRenderTimeoutInMilliseconds,
|
|
9075
9353
|
scope: delayRenderScope,
|
|
@@ -9084,20 +9362,23 @@ var internalRenderMediaOnWeb = async ({
|
|
|
9084
9362
|
width: resolved.width,
|
|
9085
9363
|
height: resolved.height
|
|
9086
9364
|
});
|
|
9365
|
+
if (signal?.aborted) {
|
|
9366
|
+
throw new Error("renderMediaOnWeb() was cancelled");
|
|
9367
|
+
}
|
|
9087
9368
|
const assets = collectAssets.current.collectAssets();
|
|
9088
9369
|
if (onArtifact) {
|
|
9089
9370
|
await artifactsHandler.handle({
|
|
9090
9371
|
imageData,
|
|
9091
|
-
frame
|
|
9372
|
+
frame,
|
|
9092
9373
|
assets,
|
|
9093
9374
|
onArtifact
|
|
9094
9375
|
});
|
|
9095
9376
|
}
|
|
9096
|
-
const audio = onlyInlineAudio(assets);
|
|
9097
9377
|
if (signal?.aborted) {
|
|
9098
9378
|
throw new Error("renderMediaOnWeb() was cancelled");
|
|
9099
9379
|
}
|
|
9100
|
-
const
|
|
9380
|
+
const audio = onlyInlineAudio({ assets, fps: resolved.fps, frame });
|
|
9381
|
+
const timestamp = Math.round((frame - realFrameRange[0]) / resolved.fps * 1e6);
|
|
9101
9382
|
const videoFrame = new VideoFrame(imageData, {
|
|
9102
9383
|
timestamp
|
|
9103
9384
|
});
|
|
@@ -9106,6 +9387,9 @@ var internalRenderMediaOnWeb = async ({
|
|
|
9106
9387
|
let frameToEncode = videoFrame;
|
|
9107
9388
|
if (onFrame) {
|
|
9108
9389
|
const returnedFrame = await onFrame(videoFrame);
|
|
9390
|
+
if (signal?.aborted) {
|
|
9391
|
+
throw new Error("renderMediaOnWeb() was cancelled");
|
|
9392
|
+
}
|
|
9109
9393
|
frameToEncode = validateVideoFrame({
|
|
9110
9394
|
originalFrame: videoFrame,
|
|
9111
9395
|
returnedFrame,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Composable } from './composable';
|
|
2
|
-
export declare const findCapturableElements: (element: HTMLDivElement) => Composable[]
|
|
2
|
+
export declare const findCapturableElements: (element: HTMLDivElement, context: OffscreenCanvasRenderingContext2D) => Promise<Composable[]>;
|
|
@@ -1,28 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
element: canvas,
|
|
10
|
-
});
|
|
1
|
+
import { drawElementToCanvas } from './drawing/draw-element-to-canvas';
|
|
2
|
+
export const findCapturableElements = async (element, context) => {
|
|
3
|
+
const treeWalker = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, (node) => {
|
|
4
|
+
if (node instanceof Element) {
|
|
5
|
+
const computedStyle = getComputedStyle(node);
|
|
6
|
+
return computedStyle.display === 'none'
|
|
7
|
+
? NodeFilter.FILTER_REJECT
|
|
8
|
+
: NodeFilter.FILTER_ACCEPT;
|
|
11
9
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
11
|
+
});
|
|
12
|
+
const composables = [];
|
|
13
|
+
while (treeWalker.nextNode()) {
|
|
14
|
+
const node = treeWalker.currentNode;
|
|
15
|
+
if (node instanceof HTMLCanvasElement ||
|
|
16
|
+
node instanceof SVGSVGElement ||
|
|
17
|
+
node instanceof HTMLImageElement) {
|
|
18
|
+
await drawElementToCanvas(node, context);
|
|
21
19
|
composables.push({
|
|
22
|
-
type: '
|
|
23
|
-
element:
|
|
20
|
+
type: 'element',
|
|
21
|
+
element: node,
|
|
24
22
|
});
|
|
25
23
|
}
|
|
26
|
-
}
|
|
24
|
+
}
|
|
27
25
|
return composables;
|
|
28
26
|
};
|
package/dist/opacity.js
ADDED
|
@@ -119,8 +119,11 @@ const internalRenderMediaOnWeb = async ({ composition, inputProps, delayRenderTi
|
|
|
119
119
|
encodedFrames: 0,
|
|
120
120
|
};
|
|
121
121
|
const throttledOnProgress = createThrottledProgressCallback(onProgress);
|
|
122
|
-
for (let
|
|
123
|
-
(
|
|
122
|
+
for (let frame = realFrameRange[0]; frame <= realFrameRange[1]; frame++) {
|
|
123
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
124
|
+
throw new Error('renderMediaOnWeb() was cancelled');
|
|
125
|
+
}
|
|
126
|
+
(_g = timeUpdater.current) === null || _g === void 0 ? void 0 : _g.update(frame);
|
|
124
127
|
await waitForReady({
|
|
125
128
|
timeoutInMilliseconds: delayRenderTimeoutInMilliseconds,
|
|
126
129
|
scope: delayRenderScope,
|
|
@@ -135,20 +138,23 @@ const internalRenderMediaOnWeb = async ({ composition, inputProps, delayRenderTi
|
|
|
135
138
|
width: resolved.width,
|
|
136
139
|
height: resolved.height,
|
|
137
140
|
});
|
|
141
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
142
|
+
throw new Error('renderMediaOnWeb() was cancelled');
|
|
143
|
+
}
|
|
138
144
|
const assets = collectAssets.current.collectAssets();
|
|
139
145
|
if (onArtifact) {
|
|
140
146
|
await artifactsHandler.handle({
|
|
141
147
|
imageData,
|
|
142
|
-
frame
|
|
148
|
+
frame,
|
|
143
149
|
assets,
|
|
144
150
|
onArtifact,
|
|
145
151
|
});
|
|
146
152
|
}
|
|
147
|
-
const audio = onlyInlineAudio(assets);
|
|
148
153
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
149
154
|
throw new Error('renderMediaOnWeb() was cancelled');
|
|
150
155
|
}
|
|
151
|
-
const
|
|
156
|
+
const audio = onlyInlineAudio({ assets, fps: resolved.fps, frame });
|
|
157
|
+
const timestamp = Math.round(((frame - realFrameRange[0]) / resolved.fps) * 1000000);
|
|
152
158
|
const videoFrame = new VideoFrame(imageData, {
|
|
153
159
|
timestamp,
|
|
154
160
|
});
|
|
@@ -158,6 +164,9 @@ const internalRenderMediaOnWeb = async ({ composition, inputProps, delayRenderTi
|
|
|
158
164
|
let frameToEncode = videoFrame;
|
|
159
165
|
if (onFrame) {
|
|
160
166
|
const returnedFrame = await onFrame(videoFrame);
|
|
167
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
168
|
+
throw new Error('renderMediaOnWeb() was cancelled');
|
|
169
|
+
}
|
|
161
170
|
frameToEncode = validateVideoFrame({
|
|
162
171
|
originalFrame: videoFrame,
|
|
163
172
|
returnedFrame,
|