remotion
Version:
Make videos programmatically
160 lines (159 loc) • 6.63 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Solid = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const enable_sequence_stack_traces_js_1 = require("../enable-sequence-stack-traces.js");
const sequence_field_schema_js_1 = require("../sequence-field-schema.js");
const Sequence_js_1 = require("../Sequence.js");
const use_delay_render_js_1 = require("../use-delay-render.js");
const wrap_in_schema_js_1 = require("../wrap-in-schema.js");
const run_effect_chain_js_1 = require("./run-effect-chain.js");
const use_effect_chain_state_js_1 = require("./use-effect-chain-state.js");
const use_memoized_effects_js_1 = require("./use-memoized-effects.js");
const resolveSolidPixelDensity = (pixelDensity) => {
if (pixelDensity === undefined) {
return 1;
}
if (typeof pixelDensity !== 'number' ||
!Number.isFinite(pixelDensity) ||
pixelDensity <= 0) {
throw new Error(`<Solid>: \`pixelDensity\` must be a positive finite number. Received: ${String(pixelDensity)}.`);
}
return pixelDensity;
};
const solidSchema = {
durationInFrames: sequence_field_schema_js_1.durationInFramesField,
from: sequence_field_schema_js_1.fromField,
color: {
type: 'color',
default: 'transparent',
description: 'Color',
},
width: {
type: 'number',
min: 1,
step: 1,
default: 1920,
description: 'Width',
hiddenFromList: false,
},
height: {
type: 'number',
min: 1,
step: 1,
default: 1080,
description: 'Height',
hiddenFromList: false,
},
...sequence_field_schema_js_1.sequenceVisualStyleSchema,
hidden: sequence_field_schema_js_1.hiddenField,
};
const SolidInner = ({ color, width, height, effects = [], className, style, pixelDensity, overrideId, reference, }) => {
const { delayRender, continueRender, cancelRender } = (0, use_delay_render_js_1.useDelayRender)();
const resolvedPixelDensity = resolveSolidPixelDensity(pixelDensity);
const canvasWidth = Math.ceil(width * resolvedPixelDensity);
const canvasHeight = Math.ceil(height * resolvedPixelDensity);
const [outputCanvas, setOutputCanvas] = (0, react_1.useState)(null);
const memoizedEffects = (0, use_memoized_effects_js_1.useMemoizedEffects)({
effects,
overrideId: overrideId !== null && overrideId !== void 0 ? overrideId : null,
});
const sourceCanvas = (0, react_1.useMemo)(() => {
if (typeof document === 'undefined') {
return null;
}
const canvas = document.createElement('canvas');
canvas.width = 1;
canvas.height = 1;
return canvas;
}, []);
const chainState = (0, use_effect_chain_state_js_1.useEffectChainState)();
const canvasRef = (0, react_1.useCallback)((canvas) => {
setOutputCanvas(canvas);
if (typeof reference === 'function') {
reference(canvas);
}
else if (reference) {
reference.current = canvas;
}
}, [reference]);
// Fill source and run effect chain on every frame / color change.
(0, react_1.useEffect)(() => {
if (!outputCanvas || !sourceCanvas) {
return;
}
const handle = delayRender('Solid effect chain');
if (!chainState) {
continueRender(handle);
return () => {
continueRender(handle);
};
}
const ctx = sourceCanvas.getContext('2d', { colorSpace: 'srgb' });
if (!ctx) {
cancelRender(new Error('Failed to acquire 2D context for <Solid> source'));
return;
}
ctx.clearRect(0, 0, 1, 1);
if (color !== undefined) {
ctx.fillStyle = color;
ctx.fillRect(0, 0, 1, 1);
}
(0, run_effect_chain_js_1.runEffectChain)({
state: chainState.get(canvasWidth, canvasHeight),
source: sourceCanvas,
effects: memoizedEffects,
output: outputCanvas,
width: canvasWidth,
height: canvasHeight,
})
.then((completed) => {
if (completed) {
continueRender(handle);
}
})
.catch((err) => {
cancelRender(err);
});
return () => {
continueRender(handle);
};
}, [
color,
outputCanvas,
sourceCanvas,
chainState,
canvasWidth,
canvasHeight,
delayRender,
continueRender,
cancelRender,
memoizedEffects,
]);
const canvasStyle = (0, react_1.useMemo)(() => {
return {
width,
height,
...(style !== null && style !== void 0 ? style : {}),
};
}, [height, style, width]);
return (jsx_runtime_1.jsx("canvas", { ref: canvasRef, width: canvasWidth, height: canvasHeight, className: className, style: canvasStyle }));
};
const SolidOuter = (0, react_1.forwardRef)(({ effects = [], _experimentalControls: controls, color, height, width, className, durationInFrames, style, name, from, hidden, showInTimeline, pixelDensity, ...props }, ref) => {
var _a;
props;
const memoizedEffectDefinitions = (0, use_memoized_effects_js_1.useMemoizedEffectDefinitions)(effects);
const actualRef = (0, react_1.useRef)(null);
(0, react_1.useImperativeHandle)(ref, () => {
return actualRef.current;
}, []);
return (jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from, hidden: hidden, showInTimeline: showInTimeline, _experimentalControls: controls, _remotionInternalEffects: memoizedEffectDefinitions, durationInFrames: durationInFrames, name: name !== null && name !== void 0 ? name : '<Solid>', _remotionInternalRefForOutline: actualRef, _remotionInternalDocumentationLink: name === undefined ? 'https://www.remotion.dev/docs/solid' : undefined, ...props, children: jsx_runtime_1.jsx(SolidInner, { reference: actualRef, overrideId: (_a = controls === null || controls === void 0 ? void 0 : controls.overrideId) !== null && _a !== void 0 ? _a : null, color: color, height: height, width: width, className: className, style: style, effects: effects, pixelDensity: pixelDensity }) }));
});
exports.Solid = (0, wrap_in_schema_js_1.wrapInSchema)({
Component: SolidOuter,
schema: solidSchema,
supportsEffects: true,
});
exports.Solid.displayName = 'Solid';
(0, enable_sequence_stack_traces_js_1.addSequenceStackTraces)(exports.Solid);