@remotion/studio
Version:
APIs for interacting with the Remotion Studio
246 lines (245 loc) • 10.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TimelineInOutPointToggle = exports.defaultInOutValue = exports.inOutHandles = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const player_1 = require("@remotion/player");
const react_1 = require("react");
const remotion_1 = require("remotion");
const no_react_1 = require("remotion/no-react");
const colors_1 = require("../helpers/colors");
const use_keybinding_1 = require("../helpers/use-keybinding");
const timelineInOutPointer_1 = require("../icons/timelineInOutPointer");
const in_out_1 = require("../state/in-out");
const ControlButton_1 = require("./ControlButton");
const getTooltipText = (pointType, key) => [
`Mark ${pointType}`,
(0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? null : `(${key})`,
'- right click to clear',
]
.filter(no_react_1.NoReactInternals.truthy)
.join(' ');
const style = {
width: 16,
height: 16,
};
exports.inOutHandles = (0, react_1.createRef)();
exports.defaultInOutValue = { inFrame: null, outFrame: null };
const TimelineInOutPointToggle = () => {
const { inFrame, outFrame } = (0, in_out_1.useTimelineInOutFramePosition)();
const { setInAndOutFrames } = (0, in_out_1.useTimelineSetInOutFramePosition)();
const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
const keybindings = (0, use_keybinding_1.useKeybinding)();
const { getCurrentFrame, isFirstFrame, isLastFrame } = player_1.PlayerInternals.usePlayer();
const onInOutClear = (0, react_1.useCallback)((composition) => {
setInAndOutFrames((prev) => {
return {
...prev,
[composition]: {
inFrame: null,
outFrame: null,
},
};
});
}, [setInAndOutFrames]);
const onInMark = (0, react_1.useCallback)((e) => {
if (!videoConfig) {
return null;
}
if (e === null || e === void 0 ? void 0 : e.shiftKey) {
setInAndOutFrames((prev) => {
var _a;
return {
...prev,
[videoConfig.id]: {
...((_a = prev[videoConfig.id]) !== null && _a !== void 0 ? _a : exports.defaultInOutValue),
inFrame: null,
},
};
});
return null;
}
setInAndOutFrames((prev) => {
var _a, _b;
var _c, _d, _e;
const prevOut = (_a = prev[videoConfig.id]) === null || _a === void 0 ? void 0 : _a.outFrame;
const biggestPossible = prevOut === undefined || prevOut === null ? Infinity : prevOut - 1;
const selected = Math.min(getCurrentFrame(), biggestPossible);
if (selected === 0) {
return {
...prev,
[videoConfig.id]: {
...((_c = prev[videoConfig.id]) !== null && _c !== void 0 ? _c : exports.defaultInOutValue),
inFrame: null,
},
};
}
const prevIn = (_b = prev[videoConfig.id]) === null || _b === void 0 ? void 0 : _b.inFrame;
if (prevIn !== null && prevIn !== undefined) {
// Disable if already at this position
if (prevIn === selected) {
return {
...prev,
[videoConfig.id]: {
...((_d = prev[videoConfig.id]) !== null && _d !== void 0 ? _d : exports.defaultInOutValue),
inFrame: null,
},
};
}
}
return {
...prev,
[videoConfig.id]: {
...((_e = prev[videoConfig.id]) !== null && _e !== void 0 ? _e : exports.defaultInOutValue),
inFrame: selected,
},
};
});
}, [getCurrentFrame, setInAndOutFrames, videoConfig]);
const clearInMark = (0, react_1.useCallback)((e) => {
if (!videoConfig) {
return null;
}
e.preventDefault();
setInAndOutFrames((f) => {
var _a;
return {
...f,
[videoConfig.id]: {
...((_a = f[videoConfig.id]) !== null && _a !== void 0 ? _a : exports.defaultInOutValue),
inFrame: null,
},
};
});
}, [setInAndOutFrames, videoConfig]);
const clearOutMark = (0, react_1.useCallback)((e) => {
if (!videoConfig) {
return null;
}
e === null || e === void 0 ? void 0 : e.preventDefault();
setInAndOutFrames((f) => {
var _a;
return {
...f,
[videoConfig.id]: {
...((_a = f[videoConfig.id]) !== null && _a !== void 0 ? _a : exports.defaultInOutValue),
outFrame: null,
},
};
});
}, [setInAndOutFrames, videoConfig]);
const onOutMark = (0, react_1.useCallback)((e) => {
if (!videoConfig) {
return null;
}
if (e === null || e === void 0 ? void 0 : e.shiftKey) {
setInAndOutFrames((f) => {
var _a;
return {
...f,
[videoConfig.id]: {
...((_a = f[videoConfig.id]) !== null && _a !== void 0 ? _a : exports.defaultInOutValue),
outFrame: null,
},
};
});
return;
}
setInAndOutFrames((prev) => {
var _a, _b;
var _c, _d, _e;
const prevInFrame = (_a = prev[videoConfig.id]) === null || _a === void 0 ? void 0 : _a.inFrame;
const smallestPossible = prevInFrame === null || prevInFrame === undefined
? -Infinity
: prevInFrame + 1;
const selected = Math.max(getCurrentFrame(), smallestPossible);
if (selected === videoConfig.durationInFrames - 1) {
return {
...prev,
[videoConfig.id]: {
...((_c = prev[videoConfig.id]) !== null && _c !== void 0 ? _c : exports.defaultInOutValue),
outFrame: null,
},
};
}
const prevOut = (_b = prev[videoConfig.id]) === null || _b === void 0 ? void 0 : _b.outFrame;
if (prevOut !== null && prevOut !== undefined) {
if (prevOut === selected) {
return {
...prev,
[videoConfig.id]: {
...((_d = prev[videoConfig.id]) !== null && _d !== void 0 ? _d : exports.defaultInOutValue),
outFrame: null,
},
};
}
}
return {
...prev,
[videoConfig.id]: {
...((_e = prev[videoConfig.id]) !== null && _e !== void 0 ? _e : exports.defaultInOutValue),
outFrame: selected,
},
};
});
}, [getCurrentFrame, setInAndOutFrames, videoConfig]);
const confId = videoConfig === null || videoConfig === void 0 ? void 0 : videoConfig.id;
(0, react_1.useEffect)(() => {
if (!confId) {
return;
}
const iKey = keybindings.registerKeybinding({
event: 'keypress',
key: 'i',
callback: (e) => {
onInMark(e);
},
commandCtrlKey: false,
preventDefault: true,
triggerIfInputFieldFocused: false,
keepRegisteredWhenNotHighestContext: false,
});
const oKey = keybindings.registerKeybinding({
event: 'keypress',
key: 'o',
callback: (e) => {
onOutMark(e);
},
commandCtrlKey: false,
preventDefault: true,
triggerIfInputFieldFocused: false,
keepRegisteredWhenNotHighestContext: false,
});
const xKey = keybindings.registerKeybinding({
event: 'keypress',
key: 'x',
callback: () => {
onInOutClear(confId);
},
commandCtrlKey: false,
preventDefault: true,
triggerIfInputFieldFocused: false,
keepRegisteredWhenNotHighestContext: false,
});
return () => {
oKey.unregister();
iKey.unregister();
xKey.unregister();
};
}, [confId, keybindings, onInMark, onInOutClear, onOutMark]);
(0, react_1.useImperativeHandle)(exports.inOutHandles, () => {
return {
clearMarks: () => {
if (!confId) {
return;
}
onInOutClear(confId);
},
inMarkClick: onInMark,
outMarkClick: onOutMark,
};
}, [confId, onInMark, onInOutClear, onOutMark]);
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: getTooltipText('In', 'I'), "aria-label": getTooltipText('In', 'I'), onClick: onInMark, onContextMenu: clearInMark, disabled: !videoConfig || isFirstFrame, children: jsx_runtime_1.jsx(timelineInOutPointer_1.TimelineInPointer, { color: inFrame === null ? 'white' : colors_1.BLUE, style: style }) }), jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: getTooltipText('Out', 'O'), "aria-label": getTooltipText('Out', 'O'), onClick: onOutMark, onContextMenu: clearOutMark, disabled: !videoConfig || isLastFrame, children: jsx_runtime_1.jsx(timelineInOutPointer_1.TimelineOutPointer, { color: outFrame === null ? 'white' : colors_1.BLUE, style: style }) })
] }));
};
exports.TimelineInOutPointToggle = TimelineInOutPointToggle;