@remotion/studio
Version:
APIs for interacting with the Remotion Studio
74 lines (73 loc) • 3.45 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TimelineRotationField = 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 unitPattern = /^([+-]?(?:\d+\.?\d*|\.\d+))(deg|rad|turn|grad)$/;
const unitToDegrees = {
deg: 1,
rad: 180 / Math.PI,
turn: 360,
grad: 360 / 400,
};
const parseCssRotationToDegrees = (value) => {
const match = value.trim().match(unitPattern);
if (match) {
return Number(match[1]) * unitToDegrees[match[2]];
}
try {
const m = new DOMMatrix(`rotate(${value})`);
return Math.round(Math.atan2(m.b, m.a) * (180 / Math.PI) * 1e6) / 1e6;
}
catch (_a) {
return 0;
}
};
const TimelineRotationField = ({ field, effectiveValue, codeValue, canUpdate, onSave, onDragValueChange, onDragEnd, }) => {
var _a;
const [dragValue, setDragValue] = (0, react_1.useState)(null);
const degrees = (0, react_1.useMemo)(() => parseCssRotationToDegrees(String(effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : '0deg')), [effectiveValue]);
const onValueChange = (0, react_1.useCallback)((newVal) => {
setDragValue(newVal);
onDragValueChange(field.key, `${newVal}deg`);
}, [onDragValueChange, field.key]);
const onValueChangeEnd = (0, react_1.useCallback)((newVal) => {
const newStr = `${newVal}deg`;
if (canUpdate && newStr !== codeValue) {
onSave(field.key, newStr).finally(() => {
setDragValue(null);
onDragEnd();
});
}
else {
setDragValue(null);
onDragEnd();
}
}, [canUpdate, onSave, field.key, codeValue, onDragEnd]);
const onTextChange = (0, react_1.useCallback)((newVal) => {
if (canUpdate) {
const parsed = Number(newVal);
if (!Number.isNaN(parsed)) {
const newStr = `${parsed}deg`;
if (newStr !== codeValue) {
setDragValue(parsed);
onSave(field.key, newStr).catch(() => {
setDragValue(null);
});
}
}
}
}, [canUpdate, onSave, field.key, codeValue]);
const step = field.fieldSchema.type === 'rotation' ? ((_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}\u00B0`;
}, [stepDecimals]);
return (jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragValue !== null && dragValue !== void 0 ? dragValue : degrees, style: timeline_field_utils_1.draggerStyle, status: "ok", small: true, onValueChange: onValueChange, onValueChangeEnd: onValueChangeEnd, onTextChange: onTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false }));
};
exports.TimelineRotationField = TimelineRotationField;