@remotion/web-renderer 4.0.490 → 4.0.492
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/README.md +1 -1
- package/dist/create-scaffold.d.ts +2 -2
- package/dist/drawing/calculate-transforms.d.ts +5 -1
- package/dist/drawing/has-transform.d.ts +4 -4
- package/dist/drawing/process-node.d.ts +3 -1
- package/dist/drawing/text/handle-text-node.d.ts +3 -1
- package/dist/esm/index.mjs +238 -113
- package/dist/html-in-canvas.d.ts +8 -2
- package/dist/render-media-on-web.d.ts +0 -1
- package/dist/render-still-on-web.d.ts +0 -1
- package/dist/take-screenshot.d.ts +2 -1
- package/dist/walk-over-node.d.ts +3 -1
- package/package.json +12 -11
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @remotion/web-renderer
|
|
2
2
|
|
|
3
|
-
Render videos in the browser
|
|
3
|
+
Render videos in the browser
|
|
4
4
|
|
|
5
5
|
[](https://npmcharts.com/compare/@remotion/web-renderer?minimal=true)
|
|
6
6
|
|
|
@@ -7,7 +7,7 @@ export type ErrorHolder = {
|
|
|
7
7
|
error: Error | null;
|
|
8
8
|
};
|
|
9
9
|
export declare function checkForError(errorHolder: ErrorHolder): void;
|
|
10
|
-
export declare function createScaffold<Props extends Record<string, unknown>>({ width, height, delayRenderTimeoutInMilliseconds, logLevel, resolvedProps, id, mediaCacheSizeInBytes, durationInFrames, fps, initialFrame, schema, Component, audioEnabled, videoEnabled, defaultCodec, defaultOutName,
|
|
10
|
+
export declare function createScaffold<Props extends Record<string, unknown>>({ width, height, delayRenderTimeoutInMilliseconds, logLevel, resolvedProps, id, mediaCacheSizeInBytes, durationInFrames, fps, initialFrame, schema, Component, audioEnabled, videoEnabled, defaultCodec, defaultOutName, useHtmlInCanvas, pixelDensity }: {
|
|
11
11
|
width: number;
|
|
12
12
|
height: number;
|
|
13
13
|
delayRenderTimeoutInMilliseconds: number;
|
|
@@ -24,7 +24,7 @@ export declare function createScaffold<Props extends Record<string, unknown>>({
|
|
|
24
24
|
videoEnabled: boolean;
|
|
25
25
|
defaultCodec: Codec | null;
|
|
26
26
|
defaultOutName: string | null;
|
|
27
|
-
|
|
27
|
+
useHtmlInCanvas: boolean;
|
|
28
28
|
pixelDensity: number;
|
|
29
29
|
}): {
|
|
30
30
|
delayRenderScope: DelayRenderScope;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { LinearGradientInfo } from './parse-linear-gradient';
|
|
2
|
-
|
|
2
|
+
type TransformStyle = Pick<CSSStyleDeclaration, 'display' | 'rotate' | 'scale' | 'transform' | 'transformOrigin'>;
|
|
3
|
+
export type TransformStyleCache = WeakMap<Element, TransformStyle>;
|
|
4
|
+
export declare const calculateTransforms: ({ element, rootElement, transformStyleCache, }: {
|
|
3
5
|
element: HTMLElement | SVGElement;
|
|
4
6
|
rootElement: HTMLElement | SVGElement;
|
|
7
|
+
transformStyleCache: TransformStyleCache;
|
|
5
8
|
}) => {
|
|
6
9
|
dimensions: DOMRect;
|
|
7
10
|
totalMatrix: DOMMatrix;
|
|
@@ -20,3 +23,4 @@ export declare const calculateTransforms: ({ element, rootElement, }: {
|
|
|
20
23
|
needsPrecompositing: boolean;
|
|
21
24
|
};
|
|
22
25
|
};
|
|
26
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const hasTransformCssValue: (style: CSSStyleDeclaration) => boolean;
|
|
2
|
-
export declare const hasRotateCssValue: (style: CSSStyleDeclaration) => boolean;
|
|
3
|
-
export declare const hasScaleCssValue: (style: CSSStyleDeclaration) => boolean;
|
|
4
|
-
export declare const hasAnyTransformCssValue: (style: CSSStyleDeclaration) => boolean;
|
|
1
|
+
export declare const hasTransformCssValue: (style: Pick<CSSStyleDeclaration, "transform">) => boolean;
|
|
2
|
+
export declare const hasRotateCssValue: (style: Pick<CSSStyleDeclaration, "rotate">) => boolean;
|
|
3
|
+
export declare const hasScaleCssValue: (style: Pick<CSSStyleDeclaration, "scale">) => boolean;
|
|
4
|
+
export declare const hasAnyTransformCssValue: (style: Pick<CSSStyleDeclaration, "rotate" | "scale" | "transform">) => boolean;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type TransformStyleCache } from './calculate-transforms';
|
|
1
2
|
import type { DrawFn } from './drawn-fn';
|
|
2
3
|
export type ProcessNodeReturnValue = {
|
|
3
4
|
type: 'continue';
|
|
@@ -5,7 +6,7 @@ export type ProcessNodeReturnValue = {
|
|
|
5
6
|
} | {
|
|
6
7
|
type: 'skip-children';
|
|
7
8
|
};
|
|
8
|
-
export declare const processNode: ({ element, context, draw, logLevel, parentRect, internalState, rootElement, scale, waitForPageResponsiveness, }: {
|
|
9
|
+
export declare const processNode: ({ element, context, draw, logLevel, parentRect, internalState, rootElement, scale, waitForPageResponsiveness, transformStyleCache, }: {
|
|
9
10
|
element: HTMLElement | SVGElement;
|
|
10
11
|
context: OffscreenCanvasRenderingContext2D;
|
|
11
12
|
draw: DrawFn;
|
|
@@ -32,4 +33,5 @@ export declare const processNode: ({ element, context, draw, logLevel, parentRec
|
|
|
32
33
|
rootElement: HTMLElement | SVGElement;
|
|
33
34
|
scale: number;
|
|
34
35
|
waitForPageResponsiveness: (() => Promise<void>) | null;
|
|
36
|
+
transformStyleCache: TransformStyleCache;
|
|
35
37
|
}) => Promise<ProcessNodeReturnValue>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { TransformStyleCache } from '../calculate-transforms';
|
|
1
2
|
import type { ProcessNodeReturnValue } from '../process-node';
|
|
2
|
-
export declare const handleTextNode: ({ node, context, logLevel, parentRect, internalState, rootElement, onlyBackgroundClipText, scale, waitForPageResponsiveness, }: {
|
|
3
|
+
export declare const handleTextNode: ({ node, context, logLevel, parentRect, internalState, rootElement, onlyBackgroundClipText, scale, waitForPageResponsiveness, transformStyleCache, }: {
|
|
3
4
|
node: Text;
|
|
4
5
|
context: OffscreenCanvasRenderingContext2D;
|
|
5
6
|
logLevel: "error" | "info" | "trace" | "verbose" | "warn";
|
|
@@ -26,4 +27,5 @@ export declare const handleTextNode: ({ node, context, logLevel, parentRect, int
|
|
|
26
27
|
onlyBackgroundClipText: boolean;
|
|
27
28
|
scale: number;
|
|
28
29
|
waitForPageResponsiveness: (() => Promise<void>) | null;
|
|
30
|
+
transformStyleCache: TransformStyleCache;
|
|
29
31
|
}) => Promise<ProcessNodeReturnValue>;
|
package/dist/esm/index.mjs
CHANGED
|
@@ -824,6 +824,8 @@ import ReactDOM from "react-dom/client";
|
|
|
824
824
|
import { Internals as Internals3 } from "remotion";
|
|
825
825
|
|
|
826
826
|
// src/html-in-canvas.ts
|
|
827
|
+
var nestedHtmlInCanvasSupport = null;
|
|
828
|
+
var forceDisableHtmlInCanvasForTesting = false;
|
|
827
829
|
var supportsNativeHtmlInCanvas = () => {
|
|
828
830
|
if (typeof document === "undefined") {
|
|
829
831
|
return false;
|
|
@@ -831,6 +833,121 @@ var supportsNativeHtmlInCanvas = () => {
|
|
|
831
833
|
const ctx = document.createElement("canvas").getContext("2d");
|
|
832
834
|
return typeof ctx?.drawElementImage === "function";
|
|
833
835
|
};
|
|
836
|
+
var runNestedHtmlInCanvasProbe = () => {
|
|
837
|
+
if (!supportsNativeHtmlInCanvas() || !document.body) {
|
|
838
|
+
return Promise.resolve(false);
|
|
839
|
+
}
|
|
840
|
+
const outer = document.createElement("canvas");
|
|
841
|
+
const inner = document.createElement("canvas");
|
|
842
|
+
const outerTarget = document.createElement("div");
|
|
843
|
+
const innerTarget = document.createElement("div");
|
|
844
|
+
const outerCtx = outer.getContext("2d");
|
|
845
|
+
const innerCtx = inner.getContext("2d");
|
|
846
|
+
if (!outerCtx || !innerCtx || typeof outer.requestPaint !== "function" || typeof inner.requestPaint !== "function") {
|
|
847
|
+
return Promise.resolve(false);
|
|
848
|
+
}
|
|
849
|
+
outer.layoutSubtree = true;
|
|
850
|
+
inner.layoutSubtree = true;
|
|
851
|
+
outer.width = 4;
|
|
852
|
+
outer.height = 4;
|
|
853
|
+
inner.width = 4;
|
|
854
|
+
inner.height = 4;
|
|
855
|
+
Object.assign(outer.style, {
|
|
856
|
+
display: "block",
|
|
857
|
+
height: "4px",
|
|
858
|
+
left: "0",
|
|
859
|
+
pointerEvents: "none",
|
|
860
|
+
position: "fixed",
|
|
861
|
+
top: "0",
|
|
862
|
+
visibility: "visible",
|
|
863
|
+
width: "4px",
|
|
864
|
+
zIndex: "2147483647"
|
|
865
|
+
});
|
|
866
|
+
Object.assign(inner.style, {
|
|
867
|
+
display: "block",
|
|
868
|
+
height: "4px",
|
|
869
|
+
width: "4px"
|
|
870
|
+
});
|
|
871
|
+
Object.assign(outerTarget.style, {
|
|
872
|
+
display: "block",
|
|
873
|
+
height: "4px",
|
|
874
|
+
width: "4px"
|
|
875
|
+
});
|
|
876
|
+
Object.assign(innerTarget.style, {
|
|
877
|
+
backgroundColor: "rgb(255, 0, 0)",
|
|
878
|
+
display: "block",
|
|
879
|
+
height: "4px",
|
|
880
|
+
width: "4px"
|
|
881
|
+
});
|
|
882
|
+
inner.appendChild(innerTarget);
|
|
883
|
+
outerTarget.appendChild(inner);
|
|
884
|
+
outer.appendChild(outerTarget);
|
|
885
|
+
document.body.appendChild(outer);
|
|
886
|
+
return new Promise((resolve) => {
|
|
887
|
+
let innerPainted = false;
|
|
888
|
+
let settled = false;
|
|
889
|
+
let timeout = null;
|
|
890
|
+
const settle = (supported) => {
|
|
891
|
+
if (settled) {
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
settled = true;
|
|
895
|
+
if (timeout !== null) {
|
|
896
|
+
window.clearTimeout(timeout);
|
|
897
|
+
}
|
|
898
|
+
outer.remove();
|
|
899
|
+
resolve(supported);
|
|
900
|
+
};
|
|
901
|
+
timeout = window.setTimeout(() => settle(false), 1000);
|
|
902
|
+
inner.addEventListener("paint", () => {
|
|
903
|
+
try {
|
|
904
|
+
innerCtx.reset();
|
|
905
|
+
const transform = innerCtx.drawElementImage(innerTarget, 0, 0, 4, 4);
|
|
906
|
+
innerTarget.style.transform = transform.toString();
|
|
907
|
+
innerPainted = true;
|
|
908
|
+
requestAnimationFrame(() => outer.requestPaint());
|
|
909
|
+
} catch {
|
|
910
|
+
settle(false);
|
|
911
|
+
}
|
|
912
|
+
});
|
|
913
|
+
outer.addEventListener("paint", () => {
|
|
914
|
+
if (!innerPainted) {
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
try {
|
|
918
|
+
outerCtx.reset();
|
|
919
|
+
if (typeof outer.captureElementImage !== "function") {
|
|
920
|
+
settle(false);
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
const elementImage = outer.captureElementImage(outerTarget);
|
|
924
|
+
const transform = outerCtx.drawElementImage(elementImage, 0, 0, 4, 4);
|
|
925
|
+
elementImage.close();
|
|
926
|
+
outerTarget.style.transform = transform.toString();
|
|
927
|
+
const pixel = outerCtx.getImageData(2, 2, 1, 1).data;
|
|
928
|
+
settle(pixel[0] > 200 && pixel[1] < 20 && pixel[2] < 20 && pixel[3] > 200);
|
|
929
|
+
} catch {
|
|
930
|
+
settle(false);
|
|
931
|
+
}
|
|
932
|
+
});
|
|
933
|
+
inner.requestPaint();
|
|
934
|
+
});
|
|
935
|
+
};
|
|
936
|
+
var supportsNestedHtmlInCanvas = () => {
|
|
937
|
+
if (forceDisableHtmlInCanvasForTesting) {
|
|
938
|
+
return Promise.resolve(false);
|
|
939
|
+
}
|
|
940
|
+
if (!nestedHtmlInCanvasSupport) {
|
|
941
|
+
nestedHtmlInCanvasSupport = runNestedHtmlInCanvasProbe();
|
|
942
|
+
}
|
|
943
|
+
return nestedHtmlInCanvasSupport;
|
|
944
|
+
};
|
|
945
|
+
var countLayoutSubtreeCanvases = (element) => {
|
|
946
|
+
return Array.from(element.querySelectorAll("canvas")).filter((canvas) => canvas.layoutSubtree === true).length;
|
|
947
|
+
};
|
|
948
|
+
var containsLayoutSubtreeCanvas = (element) => {
|
|
949
|
+
return countLayoutSubtreeCanvases(element) > 0;
|
|
950
|
+
};
|
|
834
951
|
var setupHtmlInCanvas = ({
|
|
835
952
|
wrapper,
|
|
836
953
|
div,
|
|
@@ -872,14 +989,36 @@ var drawWithHtmlInCanvas = async ({
|
|
|
872
989
|
htmlInCanvasContext,
|
|
873
990
|
element,
|
|
874
991
|
scaledWidth,
|
|
875
|
-
scaledHeight
|
|
992
|
+
scaledHeight,
|
|
993
|
+
waitForRenderReady,
|
|
994
|
+
useElementImage
|
|
876
995
|
}) => {
|
|
877
996
|
const { ctx, layoutCanvas } = htmlInCanvasContext;
|
|
997
|
+
if (layoutCanvas.width !== scaledWidth || layoutCanvas.height !== scaledHeight) {
|
|
998
|
+
layoutCanvas.width = scaledWidth;
|
|
999
|
+
layoutCanvas.height = scaledHeight;
|
|
1000
|
+
}
|
|
878
1001
|
await waitForPaint(layoutCanvas);
|
|
879
|
-
|
|
880
|
-
|
|
1002
|
+
const nestedPaintCycles = useElementImage ? countLayoutSubtreeCanvases(element) * 2 + 1 : 0;
|
|
1003
|
+
for (let i = 0;i < nestedPaintCycles; i++) {
|
|
1004
|
+
await new Promise((resolve) => requestAnimationFrame(() => resolve()));
|
|
1005
|
+
await waitForRenderReady();
|
|
1006
|
+
await waitForPaint(layoutCanvas);
|
|
1007
|
+
}
|
|
881
1008
|
ctx.reset();
|
|
882
|
-
|
|
1009
|
+
if (useElementImage) {
|
|
1010
|
+
if (typeof layoutCanvas.captureElementImage !== "function") {
|
|
1011
|
+
throw new Error("canvas.captureElementImage() is unavailable");
|
|
1012
|
+
}
|
|
1013
|
+
const elementImage = layoutCanvas.captureElementImage(element);
|
|
1014
|
+
try {
|
|
1015
|
+
ctx.drawElementImage(elementImage, 0, 0, scaledWidth, scaledHeight);
|
|
1016
|
+
} finally {
|
|
1017
|
+
elementImage.close();
|
|
1018
|
+
}
|
|
1019
|
+
} else {
|
|
1020
|
+
ctx.drawElementImage(element, 0, 0, scaledWidth, scaledHeight);
|
|
1021
|
+
}
|
|
883
1022
|
const offscreen = new OffscreenCanvas(scaledWidth, scaledHeight);
|
|
884
1023
|
const offCtx = offscreen.getContext("2d");
|
|
885
1024
|
if (!offCtx) {
|
|
@@ -1020,7 +1159,7 @@ function createScaffold({
|
|
|
1020
1159
|
videoEnabled,
|
|
1021
1160
|
defaultCodec,
|
|
1022
1161
|
defaultOutName,
|
|
1023
|
-
|
|
1162
|
+
useHtmlInCanvas,
|
|
1024
1163
|
pixelDensity
|
|
1025
1164
|
}) {
|
|
1026
1165
|
if (!ReactDOM.createRoot) {
|
|
@@ -1047,7 +1186,7 @@ function createScaffold({
|
|
|
1047
1186
|
const cleanupCSS = Internals3.CSSUtils.injectCSS(Internals3.CSSUtils.makeDefaultPreviewCSS(`.${scaffoldClassName}`, "white"));
|
|
1048
1187
|
wrapper.appendChild(div);
|
|
1049
1188
|
document.body.appendChild(wrapper);
|
|
1050
|
-
const htmlInCanvasContext =
|
|
1189
|
+
const htmlInCanvasContext = useHtmlInCanvas ? setupHtmlInCanvas({ wrapper, div, width, height }) : null;
|
|
1051
1190
|
const errorHolder = { error: null };
|
|
1052
1191
|
const root = ReactDOM.createRoot(div, {
|
|
1053
1192
|
onUncaughtError: (err, errorInfo) => {
|
|
@@ -2092,6 +2231,15 @@ var filterRequiresPrecompositing = (filter) => {
|
|
|
2092
2231
|
}
|
|
2093
2232
|
return null;
|
|
2094
2233
|
};
|
|
2234
|
+
var snapshotTransformStyle = (computedStyle) => {
|
|
2235
|
+
return {
|
|
2236
|
+
display: computedStyle.display,
|
|
2237
|
+
rotate: computedStyle.rotate,
|
|
2238
|
+
scale: computedStyle.scale,
|
|
2239
|
+
transform: computedStyle.transform,
|
|
2240
|
+
transformOrigin: computedStyle.transformOrigin
|
|
2241
|
+
};
|
|
2242
|
+
};
|
|
2095
2243
|
var isReplacedElement = (element) => {
|
|
2096
2244
|
return element instanceof HTMLImageElement || element instanceof HTMLVideoElement || element instanceof HTMLCanvasElement || element instanceof HTMLIFrameElement || element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement || element instanceof HTMLObjectElement || element instanceof HTMLEmbedElement;
|
|
2097
2245
|
};
|
|
@@ -2142,7 +2290,8 @@ var getGlobalTransformOrigin = ({ transform }) => {
|
|
|
2142
2290
|
};
|
|
2143
2291
|
var calculateTransforms = ({
|
|
2144
2292
|
element,
|
|
2145
|
-
rootElement
|
|
2293
|
+
rootElement,
|
|
2294
|
+
transformStyleCache
|
|
2146
2295
|
}) => {
|
|
2147
2296
|
let parent = element;
|
|
2148
2297
|
const transforms = [];
|
|
@@ -2152,10 +2301,19 @@ var calculateTransforms = ({
|
|
|
2152
2301
|
let maskImageInfo = null;
|
|
2153
2302
|
let filterForPrecompositing = null;
|
|
2154
2303
|
while (parent) {
|
|
2304
|
+
const cachedTransformStyle = transformStyleCache.get(parent);
|
|
2305
|
+
const shouldReadComputedStyle = parent === element || cachedTransformStyle === undefined;
|
|
2155
2306
|
const originalTransition = parent.style.transition;
|
|
2156
2307
|
parent.style.transition = "none";
|
|
2157
|
-
const computedStyle = getComputedStyle(parent);
|
|
2308
|
+
const computedStyle = shouldReadComputedStyle ? getComputedStyle(parent) : null;
|
|
2309
|
+
const transformStyle = computedStyle === null ? cachedTransformStyle : snapshotTransformStyle(computedStyle);
|
|
2310
|
+
if (computedStyle !== null) {
|
|
2311
|
+
transformStyleCache.set(parent, transformStyle);
|
|
2312
|
+
}
|
|
2158
2313
|
if (parent === element) {
|
|
2314
|
+
if (computedStyle === null) {
|
|
2315
|
+
throw new Error("Element computed style not found");
|
|
2316
|
+
}
|
|
2159
2317
|
elementComputedStyle = computedStyle;
|
|
2160
2318
|
opacity = parseFloat(computedStyle.opacity);
|
|
2161
2319
|
const maskImageValue = getMaskImageValue(computedStyle);
|
|
@@ -2178,9 +2336,9 @@ var calculateTransforms = ({
|
|
|
2178
2336
|
}
|
|
2179
2337
|
});
|
|
2180
2338
|
}
|
|
2181
|
-
const hasApplicableTransformCssValue = canApplyCssTransforms({ computedStyle, element: parent }) && hasAnyTransformCssValue(
|
|
2339
|
+
const hasApplicableTransformCssValue = canApplyCssTransforms({ computedStyle: transformStyle, element: parent }) && hasAnyTransformCssValue(transformStyle);
|
|
2182
2340
|
if (hasApplicableTransformCssValue || parent === element) {
|
|
2183
|
-
const toParse = hasApplicableTransformCssValue && hasTransformCssValue(
|
|
2341
|
+
const toParse = hasApplicableTransformCssValue && hasTransformCssValue(transformStyle) ? transformStyle.transform : undefined;
|
|
2184
2342
|
const matrix = new DOMMatrix(toParse);
|
|
2185
2343
|
const resetTransforms = makeTransformResetter(parent);
|
|
2186
2344
|
const { scale, rotate } = parent.style;
|
|
@@ -2195,7 +2353,7 @@ var calculateTransforms = ({
|
|
|
2195
2353
|
const cleanup = resetTransforms(hasApplicableTransformCssValue);
|
|
2196
2354
|
transforms.push({
|
|
2197
2355
|
element: parent,
|
|
2198
|
-
transformOrigin:
|
|
2356
|
+
transformOrigin: transformStyle.transformOrigin,
|
|
2199
2357
|
boundingClientRect: null,
|
|
2200
2358
|
matrices: additionalMatrices
|
|
2201
2359
|
});
|
|
@@ -2805,7 +2963,8 @@ var drawBackground = async ({
|
|
|
2805
2963
|
internalState,
|
|
2806
2964
|
scale,
|
|
2807
2965
|
onlyBackgroundClipText: true,
|
|
2808
|
-
waitForPageResponsiveness: null
|
|
2966
|
+
waitForPageResponsiveness: null,
|
|
2967
|
+
waitForRenderReady: () => Promise.resolve()
|
|
2809
2968
|
});
|
|
2810
2969
|
onlyBackgroundClipText.setTransform(new DOMMatrix().scale(scale, scale));
|
|
2811
2970
|
element.style.backgroundClip = originalBackgroundClip;
|
|
@@ -4000,13 +4159,15 @@ var processNode = async ({
|
|
|
4000
4159
|
internalState,
|
|
4001
4160
|
rootElement,
|
|
4002
4161
|
scale,
|
|
4003
|
-
waitForPageResponsiveness
|
|
4162
|
+
waitForPageResponsiveness,
|
|
4163
|
+
transformStyleCache
|
|
4004
4164
|
}) => {
|
|
4005
4165
|
let __stack = [];
|
|
4006
4166
|
try {
|
|
4007
4167
|
const transforms = __using(__stack, calculateTransforms({
|
|
4008
4168
|
element,
|
|
4009
|
-
rootElement
|
|
4169
|
+
rootElement,
|
|
4170
|
+
transformStyleCache
|
|
4010
4171
|
}), 0);
|
|
4011
4172
|
const { opacity, computedStyle, totalMatrix, dimensions, precompositing } = transforms;
|
|
4012
4173
|
if (opacity === 0) {
|
|
@@ -4065,7 +4226,8 @@ var processNode = async ({
|
|
|
4065
4226
|
internalState,
|
|
4066
4227
|
scale,
|
|
4067
4228
|
onlyBackgroundClipText: false,
|
|
4068
|
-
waitForPageResponsiveness
|
|
4229
|
+
waitForPageResponsiveness,
|
|
4230
|
+
waitForRenderReady: () => Promise.resolve()
|
|
4069
4231
|
});
|
|
4070
4232
|
if (waitForPageResponsiveness !== null) {
|
|
4071
4233
|
await waitForPageResponsiveness();
|
|
@@ -4173,29 +4335,25 @@ var applyTextTransform = (text, transform) => {
|
|
|
4173
4335
|
};
|
|
4174
4336
|
|
|
4175
4337
|
// src/drawing/text/find-line-breaks.text.ts
|
|
4338
|
+
var wordSegmenter = new Intl.Segmenter("en", { granularity: "word" });
|
|
4176
4339
|
var findWords = (span) => {
|
|
4177
4340
|
const originalText = span.textContent;
|
|
4178
|
-
const
|
|
4179
|
-
const segments = segmenter.segment(span.textContent);
|
|
4180
|
-
const words = Array.from(segments).map((s) => s.segment);
|
|
4341
|
+
const segments = Array.from(wordSegmenter.segment(originalText));
|
|
4181
4342
|
const tokens = [];
|
|
4182
|
-
for (
|
|
4183
|
-
const
|
|
4184
|
-
const
|
|
4185
|
-
const word = words[i];
|
|
4186
|
-
const wordsBeforeText = wordsBefore.join("");
|
|
4187
|
-
const wordsAfterText = wordsAfter.join("");
|
|
4343
|
+
for (const { index, segment } of segments) {
|
|
4344
|
+
const wordsBeforeText = originalText.slice(0, index);
|
|
4345
|
+
const wordsAfterText = originalText.slice(index + segment.length);
|
|
4188
4346
|
const beforeNode = document.createTextNode(wordsBeforeText);
|
|
4189
4347
|
const afterNode = document.createTextNode(wordsAfterText);
|
|
4190
4348
|
const interstitialNode = document.createElement("span");
|
|
4191
|
-
interstitialNode.textContent =
|
|
4349
|
+
interstitialNode.textContent = segment;
|
|
4192
4350
|
span.textContent = "";
|
|
4193
4351
|
span.appendChild(beforeNode);
|
|
4194
4352
|
span.appendChild(interstitialNode);
|
|
4195
4353
|
span.appendChild(afterNode);
|
|
4196
4354
|
const rect = interstitialNode.getBoundingClientRect();
|
|
4197
4355
|
span.textContent = originalText;
|
|
4198
|
-
tokens.push({ text:
|
|
4356
|
+
tokens.push({ text: segment, rect });
|
|
4199
4357
|
}
|
|
4200
4358
|
return tokens;
|
|
4201
4359
|
};
|
|
@@ -4492,10 +4650,10 @@ var drawText = ({
|
|
|
4492
4650
|
const ctm = contextToDraw.getTransform();
|
|
4493
4651
|
const blurScale = Math.hypot(ctm.a, ctm.b);
|
|
4494
4652
|
const { strokeFirst } = parsePaintOrder(paintOrder);
|
|
4653
|
+
const measurements = contextToDraw.measureText(originalText);
|
|
4654
|
+
const { fontBoundingBoxDescent, fontBoundingBoxAscent } = measurements;
|
|
4655
|
+
const fontHeight = fontBoundingBoxAscent + fontBoundingBoxDescent;
|
|
4495
4656
|
for (const token of tokens) {
|
|
4496
|
-
const measurements = contextToDraw.measureText(originalText);
|
|
4497
|
-
const { fontBoundingBoxDescent, fontBoundingBoxAscent } = measurements;
|
|
4498
|
-
const fontHeight = fontBoundingBoxAscent + fontBoundingBoxDescent;
|
|
4499
4657
|
const leading = token.rect.height - fontHeight;
|
|
4500
4658
|
const halfLeading = leading / 2;
|
|
4501
4659
|
const x = (isRTL ? token.rect.right : token.rect.left) - parentRect.x;
|
|
@@ -4552,7 +4710,8 @@ var handleTextNode = async ({
|
|
|
4552
4710
|
rootElement,
|
|
4553
4711
|
onlyBackgroundClipText,
|
|
4554
4712
|
scale,
|
|
4555
|
-
waitForPageResponsiveness
|
|
4713
|
+
waitForPageResponsiveness,
|
|
4714
|
+
transformStyleCache
|
|
4556
4715
|
}) => {
|
|
4557
4716
|
const span = document.createElement("span");
|
|
4558
4717
|
const parent = node.parentNode;
|
|
@@ -4570,7 +4729,8 @@ var handleTextNode = async ({
|
|
|
4570
4729
|
internalState,
|
|
4571
4730
|
rootElement,
|
|
4572
4731
|
scale,
|
|
4573
|
-
waitForPageResponsiveness
|
|
4732
|
+
waitForPageResponsiveness,
|
|
4733
|
+
transformStyleCache
|
|
4574
4734
|
});
|
|
4575
4735
|
parent.insertBefore(node, span);
|
|
4576
4736
|
parent.removeChild(span);
|
|
@@ -4587,7 +4747,8 @@ var walkOverNode = ({
|
|
|
4587
4747
|
rootElement,
|
|
4588
4748
|
onlyBackgroundClipText,
|
|
4589
4749
|
scale,
|
|
4590
|
-
waitForPageResponsiveness
|
|
4750
|
+
waitForPageResponsiveness,
|
|
4751
|
+
transformStyleCache
|
|
4591
4752
|
}) => {
|
|
4592
4753
|
if (node instanceof HTMLElement || node instanceof SVGElement) {
|
|
4593
4754
|
return processNode({
|
|
@@ -4599,7 +4760,8 @@ var walkOverNode = ({
|
|
|
4599
4760
|
internalState,
|
|
4600
4761
|
rootElement,
|
|
4601
4762
|
scale,
|
|
4602
|
-
waitForPageResponsiveness
|
|
4763
|
+
waitForPageResponsiveness,
|
|
4764
|
+
transformStyleCache
|
|
4603
4765
|
});
|
|
4604
4766
|
}
|
|
4605
4767
|
if (node instanceof Text) {
|
|
@@ -4612,7 +4774,8 @@ var walkOverNode = ({
|
|
|
4612
4774
|
rootElement,
|
|
4613
4775
|
onlyBackgroundClipText,
|
|
4614
4776
|
scale,
|
|
4615
|
-
waitForPageResponsiveness
|
|
4777
|
+
waitForPageResponsiveness,
|
|
4778
|
+
transformStyleCache
|
|
4616
4779
|
});
|
|
4617
4780
|
}
|
|
4618
4781
|
throw new Error("Unknown node type");
|
|
@@ -4645,6 +4808,7 @@ var compose = async ({
|
|
|
4645
4808
|
let __stack = [];
|
|
4646
4809
|
try {
|
|
4647
4810
|
const treeWalker = document.createTreeWalker(element, onlyBackgroundClipText ? NodeFilter.SHOW_TEXT : NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, getFilterFunction);
|
|
4811
|
+
const transformStyleCache = new WeakMap;
|
|
4648
4812
|
if (onlyBackgroundClipText) {
|
|
4649
4813
|
treeWalker.nextNode();
|
|
4650
4814
|
if (!treeWalker.currentNode) {
|
|
@@ -4664,7 +4828,8 @@ var compose = async ({
|
|
|
4664
4828
|
rootElement: element,
|
|
4665
4829
|
onlyBackgroundClipText,
|
|
4666
4830
|
scale,
|
|
4667
|
-
waitForPageResponsiveness
|
|
4831
|
+
waitForPageResponsiveness,
|
|
4832
|
+
transformStyleCache
|
|
4668
4833
|
});
|
|
4669
4834
|
if (val.type === "skip-children") {
|
|
4670
4835
|
if (!skipToNextNonDescendant(treeWalker)) {
|
|
@@ -4699,17 +4864,21 @@ var createLayer = async ({
|
|
|
4699
4864
|
cutout,
|
|
4700
4865
|
htmlInCanvasContext,
|
|
4701
4866
|
onHtmlInCanvasLayerOutcome,
|
|
4702
|
-
waitForPageResponsiveness
|
|
4867
|
+
waitForPageResponsiveness,
|
|
4868
|
+
waitForRenderReady
|
|
4703
4869
|
}) => {
|
|
4704
4870
|
const scaledWidth = Math.ceil(cutout.width * scale);
|
|
4705
4871
|
const scaledHeight = Math.ceil(cutout.height * scale);
|
|
4706
4872
|
if (!onlyBackgroundClipText && element instanceof HTMLElement && htmlInCanvasContext && onHtmlInCanvasLayerOutcome) {
|
|
4873
|
+
const hasNestedHtmlInCanvas = containsLayoutSubtreeCanvas(element);
|
|
4707
4874
|
try {
|
|
4708
4875
|
const offCtx = await drawWithHtmlInCanvas({
|
|
4709
4876
|
htmlInCanvasContext,
|
|
4710
4877
|
element,
|
|
4711
4878
|
scaledWidth,
|
|
4712
|
-
scaledHeight
|
|
4879
|
+
scaledHeight,
|
|
4880
|
+
waitForRenderReady,
|
|
4881
|
+
useElementImage: hasNestedHtmlInCanvas
|
|
4713
4882
|
});
|
|
4714
4883
|
onHtmlInCanvasLayerOutcome({ native: true });
|
|
4715
4884
|
return offCtx;
|
|
@@ -4970,7 +5139,6 @@ var internalRenderMediaOnWeb = async ({
|
|
|
4970
5139
|
muted,
|
|
4971
5140
|
scale,
|
|
4972
5141
|
isProduction,
|
|
4973
|
-
allowHtmlInCanvas,
|
|
4974
5142
|
sampleRate
|
|
4975
5143
|
}) => {
|
|
4976
5144
|
let __stack2 = [];
|
|
@@ -4984,7 +5152,7 @@ var internalRenderMediaOnWeb = async ({
|
|
|
4984
5152
|
}
|
|
4985
5153
|
htmlInCanvasLayerOutcomeReported = true;
|
|
4986
5154
|
if (outcome.native) {
|
|
4987
|
-
Internals9.Log.warn({ logLevel, tag: "@remotion/web-renderer" }, "Using Chromium experimental HTML-in-canvas (drawElementImage) for video frames. See https://
|
|
5155
|
+
Internals9.Log.warn({ logLevel, tag: "@remotion/web-renderer" }, "Using Chromium experimental HTML-in-canvas (drawElementImage) for video frames. See https://remotion.dev/docs/client-side-rendering/html-in-canvas");
|
|
4988
5156
|
} else if (outcome.shouldWarn) {
|
|
4989
5157
|
Internals9.Log.warn({ logLevel, tag: "@remotion/web-renderer" }, `Not using HTML-in-canvas: ${outcome.reason}`);
|
|
4990
5158
|
}
|
|
@@ -5038,6 +5206,7 @@ var internalRenderMediaOnWeb = async ({
|
|
|
5038
5206
|
if (signal?.aborted) {
|
|
5039
5207
|
return Promise.reject(new Error("renderMediaOnWeb() was cancelled"));
|
|
5040
5208
|
}
|
|
5209
|
+
const useHtmlInCanvas = await supportsNestedHtmlInCanvas();
|
|
5041
5210
|
const scaffold = __using(__stack2, createScaffold({
|
|
5042
5211
|
width: resolved.width,
|
|
5043
5212
|
height: resolved.height,
|
|
@@ -5055,7 +5224,7 @@ var internalRenderMediaOnWeb = async ({
|
|
|
5055
5224
|
initialFrame: 0,
|
|
5056
5225
|
defaultCodec: resolved.defaultCodec,
|
|
5057
5226
|
defaultOutName: resolved.defaultOutName,
|
|
5058
|
-
|
|
5227
|
+
useHtmlInCanvas,
|
|
5059
5228
|
pixelDensity: scale
|
|
5060
5229
|
}), 0);
|
|
5061
5230
|
const {
|
|
@@ -5066,27 +5235,6 @@ var internalRenderMediaOnWeb = async ({
|
|
|
5066
5235
|
errorHolder,
|
|
5067
5236
|
htmlInCanvasContext
|
|
5068
5237
|
} = scaffold;
|
|
5069
|
-
if (allowHtmlInCanvas && !htmlInCanvasContext) {
|
|
5070
|
-
if (!supportsNativeHtmlInCanvas()) {
|
|
5071
|
-
onHtmlInCanvasLayerOutcome({
|
|
5072
|
-
native: false,
|
|
5073
|
-
reason: "This browser does not expose CanvasRenderingContext2D.prototype.drawElementImage. In Chromium, enable chrome://flags/#canvas-draw-element and use a version that ships the API.",
|
|
5074
|
-
shouldWarn: false
|
|
5075
|
-
});
|
|
5076
|
-
} else {
|
|
5077
|
-
onHtmlInCanvasLayerOutcome({
|
|
5078
|
-
native: false,
|
|
5079
|
-
reason: "drawElementImage is available but canvas.requestPaint() is missing. Use a Chromium version that ships requestPaint.",
|
|
5080
|
-
shouldWarn: true
|
|
5081
|
-
});
|
|
5082
|
-
}
|
|
5083
|
-
} else if (!allowHtmlInCanvas) {
|
|
5084
|
-
onHtmlInCanvasLayerOutcome({
|
|
5085
|
-
native: false,
|
|
5086
|
-
reason: "allowHtmlInCanvas is false; using the built-in DOM composer.",
|
|
5087
|
-
shouldWarn: false
|
|
5088
|
-
});
|
|
5089
|
-
}
|
|
5090
5238
|
const internalState = __using(__stack2, makeInternalState(), 0);
|
|
5091
5239
|
const pageResponsivenessController = createPageResponsivenessController({
|
|
5092
5240
|
intervalInMilliseconds: pageResponsivenessIntervalInMilliseconds,
|
|
@@ -5105,6 +5253,17 @@ var internalRenderMediaOnWeb = async ({
|
|
|
5105
5253
|
fps: resolved.fps,
|
|
5106
5254
|
logLevel
|
|
5107
5255
|
}), 0);
|
|
5256
|
+
const waitForRenderReady = async () => {
|
|
5257
|
+
await waitForReady({
|
|
5258
|
+
timeoutInMilliseconds: delayRenderTimeoutInMilliseconds,
|
|
5259
|
+
scope: delayRenderScope,
|
|
5260
|
+
signal,
|
|
5261
|
+
apiName: "renderMediaOnWeb",
|
|
5262
|
+
internalState,
|
|
5263
|
+
keepalive
|
|
5264
|
+
});
|
|
5265
|
+
checkForError(errorHolder);
|
|
5266
|
+
};
|
|
5108
5267
|
const artifactsHandler = handleArtifacts();
|
|
5109
5268
|
const webFsTarget = outputTarget === "web-fs" ? await createWebFsTarget() : null;
|
|
5110
5269
|
const target = webFsTarget ? new StreamTarget(webFsTarget.stream) : new BufferTarget;
|
|
@@ -5123,15 +5282,7 @@ var internalRenderMediaOnWeb = async ({
|
|
|
5123
5282
|
if (signal?.aborted) {
|
|
5124
5283
|
throw new Error("renderMediaOnWeb() was cancelled");
|
|
5125
5284
|
}
|
|
5126
|
-
await
|
|
5127
|
-
timeoutInMilliseconds: delayRenderTimeoutInMilliseconds,
|
|
5128
|
-
scope: delayRenderScope,
|
|
5129
|
-
signal,
|
|
5130
|
-
apiName: "renderMediaOnWeb",
|
|
5131
|
-
internalState,
|
|
5132
|
-
keepalive
|
|
5133
|
-
});
|
|
5134
|
-
checkForError(errorHolder);
|
|
5285
|
+
await waitForRenderReady();
|
|
5135
5286
|
if (signal?.aborted) {
|
|
5136
5287
|
throw new Error("renderMediaOnWeb() was cancelled");
|
|
5137
5288
|
}
|
|
@@ -5189,15 +5340,7 @@ var internalRenderMediaOnWeb = async ({
|
|
|
5189
5340
|
throw new Error("renderMediaOnWeb() was cancelled");
|
|
5190
5341
|
}
|
|
5191
5342
|
timeUpdater.current?.update(frame);
|
|
5192
|
-
await
|
|
5193
|
-
timeoutInMilliseconds: delayRenderTimeoutInMilliseconds,
|
|
5194
|
-
scope: delayRenderScope,
|
|
5195
|
-
signal,
|
|
5196
|
-
apiName: "renderMediaOnWeb",
|
|
5197
|
-
keepalive,
|
|
5198
|
-
internalState
|
|
5199
|
-
});
|
|
5200
|
-
checkForError(errorHolder);
|
|
5343
|
+
await waitForRenderReady();
|
|
5201
5344
|
if (signal?.aborted) {
|
|
5202
5345
|
throw new Error("renderMediaOnWeb() was cancelled");
|
|
5203
5346
|
}
|
|
@@ -5215,7 +5358,8 @@ var internalRenderMediaOnWeb = async ({
|
|
|
5215
5358
|
cutout: new DOMRect(0, 0, resolved.width, resolved.height),
|
|
5216
5359
|
htmlInCanvasContext,
|
|
5217
5360
|
onHtmlInCanvasLayerOutcome: htmlInCanvasContext ? onHtmlInCanvasLayerOutcome : undefined,
|
|
5218
|
-
waitForPageResponsiveness
|
|
5361
|
+
waitForPageResponsiveness,
|
|
5362
|
+
waitForRenderReady
|
|
5219
5363
|
});
|
|
5220
5364
|
internalState.addCreateFrameTime(performance.now() - createFrameStart);
|
|
5221
5365
|
layerCanvas = layer.canvas;
|
|
@@ -5384,7 +5528,6 @@ var renderMediaOnWeb = (options) => {
|
|
|
5384
5528
|
muted: options.muted ?? false,
|
|
5385
5529
|
scale: options.scale ?? 1,
|
|
5386
5530
|
isProduction: options.isProduction ?? true,
|
|
5387
|
-
allowHtmlInCanvas: options.allowHtmlInCanvas ?? false,
|
|
5388
5531
|
sampleRate: options.sampleRate ?? 48000
|
|
5389
5532
|
}));
|
|
5390
5533
|
return onlyOneRenderAtATimeQueue.ref;
|
|
@@ -5443,15 +5586,14 @@ async function internalRenderStillOnWeb({
|
|
|
5443
5586
|
onArtifact,
|
|
5444
5587
|
licenseKey,
|
|
5445
5588
|
scale,
|
|
5446
|
-
isProduction
|
|
5447
|
-
allowHtmlInCanvas
|
|
5589
|
+
isProduction
|
|
5448
5590
|
}) {
|
|
5449
5591
|
let __stack = [];
|
|
5450
5592
|
try {
|
|
5451
5593
|
validateScale(scale);
|
|
5452
5594
|
const onHtmlInCanvasLayerOutcome = (outcome) => {
|
|
5453
5595
|
if (outcome.native) {
|
|
5454
|
-
Internals10.Log.warn({ logLevel, tag: "@remotion/web-renderer" }, "Using Chromium experimental HTML-in-canvas (drawElementImage) for this frame.
|
|
5596
|
+
Internals10.Log.warn({ logLevel, tag: "@remotion/web-renderer" }, "Using Chromium experimental HTML-in-canvas (drawElementImage) for this frame. See https://remotion.dev/docs/client-side-rendering/html-in-canvas");
|
|
5455
5597
|
} else if (outcome.shouldWarn) {
|
|
5456
5598
|
Internals10.Log.warn({ logLevel, tag: "@remotion/web-renderer" }, `Not using HTML-in-canvas: ${outcome.reason}`);
|
|
5457
5599
|
}
|
|
@@ -5470,6 +5612,7 @@ async function internalRenderStillOnWeb({
|
|
|
5470
5612
|
if (signal?.aborted) {
|
|
5471
5613
|
return Promise.reject(new Error("renderStillOnWeb() was cancelled"));
|
|
5472
5614
|
}
|
|
5615
|
+
const useHtmlInCanvas = await supportsNestedHtmlInCanvas();
|
|
5473
5616
|
const internalState = __using(__stack, makeInternalState(), 0);
|
|
5474
5617
|
const scaffold = __using(__stack, createScaffold({
|
|
5475
5618
|
width: resolved.width,
|
|
@@ -5488,7 +5631,7 @@ async function internalRenderStillOnWeb({
|
|
|
5488
5631
|
initialFrame: frame,
|
|
5489
5632
|
defaultCodec: resolved.defaultCodec,
|
|
5490
5633
|
defaultOutName: resolved.defaultOutName,
|
|
5491
|
-
|
|
5634
|
+
useHtmlInCanvas,
|
|
5492
5635
|
pixelDensity: scale
|
|
5493
5636
|
}), 0);
|
|
5494
5637
|
const {
|
|
@@ -5498,32 +5641,8 @@ async function internalRenderStillOnWeb({
|
|
|
5498
5641
|
errorHolder,
|
|
5499
5642
|
htmlInCanvasContext
|
|
5500
5643
|
} = scaffold;
|
|
5501
|
-
if (allowHtmlInCanvas && !htmlInCanvasContext) {
|
|
5502
|
-
if (!supportsNativeHtmlInCanvas()) {
|
|
5503
|
-
onHtmlInCanvasLayerOutcome({
|
|
5504
|
-
native: false,
|
|
5505
|
-
reason: "This browser does not expose CanvasRenderingContext2D.prototype.drawElementImage. In Chromium, enable chrome://flags/#canvas-draw-element and use a version that ships the API.",
|
|
5506
|
-
shouldWarn: false
|
|
5507
|
-
});
|
|
5508
|
-
} else {
|
|
5509
|
-
onHtmlInCanvasLayerOutcome({
|
|
5510
|
-
native: false,
|
|
5511
|
-
reason: "drawElementImage is available but canvas.requestPaint() is missing. Use a Chromium version that ships requestPaint.",
|
|
5512
|
-
shouldWarn: true
|
|
5513
|
-
});
|
|
5514
|
-
}
|
|
5515
|
-
} else if (!allowHtmlInCanvas) {
|
|
5516
|
-
onHtmlInCanvasLayerOutcome({
|
|
5517
|
-
native: false,
|
|
5518
|
-
reason: "allowHtmlInCanvas is false; using the built-in DOM composer.",
|
|
5519
|
-
shouldWarn: false
|
|
5520
|
-
});
|
|
5521
|
-
}
|
|
5522
5644
|
const artifactsHandler = handleArtifacts();
|
|
5523
|
-
|
|
5524
|
-
if (signal?.aborted) {
|
|
5525
|
-
throw new Error("renderStillOnWeb() was cancelled");
|
|
5526
|
-
}
|
|
5645
|
+
const waitForRenderReady = async () => {
|
|
5527
5646
|
await waitForReady({
|
|
5528
5647
|
timeoutInMilliseconds: delayRenderTimeoutInMilliseconds,
|
|
5529
5648
|
scope: delayRenderScope,
|
|
@@ -5533,6 +5652,12 @@ async function internalRenderStillOnWeb({
|
|
|
5533
5652
|
keepalive: null
|
|
5534
5653
|
});
|
|
5535
5654
|
checkForError(errorHolder);
|
|
5655
|
+
};
|
|
5656
|
+
try {
|
|
5657
|
+
if (signal?.aborted) {
|
|
5658
|
+
throw new Error("renderStillOnWeb() was cancelled");
|
|
5659
|
+
}
|
|
5660
|
+
await waitForRenderReady();
|
|
5536
5661
|
if (signal?.aborted) {
|
|
5537
5662
|
throw new Error("renderStillOnWeb() was cancelled");
|
|
5538
5663
|
}
|
|
@@ -5545,7 +5670,8 @@ async function internalRenderStillOnWeb({
|
|
|
5545
5670
|
cutout: new DOMRect(0, 0, resolved.width, resolved.height),
|
|
5546
5671
|
htmlInCanvasContext,
|
|
5547
5672
|
onHtmlInCanvasLayerOutcome: htmlInCanvasContext ? onHtmlInCanvasLayerOutcome : undefined,
|
|
5548
|
-
waitForPageResponsiveness: null
|
|
5673
|
+
waitForPageResponsiveness: null,
|
|
5674
|
+
waitForRenderReady
|
|
5549
5675
|
});
|
|
5550
5676
|
const { canvas } = capturedFrame;
|
|
5551
5677
|
const assets = collectAssets.current.collectAssets();
|
|
@@ -5596,8 +5722,7 @@ var renderStillOnWeb = (options) => {
|
|
|
5596
5722
|
onArtifact: options.onArtifact ?? null,
|
|
5597
5723
|
licenseKey: options.licenseKey ?? null,
|
|
5598
5724
|
scale: options.scale ?? 1,
|
|
5599
|
-
isProduction: options.isProduction ?? true
|
|
5600
|
-
allowHtmlInCanvas: options.allowHtmlInCanvas ?? false
|
|
5725
|
+
isProduction: options.isProduction ?? true
|
|
5601
5726
|
}));
|
|
5602
5727
|
return onlyOneRenderAtATimeQueue.ref;
|
|
5603
5728
|
};
|
package/dist/html-in-canvas.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
type Canvas2DWithDrawElement = CanvasRenderingContext2D & {
|
|
2
|
-
drawElementImage: (element: Element, dx: number, dy: number, dwidth: number, dheight: number) => DOMMatrix;
|
|
2
|
+
drawElementImage: (element: Element | ElementImage, dx: number, dy: number, dwidth: number, dheight: number) => DOMMatrix;
|
|
3
3
|
};
|
|
4
4
|
type HTMLCanvasWithLayoutSubtree = HTMLCanvasElement & {
|
|
5
|
+
captureElementImage?: (element: Element) => ElementImage;
|
|
5
6
|
layoutSubtree?: boolean;
|
|
6
7
|
requestPaint?: () => void;
|
|
7
8
|
};
|
|
9
|
+
export declare const setForceDisableHtmlInCanvasForTesting: (forceDisable: boolean) => void;
|
|
8
10
|
export declare const supportsNativeHtmlInCanvas: () => boolean;
|
|
11
|
+
export declare const supportsNestedHtmlInCanvas: () => Promise<boolean>;
|
|
12
|
+
export declare const containsLayoutSubtreeCanvas: (element: HTMLElement) => boolean;
|
|
9
13
|
export type HtmlInCanvasContext = {
|
|
10
14
|
layoutCanvas: HTMLCanvasWithLayoutSubtree;
|
|
11
15
|
ctx: Canvas2DWithDrawElement;
|
|
@@ -29,11 +33,13 @@ export declare const setupHtmlInCanvas: ({ wrapper, div, width, height, }: {
|
|
|
29
33
|
* The caller is responsible for ensuring the frame content is ready (via
|
|
30
34
|
* waitForReady) before calling this function.
|
|
31
35
|
*/
|
|
32
|
-
export declare const drawWithHtmlInCanvas: ({ htmlInCanvasContext, element, scaledWidth, scaledHeight, }: {
|
|
36
|
+
export declare const drawWithHtmlInCanvas: ({ htmlInCanvasContext, element, scaledWidth, scaledHeight, waitForRenderReady, useElementImage, }: {
|
|
33
37
|
htmlInCanvasContext: HtmlInCanvasContext;
|
|
34
38
|
element: HTMLElement;
|
|
35
39
|
scaledWidth: number;
|
|
36
40
|
scaledHeight: number;
|
|
41
|
+
waitForRenderReady: () => Promise<void>;
|
|
42
|
+
useElementImage: boolean;
|
|
37
43
|
}) => Promise<OffscreenCanvasRenderingContext2D>;
|
|
38
44
|
export declare const teardownHtmlInCanvas: ({ htmlInCanvasContext, wrapper, div, }: {
|
|
39
45
|
htmlInCanvasContext: HtmlInCanvasContext;
|
|
@@ -67,7 +67,6 @@ type OptionalRenderMediaOnWebOptions<Schema extends $ZodObject> = {
|
|
|
67
67
|
isProduction: boolean;
|
|
68
68
|
muted: boolean;
|
|
69
69
|
scale: number;
|
|
70
|
-
allowHtmlInCanvas: boolean;
|
|
71
70
|
sampleRate: number;
|
|
72
71
|
};
|
|
73
72
|
export type RenderMediaOnWebOptions<Schema extends $ZodObject, Props extends Record<string, unknown>> = MandatoryRenderMediaOnWebOptions<Schema, Props> & Partial<OptionalRenderMediaOnWebOptions<Schema>> & InputPropsIfHasProps<Schema, Props>;
|
|
@@ -20,7 +20,6 @@ type OptionalRenderStillOnWebOptions<Schema extends $ZodObject> = {
|
|
|
20
20
|
licenseKey: string | null;
|
|
21
21
|
scale: number;
|
|
22
22
|
isProduction: boolean;
|
|
23
|
-
allowHtmlInCanvas: boolean;
|
|
24
23
|
};
|
|
25
24
|
export type RenderStillOnWebOptions<Schema extends $ZodObject, Props extends Record<string, unknown>> = MandatoryRenderStillOnWebOptions<Schema, Props> & Partial<OptionalRenderStillOnWebOptions<Schema>> & InputPropsIfHasProps<Schema, Props>;
|
|
26
25
|
export declare const renderStillOnWeb: <Schema extends $ZodObject<Readonly<Readonly<{
|
|
@@ -6,7 +6,7 @@ export type HtmlInCanvasLayerOutcome = {
|
|
|
6
6
|
reason: string;
|
|
7
7
|
shouldWarn: boolean;
|
|
8
8
|
};
|
|
9
|
-
export declare const createLayer: ({ element, scale, logLevel, internalState, onlyBackgroundClipText, cutout, htmlInCanvasContext, onHtmlInCanvasLayerOutcome, waitForPageResponsiveness, }: {
|
|
9
|
+
export declare const createLayer: ({ element, scale, logLevel, internalState, onlyBackgroundClipText, cutout, htmlInCanvasContext, onHtmlInCanvasLayerOutcome, waitForPageResponsiveness, waitForRenderReady, }: {
|
|
10
10
|
element: HTMLElement | SVGElement;
|
|
11
11
|
scale: number;
|
|
12
12
|
logLevel: "error" | "info" | "trace" | "verbose" | "warn";
|
|
@@ -33,4 +33,5 @@ export declare const createLayer: ({ element, scale, logLevel, internalState, on
|
|
|
33
33
|
htmlInCanvasContext?: HtmlInCanvasContext | null | undefined;
|
|
34
34
|
onHtmlInCanvasLayerOutcome?: ((outcome: HtmlInCanvasLayerOutcome) => void) | undefined;
|
|
35
35
|
waitForPageResponsiveness: (() => Promise<void>) | null;
|
|
36
|
+
waitForRenderReady: () => Promise<void>;
|
|
36
37
|
}) => Promise<OffscreenCanvasRenderingContext2D>;
|
package/dist/walk-over-node.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { TransformStyleCache } from './drawing/calculate-transforms';
|
|
1
2
|
import type { ProcessNodeReturnValue } from './drawing/process-node';
|
|
2
|
-
export declare const walkOverNode: ({ node, context, logLevel, parentRect, internalState, rootElement, onlyBackgroundClipText, scale, waitForPageResponsiveness, }: {
|
|
3
|
+
export declare const walkOverNode: ({ node, context, logLevel, parentRect, internalState, rootElement, onlyBackgroundClipText, scale, waitForPageResponsiveness, transformStyleCache, }: {
|
|
3
4
|
node: Node;
|
|
4
5
|
context: OffscreenCanvasRenderingContext2D;
|
|
5
6
|
logLevel: "error" | "info" | "trace" | "verbose" | "warn";
|
|
@@ -26,4 +27,5 @@ export declare const walkOverNode: ({ node, context, logLevel, parentRect, inter
|
|
|
26
27
|
onlyBackgroundClipText: boolean;
|
|
27
28
|
scale: number;
|
|
28
29
|
waitForPageResponsiveness: (() => Promise<void>) | null;
|
|
30
|
+
transformStyleCache: TransformStyleCache;
|
|
29
31
|
}) => Promise<ProcessNodeReturnValue>;
|
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.492",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"scripts": {
|
|
@@ -22,19 +22,20 @@
|
|
|
22
22
|
"@mediabunny/mp3-encoder": "1.50.8",
|
|
23
23
|
"@mediabunny/aac-encoder": "1.50.8",
|
|
24
24
|
"@mediabunny/flac-encoder": "1.50.8",
|
|
25
|
-
"@remotion/licensing": "4.0.
|
|
26
|
-
"remotion": "4.0.
|
|
25
|
+
"@remotion/licensing": "4.0.492",
|
|
26
|
+
"remotion": "4.0.492",
|
|
27
27
|
"mediabunny": "1.50.8"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
+
"@remotion/effects": "4.0.492",
|
|
30
31
|
"@react-three/fiber": "9.2.0",
|
|
31
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
32
|
-
"@remotion/paths": "4.0.
|
|
33
|
-
"@remotion/player": "4.0.
|
|
34
|
-
"@remotion/media": "4.0.
|
|
35
|
-
"@remotion/shapes": "4.0.
|
|
36
|
-
"@remotion/three": "4.0.
|
|
37
|
-
"@remotion/transitions": "4.0.
|
|
32
|
+
"@remotion/eslint-config-internal": "4.0.492",
|
|
33
|
+
"@remotion/paths": "4.0.492",
|
|
34
|
+
"@remotion/player": "4.0.492",
|
|
35
|
+
"@remotion/media": "4.0.492",
|
|
36
|
+
"@remotion/shapes": "4.0.492",
|
|
37
|
+
"@remotion/three": "4.0.492",
|
|
38
|
+
"@remotion/transitions": "4.0.492",
|
|
38
39
|
"@types/three": "0.170.0",
|
|
39
40
|
"@typescript/native-preview": "7.0.0-dev.20260217.1",
|
|
40
41
|
"@vitejs/plugin-react": "4.3.4",
|
|
@@ -68,6 +69,6 @@
|
|
|
68
69
|
"renderer",
|
|
69
70
|
"web"
|
|
70
71
|
],
|
|
71
|
-
"description": "Render videos in the browser
|
|
72
|
+
"description": "Render videos in the browser",
|
|
72
73
|
"homepage": "https://www.remotion.dev/docs/web-renderer/"
|
|
73
74
|
}
|