@remotion/studio
Version:
APIs for interacting with the Remotion Studio
131 lines (130 loc) • 5.88 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TimelineTranslateField = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const InputDragger_1 = require("../NewComposition/InputDragger");
const timeline_field_utils_1 = require("./timeline-field-utils");
const leftDraggerStyle = {
paddingLeft: 0,
};
const rightDraggerStyle = {
paddingRight: 0,
};
const PIXEL_PATTERN = /^(-?\d+(?:\.\d+)?)px(?:\s+(-?\d+(?:\.\d+)?)px)?$/;
const parseTranslate = (value) => {
const m = value.match(PIXEL_PATTERN);
if (!m) {
return [0, 0];
}
return [Number(m[1]), m[2] !== undefined ? Number(m[2]) : 0];
};
const containerStyle = {
display: 'flex',
gap: 4,
};
const TimelineTranslateField = ({ field, codeValue, effectiveValue, canUpdate, onSave, onDragValueChange, onDragEnd, }) => {
var _a;
const [dragX, setDragX] = (0, react_1.useState)(null);
const [dragY, setDragY] = (0, react_1.useState)(null);
const [codeX, codeY] = (0, react_1.useMemo)(() => parseTranslate(String(effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : '0px 0px')), [effectiveValue]);
const makeString = (0, react_1.useCallback)((x, y) => `${x}px ${y}px`, []);
const step = field.fieldSchema.type === 'translate' ? ((_a = field.fieldSchema.step) !== null && _a !== void 0 ? _a : 1) : 1;
const stepDecimals = (0, react_1.useMemo)(() => (0, timeline_field_utils_1.getDecimalPlaces)(step), [step]);
const formatter = (0, react_1.useCallback)((v) => {
const num = Number(v);
const digits = Math.max(stepDecimals, (0, timeline_field_utils_1.getDecimalPlaces)(num));
const formatted = digits === 0 ? String(num) : num.toFixed(digits);
return `${formatted}px`;
}, [stepDecimals]);
// --- X callbacks ---
const onXChange = (0, react_1.useCallback)((newVal) => {
setDragX(newVal);
const currentY = dragY !== null && dragY !== void 0 ? dragY : codeY;
onDragValueChange(field.key, makeString(newVal, currentY));
}, [onDragValueChange, field.key, dragY, codeY, makeString]);
const onXChangeEnd = (0, react_1.useCallback)((newVal) => {
const currentY = dragY !== null && dragY !== void 0 ? dragY : codeY;
const newStr = makeString(newVal, currentY);
if (canUpdate && newStr !== codeValue) {
onSave(field.key, newStr).finally(() => {
setDragX(null);
onDragEnd();
});
}
else {
setDragX(null);
onDragEnd();
}
}, [
dragY,
codeY,
makeString,
canUpdate,
codeValue,
onSave,
field.key,
onDragEnd,
]);
const onXTextChange = (0, react_1.useCallback)((newVal) => {
if (canUpdate) {
const parsed = Number(newVal);
if (!Number.isNaN(parsed)) {
const currentY = dragY !== null && dragY !== void 0 ? dragY : codeY;
const newStr = makeString(parsed, currentY);
if (newStr !== codeValue) {
setDragX(parsed);
onSave(field.key, newStr);
}
}
}
}, [canUpdate, dragY, codeY, makeString, codeValue, onSave, field.key]);
// --- Y callbacks ---
const onYChange = (0, react_1.useCallback)((newVal) => {
setDragY(newVal);
const currentX = dragX !== null && dragX !== void 0 ? dragX : codeX;
onDragValueChange(field.key, makeString(currentX, newVal));
}, [onDragValueChange, field.key, dragX, codeX, makeString]);
const onYChangeEnd = (0, react_1.useCallback)((newVal) => {
const currentX = dragX !== null && dragX !== void 0 ? dragX : codeX;
const newStr = makeString(currentX, newVal);
if (canUpdate && newStr !== codeValue) {
onSave(field.key, newStr).finally(() => {
setDragY(null);
onDragEnd();
});
}
else {
setDragY(null);
onDragEnd();
}
}, [
dragX,
codeX,
makeString,
canUpdate,
codeValue,
onSave,
field.key,
onDragEnd,
]);
const onYTextChange = (0, react_1.useCallback)((newVal) => {
if (canUpdate) {
const parsed = Number(newVal);
if (!Number.isNaN(parsed)) {
const currentX = dragX !== null && dragX !== void 0 ? dragX : codeX;
const newStr = makeString(currentX, parsed);
if (newStr !== codeValue) {
setDragY(parsed);
onSave(field.key, newStr).catch(() => {
setDragY(null);
});
}
}
}
}, [canUpdate, onSave, field.key, codeValue, dragX, codeX, makeString]);
return (jsx_runtime_1.jsxs("span", { style: containerStyle, children: [
jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragX !== null && dragX !== void 0 ? dragX : codeX, style: leftDraggerStyle, status: "ok", small: true, onValueChange: onXChange, onValueChangeEnd: onXChangeEnd, onTextChange: onXTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false }), jsx_runtime_1.jsx("div", { style: { marginLeft: -6, marginRight: -6 } }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragY !== null && dragY !== void 0 ? dragY : codeY, style: rightDraggerStyle, status: "ok", small: true, onValueChange: onYChange, onValueChangeEnd: onYChangeEnd, onTextChange: onYTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false })
] }));
};
exports.TimelineTranslateField = TimelineTranslateField;