105 lines
5.0 KiB
JavaScript
105 lines
5.0 KiB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
|
|
import { createRef } from 'react';
|
|
import { flushSync } from 'react-dom';
|
|
import ReactDOM from 'react-dom/client';
|
|
import { Internals } from 'remotion';
|
|
import { UpdateTime } from './update-time';
|
|
import { withResolvers } from './with-resolvers';
|
|
export async function createScaffold({ width, height, delayRenderTimeoutInMilliseconds, logLevel, resolvedProps, id, mediaCacheSizeInBytes, durationInFrames, fps, initialFrame, schema, Component, audioEnabled, videoEnabled, defaultCodec, defaultOutName, }) {
|
|
if (!ReactDOM.createRoot) {
|
|
throw new Error('@remotion/web-renderer requires React 18 or higher');
|
|
}
|
|
const div = document.createElement('div');
|
|
// Match same behavior as in portal-node.ts
|
|
div.style.position = 'fixed';
|
|
div.style.display = 'flex';
|
|
div.style.flexDirection = 'column';
|
|
div.style.backgroundColor = 'transparent';
|
|
div.style.width = `${width}px`;
|
|
div.style.height = `${height}px`;
|
|
div.style.zIndex = '-9999';
|
|
div.style.top = '0';
|
|
div.style.left = '0';
|
|
div.style.right = '0';
|
|
div.style.bottom = '0';
|
|
div.style.visibility = 'hidden';
|
|
div.style.pointerEvents = 'none';
|
|
const scaffoldClassName = `remotion-scaffold-${Math.random().toString(36).substring(2, 15)}`;
|
|
div.className = scaffoldClassName;
|
|
const cleanupCSS = Internals.CSSUtils.injectCSS(Internals.CSSUtils.makeDefaultPreviewCSS(`.${scaffoldClassName}`, 'white'));
|
|
document.body.appendChild(div);
|
|
const { promise, resolve, reject } = withResolvers();
|
|
// TODO: This might not work in React 18
|
|
const root = ReactDOM.createRoot(div, {
|
|
onUncaughtError: (err) => {
|
|
reject(err);
|
|
},
|
|
});
|
|
const delayRenderScope = {
|
|
remotion_renderReady: true,
|
|
remotion_delayRenderTimeouts: {},
|
|
remotion_puppeteerTimeout: delayRenderTimeoutInMilliseconds,
|
|
remotion_attempt: 0,
|
|
remotion_delayRenderHandles: [],
|
|
};
|
|
const timeUpdater = createRef();
|
|
const collectAssets = createRef();
|
|
flushSync(() => {
|
|
root.render(_jsx(Internals.MaxMediaCacheSizeContext.Provider, { value: mediaCacheSizeInBytes, children: _jsx(Internals.RemotionEnvironmentContext.Provider, { value: {
|
|
isStudio: false,
|
|
isRendering: true,
|
|
isPlayer: false,
|
|
isReadOnlyStudio: false,
|
|
isClientSideRendering: true,
|
|
}, children: _jsx(Internals.DelayRenderContextType.Provider, { value: delayRenderScope, children: _jsx(Internals.CompositionManager.Provider, { value: {
|
|
compositions: [
|
|
{
|
|
id,
|
|
// @ts-expect-error
|
|
component: Component,
|
|
nonce: 0,
|
|
defaultProps: {},
|
|
folderName: null,
|
|
parentFolderName: null,
|
|
schema: schema !== null && schema !== void 0 ? schema : null,
|
|
calculateMetadata: null,
|
|
durationInFrames,
|
|
fps,
|
|
height,
|
|
width,
|
|
},
|
|
],
|
|
canvasContent: {
|
|
type: 'composition',
|
|
compositionId: id,
|
|
},
|
|
currentCompositionMetadata: {
|
|
props: resolvedProps,
|
|
durationInFrames,
|
|
fps,
|
|
height,
|
|
width,
|
|
defaultCodec: defaultCodec !== null && defaultCodec !== void 0 ? defaultCodec : null,
|
|
defaultOutName: defaultOutName !== null && defaultOutName !== void 0 ? defaultOutName : null,
|
|
defaultVideoImageFormat: null,
|
|
defaultPixelFormat: null,
|
|
defaultProResProfile: null,
|
|
},
|
|
folders: [],
|
|
}, children: _jsx(Internals.RenderAssetManagerProvider, { collectAssets: collectAssets, children: _jsx(UpdateTime, { audioEnabled: audioEnabled, videoEnabled: videoEnabled, logLevel: logLevel, compId: id, initialFrame: initialFrame, timeUpdater: timeUpdater, children: _jsx(Internals.CanUseRemotionHooks.Provider, { value: true, children: _jsx(Component, { ...resolvedProps }) }) }) }) }) }) }) }));
|
|
});
|
|
resolve();
|
|
await promise;
|
|
return {
|
|
delayRenderScope,
|
|
div,
|
|
cleanupScaffold: () => {
|
|
root.unmount();
|
|
div.remove();
|
|
cleanupCSS();
|
|
},
|
|
timeUpdater,
|
|
collectAssets,
|
|
};
|
|
}
|