UNPKG

remotion

Version:

Make videos programmatically

226 lines (225 loc) • 12.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Sequence = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); /* eslint-disable @typescript-eslint/no-use-before-define */ const react_1 = require("react"); const AbsoluteFill_js_1 = require("./AbsoluteFill.js"); const freeze_js_1 = require("./freeze.js"); const nonce_js_1 = require("./nonce.js"); const SequenceContext_js_1 = require("./SequenceContext.js"); const SequenceManager_js_1 = require("./SequenceManager.js"); const timeline_position_state_js_1 = require("./timeline-position-state.js"); const TimelineContext_js_1 = require("./TimelineContext.js"); const use_current_frame_1 = require("./use-current-frame"); const use_remotion_environment_js_1 = require("./use-remotion-environment.js"); const use_video_config_js_1 = require("./use-video-config.js"); const v5_flag_js_1 = require("./v5-flag.js"); const RegularSequenceRefForwardingFunction = ({ from = 0, durationInFrames = Infinity, children, name, height, width, showInTimeline = true, controls, _remotionInternalLoopDisplay: loopDisplay, _remotionInternalStack: stack, _remotionInternalPremountDisplay: premountDisplay, _remotionInternalPostmountDisplay: postmountDisplay, ...other }, ref) => { var _a, _b; const { layout = 'absolute-fill' } = other; const [id] = (0, react_1.useState)(() => String(Math.random())); const parentSequence = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext); const { rootId } = (0, react_1.useContext)(TimelineContext_js_1.TimelineContext); const cumulatedFrom = parentSequence ? parentSequence.cumulatedFrom + parentSequence.relativeFrom : 0; const nonce = (0, nonce_js_1.useNonce)(); if (layout !== 'absolute-fill' && layout !== 'none') { throw new TypeError(`The layout prop of <Sequence /> expects either "absolute-fill" or "none", but you passed: ${layout}`); } // @ts-expect-error if (layout === 'none' && typeof other.style !== 'undefined') { throw new TypeError('If layout="none", you may not pass a style.'); } if (typeof durationInFrames !== 'number') { throw new TypeError(`You passed to durationInFrames an argument of type ${typeof durationInFrames}, but it must be a number.`); } if (durationInFrames <= 0) { throw new TypeError(`durationInFrames must be positive, but got ${durationInFrames}`); } if (typeof from !== 'number') { throw new TypeError(`You passed to the "from" props of your <Sequence> an argument of type ${typeof from}, but it must be a number.`); } if (!Number.isFinite(from)) { throw new TypeError(`The "from" prop of a sequence must be finite, but got ${from}.`); } const absoluteFrame = (0, timeline_position_state_js_1.useTimelinePosition)(); const videoConfig = (0, use_video_config_js_1.useVideoConfig)(); const parentSequenceDuration = parentSequence ? Math.min(parentSequence.durationInFrames - from, durationInFrames) : durationInFrames; const actualDurationInFrames = Math.max(0, Math.min(videoConfig.durationInFrames - from, parentSequenceDuration)); const { registerSequence, unregisterSequence } = (0, react_1.useContext)(SequenceManager_js_1.SequenceManager); const { hidden } = (0, react_1.useContext)(SequenceManager_js_1.SequenceVisibilityToggleContext); const premounting = (0, react_1.useMemo)(() => { // || is intentional, ?? would not trigger on `false` return ((parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.premounting) || Boolean(other._remotionInternalIsPremounting)); }, [other._remotionInternalIsPremounting, parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.premounting]); const postmounting = (0, react_1.useMemo)(() => { // || is intentional, ?? would not trigger on `false` return ((parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.postmounting) || Boolean(other._remotionInternalIsPostmounting)); }, [other._remotionInternalIsPostmounting, parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.postmounting]); const contextValue = (0, react_1.useMemo)(() => { var _a, _b, _c; return { cumulatedFrom, relativeFrom: from, durationInFrames: actualDurationInFrames, parentFrom: (_a = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.relativeFrom) !== null && _a !== void 0 ? _a : 0, id, height: (_b = height !== null && height !== void 0 ? height : parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.height) !== null && _b !== void 0 ? _b : null, width: (_c = width !== null && width !== void 0 ? width : parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.width) !== null && _c !== void 0 ? _c : null, premounting, postmounting, premountDisplay: premountDisplay !== null && premountDisplay !== void 0 ? premountDisplay : null, postmountDisplay: postmountDisplay !== null && postmountDisplay !== void 0 ? postmountDisplay : null, }; }, [ cumulatedFrom, from, actualDurationInFrames, parentSequence, id, height, width, premounting, postmounting, premountDisplay, postmountDisplay, ]); const timelineClipName = (0, react_1.useMemo)(() => { return name !== null && name !== void 0 ? name : ''; }, [name]); const env = (0, use_remotion_environment_js_1.useRemotionEnvironment)(); const inheritedStack = (_a = other === null || other === void 0 ? void 0 : other.stack) !== null && _a !== void 0 ? _a : null; (0, react_1.useEffect)(() => { var _a; if (!env.isStudio) { return; } registerSequence({ from, duration: actualDurationInFrames, id, displayName: timelineClipName, parent: (_a = parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.id) !== null && _a !== void 0 ? _a : null, type: 'sequence', rootId, showInTimeline, nonce, loopDisplay, stack: stack !== null && stack !== void 0 ? stack : inheritedStack, premountDisplay: premountDisplay !== null && premountDisplay !== void 0 ? premountDisplay : null, postmountDisplay: postmountDisplay !== null && postmountDisplay !== void 0 ? postmountDisplay : null, controls: controls !== null && controls !== void 0 ? controls : null, }); return () => { unregisterSequence(id); }; }, [ durationInFrames, id, name, registerSequence, timelineClipName, unregisterSequence, parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.id, actualDurationInFrames, rootId, from, showInTimeline, nonce, loopDisplay, stack, premountDisplay, postmountDisplay, env.isStudio, inheritedStack, controls, ]); // Ceil to support floats // https://github.com/remotion-dev/remotion/issues/2958 const endThreshold = Math.ceil(cumulatedFrom + from + durationInFrames - 1); const content = absoluteFrame < cumulatedFrom + from ? null : absoluteFrame > endThreshold ? null : children; const styleIfThere = other.layout === 'none' ? undefined : other.style; const defaultStyle = (0, react_1.useMemo)(() => { return { flexDirection: undefined, ...(width ? { width } : {}), ...(height ? { height } : {}), ...(styleIfThere !== null && styleIfThere !== void 0 ? styleIfThere : {}), }; }, [height, styleIfThere, width]); if (ref !== null && layout === 'none') { throw new TypeError('It is not supported to pass both a `ref` and `layout="none"` to <Sequence />.'); } const isSequenceHidden = (_b = hidden[id]) !== null && _b !== void 0 ? _b : false; if (isSequenceHidden) { return null; } return ((0, jsx_runtime_1.jsx)(SequenceContext_js_1.SequenceContext.Provider, { value: contextValue, children: content === null ? null : other.layout === 'none' ? (content) : ((0, jsx_runtime_1.jsx)(AbsoluteFill_js_1.AbsoluteFill, { ref: ref, style: defaultStyle, className: other.className, children: content })) })); }; const RegularSequence = (0, react_1.forwardRef)(RegularSequenceRefForwardingFunction); const PremountedPostmountedSequenceRefForwardingFunction = (props, ref) => { const frame = (0, use_current_frame_1.useCurrentFrame)(); if (props.layout === 'none') { throw new Error('`<Sequence>` with `premountFor` and `postmountFor` props does not support layout="none"'); } const { style: passedStyle, from = 0, durationInFrames = Infinity, premountFor = 0, postmountFor = 0, styleWhilePremounted, styleWhilePostmounted, ...otherProps } = props; const endThreshold = Math.ceil(from + durationInFrames - 1); const premountingActive = frame < from && frame >= from - premountFor; const postmountingActive = frame > endThreshold && frame <= endThreshold + postmountFor; // Determine which freeze frame to use const freezeFrame = premountingActive ? from : postmountingActive ? from + durationInFrames - 1 : 0; const isFreezingActive = premountingActive || postmountingActive; const style = (0, react_1.useMemo)(() => { var _a; return { ...passedStyle, opacity: premountingActive || postmountingActive ? 0 : 1, pointerEvents: premountingActive || postmountingActive ? 'none' : ((_a = passedStyle === null || passedStyle === void 0 ? void 0 : passedStyle.pointerEvents) !== null && _a !== void 0 ? _a : undefined), ...(premountingActive ? styleWhilePremounted : {}), ...(postmountingActive ? styleWhilePostmounted : {}), }; }, [ passedStyle, premountingActive, postmountingActive, styleWhilePremounted, styleWhilePostmounted, ]); return ((0, jsx_runtime_1.jsx)(freeze_js_1.Freeze, { frame: freezeFrame, active: isFreezingActive, children: (0, jsx_runtime_1.jsx)(exports.Sequence, { ref: ref, from: from, durationInFrames: durationInFrames, style: style, _remotionInternalPremountDisplay: premountFor, _remotionInternalPostmountDisplay: postmountFor, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, ...otherProps }) })); }; const PremountedPostmountedSequence = (0, react_1.forwardRef)(PremountedPostmountedSequenceRefForwardingFunction); const SequenceRefForwardingFunction = (props, ref) => { var _a; const env = (0, use_remotion_environment_js_1.useRemotionEnvironment)(); const { fps } = (0, use_video_config_js_1.useVideoConfig)(); if (props.layout !== 'none' && !env.isRendering) { const effectivePremountFor = v5_flag_js_1.ENABLE_V5_BREAKING_CHANGES ? ((_a = props.premountFor) !== null && _a !== void 0 ? _a : fps) : props.premountFor; if (effectivePremountFor || props.postmountFor) { return ((0, jsx_runtime_1.jsx)(PremountedPostmountedSequence, { ref: ref, ...props, premountFor: effectivePremountFor })); } } return (0, jsx_runtime_1.jsx)(RegularSequence, { ...props, ref: ref }); }; /* * @description A component that time-shifts its children and wraps them in an absolutely positioned <div>. * @see [Documentation](https://www.remotion.dev/docs/sequence) */ exports.Sequence = (0, react_1.forwardRef)(SequenceRefForwardingFunction);