@remotion/player
Version:
React component for embedding a Remotion preview into your app
165 lines (164 loc) • 6.98 kB
JavaScript
;
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 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", { onMouseEnter: onMouseEnter, onMouseLeave: 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 }), rate.toFixed(1), "x"] }, rate));
};
const PlaybackPopup = ({ setIsComponentVisible, playbackRates, canvasSize }) => {
const { setPlaybackRate, playbackRate } = (0, react_1.useContext)(remotion_1.Internals.Timeline.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.Timeline.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;