170 lines
7.0 KiB
JavaScript
170 lines
7.0 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.PlaybackrateControl = exports.playerButtonStyle = exports.Checkmark = void 0;
|
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
const react_1 = require("react");
|
|
const remotion_1 = require("remotion");
|
|
const use_component_visible_js_1 = __importDefault(require("./utils/use-component-visible.js"));
|
|
// To align
|
|
const BOTTOM = 35;
|
|
// Arbitrary to clamp the height of the popup
|
|
const THRESHOLD = 70;
|
|
const rateDiv = {
|
|
height: 30,
|
|
paddingRight: 15,
|
|
paddingLeft: 12,
|
|
display: 'flex',
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
};
|
|
const checkmarkContainer = {
|
|
width: 22,
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
};
|
|
const checkmarkStyle = {
|
|
width: 14,
|
|
height: 14,
|
|
color: 'black',
|
|
};
|
|
const Checkmark = () => ((0, jsx_runtime_1.jsx)("svg", { viewBox: "0 0 512 512", style: checkmarkStyle, children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M435.848 83.466L172.804 346.51l-96.652-96.652c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971l133.421 133.421c4.686 4.686 12.284 4.686 16.971 0l299.813-299.813c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.97 0z" }) }));
|
|
exports.Checkmark = Checkmark;
|
|
const formatPlaybackRate = (rate) => {
|
|
const str = rate.toString();
|
|
// If the string doesn't contain a decimal point, add ".0"
|
|
return str.includes('.') ? str : str + '.0';
|
|
};
|
|
const PlaybackrateOption = ({ rate, onSelect, selectedRate, keyboardSelectedRate }) => {
|
|
const onClick = (0, react_1.useCallback)((e) => {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
onSelect(rate);
|
|
}, [onSelect, rate]);
|
|
const [hovered, setHovered] = (0, react_1.useState)(false);
|
|
const onMouseEnter = (0, react_1.useCallback)(() => {
|
|
setHovered(true);
|
|
}, []);
|
|
const onMouseLeave = (0, react_1.useCallback)(() => {
|
|
setHovered(false);
|
|
}, []);
|
|
const isFocused = keyboardSelectedRate === rate;
|
|
const actualStyle = (0, react_1.useMemo)(() => {
|
|
return {
|
|
...rateDiv,
|
|
backgroundColor: hovered || isFocused ? '#eee' : 'transparent',
|
|
};
|
|
}, [hovered, isFocused]);
|
|
return ((0, jsx_runtime_1.jsxs)("div", { onPointerEnter: onMouseEnter, onPointerLeave: onMouseLeave, tabIndex: 0, style: actualStyle, onClick: onClick, children: [(0, jsx_runtime_1.jsx)("div", { style: checkmarkContainer, children: rate === selectedRate ? (0, jsx_runtime_1.jsx)(exports.Checkmark, {}) : null }), formatPlaybackRate(rate), "x"] }, rate));
|
|
};
|
|
const PlaybackPopup = ({ setIsComponentVisible, playbackRates, canvasSize }) => {
|
|
const { setPlaybackRate, playbackRate } = (0, react_1.useContext)(remotion_1.Internals.TimelineContext);
|
|
const [keyboardSelectedRate, setKeyboardSelectedRate] = (0, react_1.useState)(playbackRate);
|
|
(0, react_1.useEffect)(() => {
|
|
const listener = (e) => {
|
|
e.preventDefault();
|
|
if (e.key === 'ArrowUp') {
|
|
const currentIndex = playbackRates.findIndex((rate) => rate === keyboardSelectedRate);
|
|
if (currentIndex === 0) {
|
|
return;
|
|
}
|
|
if (currentIndex === -1) {
|
|
setKeyboardSelectedRate(playbackRates[0]);
|
|
}
|
|
else {
|
|
setKeyboardSelectedRate(playbackRates[currentIndex - 1]);
|
|
}
|
|
}
|
|
else if (e.key === 'ArrowDown') {
|
|
const currentIndex = playbackRates.findIndex((rate) => rate === keyboardSelectedRate);
|
|
if (currentIndex === playbackRates.length - 1) {
|
|
return;
|
|
}
|
|
if (currentIndex === -1) {
|
|
setKeyboardSelectedRate(playbackRates[playbackRates.length - 1]);
|
|
}
|
|
else {
|
|
setKeyboardSelectedRate(playbackRates[currentIndex + 1]);
|
|
}
|
|
}
|
|
else if (e.key === 'Enter') {
|
|
setPlaybackRate(keyboardSelectedRate);
|
|
setIsComponentVisible(false);
|
|
}
|
|
};
|
|
window.addEventListener('keydown', listener);
|
|
return () => {
|
|
window.removeEventListener('keydown', listener);
|
|
};
|
|
}, [
|
|
playbackRates,
|
|
keyboardSelectedRate,
|
|
setPlaybackRate,
|
|
setIsComponentVisible,
|
|
]);
|
|
const onSelect = (0, react_1.useCallback)((rate) => {
|
|
setPlaybackRate(rate);
|
|
setIsComponentVisible(false);
|
|
}, [setIsComponentVisible, setPlaybackRate]);
|
|
const playbackPopup = (0, react_1.useMemo)(() => {
|
|
return {
|
|
position: 'absolute',
|
|
right: 0,
|
|
width: 125,
|
|
maxHeight: canvasSize.height - THRESHOLD - BOTTOM,
|
|
bottom: 35,
|
|
background: '#fff',
|
|
borderRadius: 4,
|
|
overflow: 'auto',
|
|
color: 'black',
|
|
textAlign: 'left',
|
|
};
|
|
}, [canvasSize.height]);
|
|
return ((0, jsx_runtime_1.jsx)("div", { style: playbackPopup, children: playbackRates.map((rate) => {
|
|
return ((0, jsx_runtime_1.jsx)(PlaybackrateOption, { selectedRate: playbackRate, onSelect: onSelect, rate: rate, keyboardSelectedRate: keyboardSelectedRate }, rate));
|
|
}) }));
|
|
};
|
|
const label = {
|
|
fontSize: 13,
|
|
fontWeight: 'bold',
|
|
color: 'white',
|
|
border: '2px solid white',
|
|
borderRadius: 20,
|
|
paddingLeft: 8,
|
|
paddingRight: 8,
|
|
paddingTop: 2,
|
|
paddingBottom: 2,
|
|
};
|
|
exports.playerButtonStyle = {
|
|
appearance: 'none',
|
|
backgroundColor: 'transparent',
|
|
border: 'none',
|
|
cursor: 'pointer',
|
|
paddingLeft: 0,
|
|
paddingRight: 0,
|
|
paddingTop: 6,
|
|
paddingBottom: 6,
|
|
height: 37,
|
|
display: 'inline-flex',
|
|
marginBottom: 0,
|
|
marginTop: 0,
|
|
alignItems: 'center',
|
|
};
|
|
const button = {
|
|
...exports.playerButtonStyle,
|
|
position: 'relative',
|
|
};
|
|
const PlaybackrateControl = ({ playbackRates, canvasSize }) => {
|
|
const { ref, isComponentVisible, setIsComponentVisible } = (0, use_component_visible_js_1.default)(false);
|
|
const { playbackRate } = (0, react_1.useContext)(remotion_1.Internals.TimelineContext);
|
|
const onClick = (0, react_1.useCallback)((e) => {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
setIsComponentVisible((prevIsComponentVisible) => !prevIsComponentVisible);
|
|
}, [setIsComponentVisible]);
|
|
return ((0, jsx_runtime_1.jsx)("div", { ref: ref, children: (0, jsx_runtime_1.jsxs)("button", { type: "button", "aria-label": "Change playback rate", style: button, onClick: onClick, children: [(0, jsx_runtime_1.jsxs)("div", { style: label, children: [playbackRate, "x"] }), isComponentVisible && ((0, jsx_runtime_1.jsx)(PlaybackPopup, { canvasSize: canvasSize, playbackRates: playbackRates, setIsComponentVisible: setIsComponentVisible }))] }) }));
|
|
};
|
|
exports.PlaybackrateControl = PlaybackrateControl;
|