@remotion/studio 4.0.482 → 4.0.484
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Canvas.js +19 -0
- package/dist/components/ColorPicker/ColorPicker.js +65 -3
- package/dist/components/ColorPicker/ColorPickerPopup.d.ts +1 -0
- package/dist/components/ColorPicker/ColorPickerPopup.js +3 -2
- package/dist/components/InspectorPanel/EasingInspector.js +184 -10
- package/dist/components/InspectorPanel/KeyframeEasingNavigator.d.ts +14 -0
- package/dist/components/InspectorPanel/KeyframeEasingNavigator.js +146 -0
- package/dist/components/InspectorPanel/KeyframeInspector.d.ts +1 -1
- package/dist/components/InspectorPanel/KeyframeInspector.js +228 -5
- package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +17 -0
- package/dist/components/InspectorPanel/SequenceInspectorHeader.js +93 -0
- package/dist/components/InspectorPanel/SequenceSelectionInspector.js +4 -58
- package/dist/components/InspectorPanel/common.d.ts +12 -0
- package/dist/components/InspectorPanel/common.js +78 -1
- package/dist/components/InspectorPanel/easing-inspector-selection.d.ts +14 -0
- package/dist/components/InspectorPanel/easing-inspector-selection.js +18 -0
- package/dist/components/InspectorPanel/keyframe-easing-navigator-items.d.ts +24 -0
- package/dist/components/InspectorPanel/keyframe-easing-navigator-items.js +40 -0
- package/dist/components/InspectorPanel/keyframe-inspector-frame.d.ts +8 -0
- package/dist/components/InspectorPanel/keyframe-inspector-frame.js +14 -0
- package/dist/components/InspectorPanel/styles.d.ts +1 -0
- package/dist/components/InspectorPanel/styles.js +9 -1
- package/dist/components/InspectorSequenceSection.js +47 -10
- package/dist/components/Preview.js +1 -1
- package/dist/components/SelectedOutlineOverlay.d.ts +2 -0
- package/dist/components/SelectedOutlineOverlay.js +33 -12
- package/dist/components/SelectedOutlineUvControls.js +461 -2
- package/dist/components/Timeline/EasingEditorModal.js +48 -5
- package/dist/components/Timeline/Timeline.js +2 -1
- package/dist/components/Timeline/TimelineDeleteKeybindings.js +11 -1
- package/dist/components/Timeline/TimelineEffectItem.js +8 -5
- package/dist/components/Timeline/TimelineEffectPropItem.js +82 -1
- package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +2 -2
- package/dist/components/Timeline/TimelineKeyframeControls.js +37 -7
- package/dist/components/Timeline/TimelineKeyframeEasingLine.d.ts +4 -0
- package/dist/components/Timeline/TimelineKeyframeEasingLine.js +12 -6
- package/dist/components/Timeline/TimelineKeyframedValue.js +1 -0
- package/dist/components/Timeline/TimelineRowChrome.js +6 -4
- package/dist/components/Timeline/TimelineSelection.d.ts +7 -1
- package/dist/components/Timeline/TimelineSelection.js +19 -3
- package/dist/components/Timeline/TimelineSequence.js +20 -8
- package/dist/components/Timeline/TimelineSequenceItem.js +64 -28
- package/dist/components/Timeline/TimelineSequenceName.d.ts +1 -0
- package/dist/components/Timeline/TimelineSequenceName.js +7 -6
- package/dist/components/Timeline/TimelineSequencePropItem.d.ts +1 -1
- package/dist/components/Timeline/TimelineSequencePropItem.js +80 -1
- package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +40 -1
- package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +308 -1
- package/dist/components/Timeline/TimelineSlider.js +17 -3
- package/dist/components/Timeline/TimelineTrack.js +2 -4
- package/dist/components/Timeline/delete-selected-timeline-item.d.ts +8 -2
- package/dist/components/Timeline/delete-selected-timeline-item.js +80 -1
- package/dist/components/Timeline/get-animation-item-selection-for-frame.d.ts +18 -0
- package/dist/components/Timeline/get-animation-item-selection-for-frame.js +49 -0
- package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.d.ts +15 -0
- package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.js +26 -0
- package/dist/components/Timeline/save-sequence-prop.js +2 -0
- package/dist/components/Timeline/should-subscribe-to-sequence-props.d.ts +4 -0
- package/dist/components/Timeline/should-subscribe-to-sequence-props.js +10 -0
- package/dist/components/Timeline/update-selected-easing.d.ts +1 -0
- package/dist/components/Timeline/update-selected-easing.js +4 -3
- package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.d.ts +2 -1
- package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.js +19 -13
- package/dist/components/element-drag-and-drop.d.ts +3 -0
- package/dist/components/element-drag-and-drop.js +30 -0
- package/dist/components/import-assets.d.ts +11 -0
- package/dist/components/import-assets.js +23 -1
- package/dist/components/selected-outline-uv.d.ts +71 -1
- package/dist/components/selected-outline-uv.js +332 -10
- package/dist/esm/{chunk-nkqfa5bw.js → chunk-9erwh79m.js} +11896 -9019
- package/dist/esm/internals.mjs +11896 -9019
- package/dist/esm/previewEntry.mjs +11923 -9046
- package/dist/esm/renderEntry.mjs +1 -1
- package/dist/helpers/timeline-layout.d.ts +3 -3
- package/dist/helpers/timeline-layout.js +3 -1
- package/dist/helpers/use-menu-structure.js +0 -14
- package/package.json +11 -11
|
@@ -37,9 +37,12 @@ const PRESET_PREVIEW_HEIGHT = 30;
|
|
|
37
37
|
const PRESET_PREVIEW_PADDING = 5;
|
|
38
38
|
const PRESET_PREVIEW_Y_MIN = -0.35;
|
|
39
39
|
const PRESET_PREVIEW_Y_MAX = 1.45;
|
|
40
|
+
const DEFAULT_DURATION_REST_THRESHOLD = 0.02;
|
|
40
41
|
const DEFAULT_SPRING_EASING = {
|
|
41
42
|
type: 'spring',
|
|
43
|
+
allowTail: true,
|
|
42
44
|
damping: 10,
|
|
45
|
+
durationRestThreshold: DEFAULT_DURATION_REST_THRESHOLD,
|
|
43
46
|
mass: 1,
|
|
44
47
|
overshootClamping: false,
|
|
45
48
|
stiffness: 100,
|
|
@@ -54,14 +57,22 @@ const EDITOR_EASING_PRESETS = [
|
|
|
54
57
|
];
|
|
55
58
|
const SPRING_LIMITS = {
|
|
56
59
|
damping: { min: 1, max: 200, step: 1 },
|
|
60
|
+
durationRestThreshold: { min: 0.001, max: 0.5, step: 0.001 },
|
|
57
61
|
mass: { min: 0.1, max: 20, step: 0.1 },
|
|
58
62
|
stiffness: { min: 1, max: 1000, step: 1 },
|
|
59
63
|
};
|
|
60
64
|
const SPRING_DECIMAL_PLACES = {
|
|
61
65
|
damping: 0,
|
|
66
|
+
durationRestThreshold: 3,
|
|
62
67
|
mass: 2,
|
|
63
68
|
stiffness: 0,
|
|
64
69
|
};
|
|
70
|
+
const SPRING_FALLBACKS = {
|
|
71
|
+
damping: DEFAULT_SPRING_EASING.damping,
|
|
72
|
+
durationRestThreshold: DEFAULT_DURATION_REST_THRESHOLD,
|
|
73
|
+
mass: DEFAULT_SPRING_EASING.mass,
|
|
74
|
+
stiffness: DEFAULT_SPRING_EASING.stiffness,
|
|
75
|
+
};
|
|
65
76
|
const inlineContainer = {
|
|
66
77
|
width: '100%',
|
|
67
78
|
minWidth: 0,
|
|
@@ -69,8 +80,8 @@ const inlineContainer = {
|
|
|
69
80
|
const segmentedControlWrapper = {
|
|
70
81
|
display: 'flex',
|
|
71
82
|
justifyContent: 'flex-start',
|
|
83
|
+
marginTop: 8,
|
|
72
84
|
padding: `0 ${InspectorPanelLayout_1.INSPECTOR_PANEL_HORIZONTAL_PADDING}px`,
|
|
73
|
-
marginBottom: 10,
|
|
74
85
|
};
|
|
75
86
|
const presetButtonsWrapper = {
|
|
76
87
|
display: 'flex',
|
|
@@ -80,6 +91,10 @@ const presetButtonsWrapper = {
|
|
|
80
91
|
marginBottom: 8,
|
|
81
92
|
padding: `0 ${InspectorPanelLayout_1.INSPECTOR_PANEL_HORIZONTAL_PADDING}px`,
|
|
82
93
|
};
|
|
94
|
+
const inspectorPresetButtonsWrapper = {
|
|
95
|
+
...presetButtonsWrapper,
|
|
96
|
+
padding: `8px ${InspectorPanelLayout_1.INSPECTOR_PANEL_HORIZONTAL_PADDING}px 0`,
|
|
97
|
+
};
|
|
83
98
|
const presetButtonBase = {
|
|
84
99
|
alignItems: 'center',
|
|
85
100
|
backgroundColor: colors_1.INPUT_BACKGROUND,
|
|
@@ -186,7 +201,11 @@ const sanitizeSpringValue = (value, key, fallback) => {
|
|
|
186
201
|
};
|
|
187
202
|
const sanitizeSpring = (spring) => ({
|
|
188
203
|
type: 'spring',
|
|
204
|
+
allowTail: spring.allowTail,
|
|
189
205
|
damping: sanitizeSpringValue(spring.damping, 'damping', DEFAULT_SPRING_EASING.damping),
|
|
206
|
+
durationRestThreshold: spring.durationRestThreshold === null
|
|
207
|
+
? null
|
|
208
|
+
: sanitizeSpringValue(spring.durationRestThreshold, 'durationRestThreshold', DEFAULT_DURATION_REST_THRESHOLD),
|
|
190
209
|
mass: sanitizeSpringValue(spring.mass, 'mass', DEFAULT_SPRING_EASING.mass),
|
|
191
210
|
overshootClamping: spring.overshootClamping,
|
|
192
211
|
stiffness: sanitizeSpringValue(spring.stiffness, 'stiffness', DEFAULT_SPRING_EASING.stiffness),
|
|
@@ -210,6 +229,7 @@ const formatNumberWithDecimalPlaces = (decimalPlaces) => (value) => {
|
|
|
210
229
|
};
|
|
211
230
|
const springFormatters = {
|
|
212
231
|
damping: formatNumberWithDecimalPlaces(SPRING_DECIMAL_PLACES.damping),
|
|
232
|
+
durationRestThreshold: formatNumberWithDecimalPlaces(SPRING_DECIMAL_PLACES.durationRestThreshold),
|
|
213
233
|
mass: formatNumberWithDecimalPlaces(SPRING_DECIMAL_PLACES.mass),
|
|
214
234
|
stiffness: formatNumberWithDecimalPlaces(SPRING_DECIMAL_PLACES.stiffness),
|
|
215
235
|
};
|
|
@@ -225,7 +245,9 @@ const areEasingsEqual = (first, second) => {
|
|
|
225
245
|
return true;
|
|
226
246
|
case 'spring':
|
|
227
247
|
return (second.type === 'spring' &&
|
|
248
|
+
first.allowTail === second.allowTail &&
|
|
228
249
|
first.damping === second.damping &&
|
|
250
|
+
first.durationRestThreshold === second.durationRestThreshold &&
|
|
229
251
|
first.mass === second.mass &&
|
|
230
252
|
first.overshootClamping === second.overshootClamping &&
|
|
231
253
|
first.stiffness === second.stiffness);
|
|
@@ -295,6 +317,7 @@ const presetPreviewYToSvg = (value) => PRESET_PREVIEW_PADDING +
|
|
|
295
317
|
(PRESET_PREVIEW_Y_MAX - PRESET_PREVIEW_Y_MIN)) *
|
|
296
318
|
(PRESET_PREVIEW_HEIGHT - PRESET_PREVIEW_PADDING * 2);
|
|
297
319
|
const getEasingFunction = (easing) => {
|
|
320
|
+
var _a, _b;
|
|
298
321
|
switch (easing.type) {
|
|
299
322
|
case 'linear':
|
|
300
323
|
return remotion_1.Easing.linear;
|
|
@@ -302,7 +325,9 @@ const getEasingFunction = (easing) => {
|
|
|
302
325
|
return remotion_1.Easing.bezier(easing.x1, easing.y1, easing.x2, easing.y2);
|
|
303
326
|
case 'spring':
|
|
304
327
|
return remotion_1.Easing.spring({
|
|
328
|
+
allowTail: (_a = easing.allowTail) !== null && _a !== void 0 ? _a : undefined,
|
|
305
329
|
damping: easing.damping,
|
|
330
|
+
durationRestThreshold: (_b = easing.durationRestThreshold) !== null && _b !== void 0 ? _b : undefined,
|
|
306
331
|
mass: easing.mass,
|
|
307
332
|
overshootClamping: easing.overshootClamping,
|
|
308
333
|
stiffness: easing.stiffness,
|
|
@@ -374,6 +399,7 @@ const EasingPresetButton = ({ currentEasing, disabled, onClick, preset }) => {
|
|
|
374
399
|
return (jsx_runtime_1.jsx("button", { type: "button", style: style, title: preset.label, "aria-label": `Apply ${preset.label} easing`, disabled: disabled, onClick: handleClick, children: jsx_runtime_1.jsx("svg", { width: PRESET_PREVIEW_WIDTH, height: PRESET_PREVIEW_HEIGHT, viewBox: `0 0 ${PRESET_PREVIEW_WIDTH} ${PRESET_PREVIEW_HEIGHT}`, style: presetPreviewSvgStyle, "aria-hidden": "true", focusable: false, children: jsx_runtime_1.jsx("path", { d: path, fill: "none", stroke: "white", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" }) }) }));
|
|
375
400
|
};
|
|
376
401
|
const EasingEditor = ({ state, renderHeader }) => {
|
|
402
|
+
var _a, _b;
|
|
377
403
|
const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
|
|
378
404
|
const sequencesRef = (0, react_1.useContext)(remotion_1.Internals.SequenceManagerRefContext);
|
|
379
405
|
const propStatusesRef = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesRefContext);
|
|
@@ -532,7 +558,7 @@ const EasingEditor = ({ state, renderHeader }) => {
|
|
|
532
558
|
const setSpringNumber = (0, react_1.useCallback)((key, value, commit) => {
|
|
533
559
|
const next = {
|
|
534
560
|
...springRef.current,
|
|
535
|
-
[key]: sanitizeSpringValue(value, key,
|
|
561
|
+
[key]: sanitizeSpringValue(value, key, SPRING_FALLBACKS[key]),
|
|
536
562
|
};
|
|
537
563
|
const version = setSpringAndPreview(next);
|
|
538
564
|
if (commit) {
|
|
@@ -547,6 +573,15 @@ const EasingEditor = ({ state, renderHeader }) => {
|
|
|
547
573
|
const version = setSpringAndPreview(next);
|
|
548
574
|
commitEasing(serializeSpring(next), version);
|
|
549
575
|
}, [commitEasing, setSpringAndPreview]);
|
|
576
|
+
const setAllowTail = (0, react_1.useCallback)(() => {
|
|
577
|
+
var _a;
|
|
578
|
+
const next = {
|
|
579
|
+
...springRef.current,
|
|
580
|
+
allowTail: !((_a = springRef.current.allowTail) !== null && _a !== void 0 ? _a : false),
|
|
581
|
+
};
|
|
582
|
+
const version = setSpringAndPreview(next);
|
|
583
|
+
commitEasing(serializeSpring(next), version);
|
|
584
|
+
}, [commitEasing, setSpringAndPreview]);
|
|
550
585
|
const switchMode = (0, react_1.useCallback)((nextMode) => {
|
|
551
586
|
setMode(nextMode);
|
|
552
587
|
if (mode === nextMode || previewServerState.type !== 'connected') {
|
|
@@ -647,8 +682,11 @@ const EasingEditor = ({ state, renderHeader }) => {
|
|
|
647
682
|
return `M ${startPoint.x} ${startPoint.y} C ${firstHandle.x} ${firstHandle.y}, ${secondHandle.x} ${secondHandle.y}, ${endPoint.x} ${endPoint.y}`;
|
|
648
683
|
}, [endPoint, firstHandle, secondHandle, startPoint]);
|
|
649
684
|
const springPath = (0, react_1.useMemo)(() => {
|
|
685
|
+
var _a, _b;
|
|
650
686
|
const easing = remotion_1.Easing.spring({
|
|
687
|
+
allowTail: (_a = spring.allowTail) !== null && _a !== void 0 ? _a : undefined,
|
|
651
688
|
damping: spring.damping,
|
|
689
|
+
durationRestThreshold: (_b = spring.durationRestThreshold) !== null && _b !== void 0 ? _b : undefined,
|
|
652
690
|
mass: spring.mass,
|
|
653
691
|
overshootClamping: spring.overshootClamping,
|
|
654
692
|
stiffness: spring.stiffness,
|
|
@@ -687,10 +725,11 @@ const EasingEditor = ({ state, renderHeader }) => {
|
|
|
687
725
|
gridTemplateColumns: 'repeat(2, minmax(0, 1fr))',
|
|
688
726
|
padding: '0 12px 12px',
|
|
689
727
|
}), []);
|
|
690
|
-
|
|
728
|
+
const modeSwitcher = (jsx_runtime_1.jsx("div", { style: segmentedControlWrapper, children: jsx_runtime_1.jsx(SegmentedControl_1.SegmentedControl, { items: modeItems, needsWrapping: false }) }));
|
|
729
|
+
return (jsx_runtime_1.jsxs("div", { style: inlineContainer, children: [renderHeader ? renderHeader(modeItems) : null, jsx_runtime_1.jsx("div", { style: renderHeader ? inspectorPresetButtonsWrapper : presetButtonsWrapper, children: EDITOR_EASING_PRESETS.map((preset) => (jsx_runtime_1.jsx(EasingPresetButton, { currentEasing: currentEasing, disabled: disabled, onClick: applyPreset, preset: preset }, preset.id))) }), mode === 'bezier' ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
691
730
|
jsx_runtime_1.jsxs("svg", { ref: svgRef, width: SVG_WIDTH, height: SVG_HEIGHT, viewBox: `0 0 ${SVG_WIDTH} ${SVG_HEIGHT}`, style: svgStyle, "aria-label": "Bezier curve editor", children: [
|
|
692
731
|
jsx_runtime_1.jsx(EasingGraphScaffold, { labels: graphLabels }), jsx_runtime_1.jsx("line", { x1: startPoint.x, y1: startPoint.y, x2: firstHandle.x, y2: firstHandle.y, stroke: "rgba(255, 255, 255, 0.35)", strokeWidth: 1 }), jsx_runtime_1.jsx("line", { x1: endPoint.x, y1: endPoint.y, x2: secondHandle.x, y2: secondHandle.y, stroke: "rgba(255, 255, 255, 0.35)", strokeWidth: 1 }), jsx_runtime_1.jsx("path", { d: bezierPath, fill: "none", stroke: colors_1.BLUE, strokeWidth: 3 }), jsx_runtime_1.jsx("circle", { cx: startPoint.x, cy: startPoint.y, r: 4, fill: "white" }), jsx_runtime_1.jsx("circle", { cx: endPoint.x, cy: endPoint.y, r: 4, fill: "white" }), jsx_runtime_1.jsx("circle", { cx: firstHandle.x, cy: firstHandle.y, r: 6, fill: "white", stroke: colors_1.BLUE, strokeWidth: 2, vectorEffect: "non-scaling-stroke", pointerEvents: disabled ? 'none' : 'all', cursor: activeHandle === 0 ? 'grabbing' : 'default', onPointerDown: (event) => onHandlePointerDown(0, event) }), jsx_runtime_1.jsx("circle", { cx: secondHandle.x, cy: secondHandle.y, r: 6, fill: "white", stroke: colors_1.BLUE, strokeWidth: 2, vectorEffect: "non-scaling-stroke", pointerEvents: disabled ? 'none' : 'all', cursor: activeHandle === 1 ? 'grabbing' : 'default', onPointerDown: (event) => onHandlePointerDown(1, event) })
|
|
693
|
-
] }), jsx_runtime_1.jsxs("div", { style: coordinatesGrid, children: [
|
|
732
|
+
] }), modeSwitcher, jsx_runtime_1.jsxs("div", { style: coordinatesGrid, children: [
|
|
694
733
|
jsx_runtime_1.jsxs("div", { style: coordinateRow, children: [
|
|
695
734
|
jsx_runtime_1.jsx("div", { style: coordinateLabel, children: "X1" }), jsx_runtime_1.jsx("div", { style: coordinateInputWrapper, children: jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: bezier[0], status: "ok", onValueChange: (value) => setCoordinate(0, 'x', value, false), onValueChangeEnd: (value) => setCoordinate(0, 'x', value, true), onTextChange: () => undefined, min: 0, max: 1, step: 0.01, formatter: formatNumber, rightAlign: false, style: numberInputStyle, snapToStep: false, disabled: disabled }) })
|
|
696
735
|
] }), jsx_runtime_1.jsxs("div", { style: coordinateRow, children: [
|
|
@@ -704,15 +743,19 @@ const EasingEditor = ({ state, renderHeader }) => {
|
|
|
704
743
|
] })) : (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
705
744
|
jsx_runtime_1.jsxs("svg", { width: SVG_WIDTH, height: SVG_HEIGHT, viewBox: `0 0 ${SVG_WIDTH} ${SVG_HEIGHT}`, style: svgStyle, "aria-label": "Spring easing curve", children: [
|
|
706
745
|
jsx_runtime_1.jsx(EasingGraphScaffold, { labels: graphLabels }), jsx_runtime_1.jsx("path", { d: springPath, fill: "none", stroke: colors_1.BLUE, strokeWidth: 3 }), jsx_runtime_1.jsx("circle", { cx: xToSvg(0), cy: yToSvg(0), r: 4, fill: "white" }), jsx_runtime_1.jsx("circle", { cx: xToSvg(1), cy: yToSvg(1), r: 4, fill: "white" })
|
|
707
|
-
] }), jsx_runtime_1.jsxs("div", { style: coordinatesGrid, children: [
|
|
746
|
+
] }), modeSwitcher, jsx_runtime_1.jsxs("div", { style: coordinatesGrid, children: [
|
|
708
747
|
jsx_runtime_1.jsxs("div", { style: coordinateRow, children: [
|
|
709
748
|
jsx_runtime_1.jsx("div", { style: coordinateLabel, children: "Damping" }), jsx_runtime_1.jsx("div", { style: coordinateInputWrapper, children: jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: spring.damping, status: "ok", onValueChange: (value) => setSpringNumber('damping', value, false), onValueChangeEnd: (value) => setSpringNumber('damping', value, true), onTextChange: () => undefined, min: SPRING_LIMITS.damping.min, max: SPRING_LIMITS.damping.max, step: SPRING_LIMITS.damping.step, formatter: springFormatters.damping, rightAlign: false, style: numberInputStyle, snapToStep: false, dragDecimalPlaces: SPRING_DECIMAL_PLACES.damping, disabled: disabled }) })
|
|
710
749
|
] }), jsx_runtime_1.jsxs("div", { style: coordinateRow, children: [
|
|
711
750
|
jsx_runtime_1.jsx("div", { style: coordinateLabel, children: "Mass" }), jsx_runtime_1.jsx("div", { style: coordinateInputWrapper, children: jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: spring.mass, status: "ok", onValueChange: (value) => setSpringNumber('mass', value, false), onValueChangeEnd: (value) => setSpringNumber('mass', value, true), onTextChange: () => undefined, min: SPRING_LIMITS.mass.min, max: SPRING_LIMITS.mass.max, step: SPRING_LIMITS.mass.step, formatter: springFormatters.mass, rightAlign: false, style: numberInputStyle, snapToStep: false, dragDecimalPlaces: SPRING_DECIMAL_PLACES.mass, disabled: disabled }) })
|
|
712
751
|
] }), jsx_runtime_1.jsxs("div", { style: coordinateRow, children: [
|
|
713
752
|
jsx_runtime_1.jsx("div", { style: coordinateLabel, children: "Stiffness" }), jsx_runtime_1.jsx("div", { style: coordinateInputWrapper, children: jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: spring.stiffness, status: "ok", onValueChange: (value) => setSpringNumber('stiffness', value, false), onValueChangeEnd: (value) => setSpringNumber('stiffness', value, true), onTextChange: () => undefined, min: SPRING_LIMITS.stiffness.min, max: SPRING_LIMITS.stiffness.max, step: SPRING_LIMITS.stiffness.step, formatter: springFormatters.stiffness, rightAlign: false, style: numberInputStyle, snapToStep: false, dragDecimalPlaces: SPRING_DECIMAL_PLACES.stiffness, disabled: disabled }) })
|
|
753
|
+
] }), jsx_runtime_1.jsxs("div", { style: coordinateRow, children: [
|
|
754
|
+
jsx_runtime_1.jsx("div", { style: coordinateLabel, children: "Rest threshold" }), jsx_runtime_1.jsx("div", { style: coordinateInputWrapper, children: jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: (_a = spring.durationRestThreshold) !== null && _a !== void 0 ? _a : DEFAULT_DURATION_REST_THRESHOLD, status: "ok", onValueChange: (value) => setSpringNumber('durationRestThreshold', value, false), onValueChangeEnd: (value) => setSpringNumber('durationRestThreshold', value, true), onTextChange: () => undefined, min: SPRING_LIMITS.durationRestThreshold.min, max: SPRING_LIMITS.durationRestThreshold.max, step: SPRING_LIMITS.durationRestThreshold.step, formatter: springFormatters.durationRestThreshold, rightAlign: false, style: numberInputStyle, snapToStep: false, dragDecimalPlaces: SPRING_DECIMAL_PLACES.durationRestThreshold, disabled: disabled }) })
|
|
714
755
|
] }), jsx_runtime_1.jsxs("div", { style: coordinateRow, children: [
|
|
715
756
|
jsx_runtime_1.jsx("div", { style: coordinateLabel, children: "Clamp overshoot" }), jsx_runtime_1.jsx("div", { style: checkboxWrapper, children: jsx_runtime_1.jsx(Checkbox_1.Checkbox, { checked: spring.overshootClamping, onChange: setOvershootClamping, name: "spring-overshoot-clamping", disabled: disabled, variant: "small" }) })
|
|
757
|
+
] }), jsx_runtime_1.jsxs("div", { style: coordinateRow, children: [
|
|
758
|
+
jsx_runtime_1.jsx("div", { style: coordinateLabel, children: "Allow tail" }), jsx_runtime_1.jsx("div", { style: checkboxWrapper, children: jsx_runtime_1.jsx(Checkbox_1.Checkbox, { checked: (_b = spring.allowTail) !== null && _b !== void 0 ? _b : false, onChange: setAllowTail, name: "spring-allow-tail", disabled: disabled, variant: "small" }) })
|
|
716
759
|
] })
|
|
717
760
|
] })
|
|
718
761
|
] }))] }));
|
|
@@ -53,6 +53,7 @@ const SplitterHandle_1 = require("../Splitter/SplitterHandle");
|
|
|
53
53
|
const MaxTimelineTracks_1 = require("./MaxTimelineTracks");
|
|
54
54
|
const SequencePropsObserver_1 = require("./SequencePropsObserver");
|
|
55
55
|
const should_show_track_in_timeline_1 = require("./should-show-track-in-timeline");
|
|
56
|
+
const should_subscribe_to_sequence_props_1 = require("./should-subscribe-to-sequence-props");
|
|
56
57
|
const SubscribeToNodePaths_1 = require("./SubscribeToNodePaths");
|
|
57
58
|
const timeline_refs_1 = require("./timeline-refs");
|
|
58
59
|
const TimelineDragHandler_1 = require("./TimelineDragHandler");
|
|
@@ -227,7 +228,7 @@ const TimelineInner = () => {
|
|
|
227
228
|
}, [filtered]);
|
|
228
229
|
const hasBeenCut = filtered.length > shown.length;
|
|
229
230
|
return (jsx_runtime_1.jsxs(TimelineContextMenuArea, { children: [sequences.map((sequence) => {
|
|
230
|
-
if (!sequence
|
|
231
|
+
if (!(0, should_subscribe_to_sequence_props_1.shouldSubscribeToSequenceProps)(sequence, previewConnected)) {
|
|
231
232
|
return null;
|
|
232
233
|
}
|
|
233
234
|
return (jsx_runtime_1.jsx(SubscribeToNodePaths_1.SubscribeToNodePaths, { overrideId: sequence.controls.overrideId, componentIdentity: sequence.controls.componentIdentity, schema: sequence.controls.schema, getStack: sequence.getStack, effects: sequence.effects }, sequence.id));
|
|
@@ -24,6 +24,9 @@ const TimelineDeleteKeybindings = () => {
|
|
|
24
24
|
const { canSelect } = (0, TimelineSelection_1.useTimelineSelection)();
|
|
25
25
|
const currentSelection = (0, TimelineSelection_1.useCurrentTimelineSelectionStateAsRef)();
|
|
26
26
|
const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
|
|
27
|
+
const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
|
|
28
|
+
const timelinePositionRef = (0, react_1.useRef)(timelinePosition);
|
|
29
|
+
timelinePositionRef.current = timelinePosition;
|
|
27
30
|
(0, react_1.useEffect)(() => {
|
|
28
31
|
if (!canSelect || previewServerState.type !== 'connected') {
|
|
29
32
|
return;
|
|
@@ -58,7 +61,13 @@ const TimelineDeleteKeybindings = () => {
|
|
|
58
61
|
deletePromise
|
|
59
62
|
.then((deleted) => {
|
|
60
63
|
if (deleted) {
|
|
61
|
-
const nextSelection = (0, delete_selected_timeline_item_1.getTimelineSelectionAfterDeletingItems)(
|
|
64
|
+
const nextSelection = (0, delete_selected_timeline_item_1.getTimelineSelectionAfterDeletingItems)({
|
|
65
|
+
selections: selectedItems,
|
|
66
|
+
sequences,
|
|
67
|
+
overrideIdsToNodePaths: overrideIdToNodePathMappings,
|
|
68
|
+
propStatuses,
|
|
69
|
+
timelinePosition: timelinePositionRef.current,
|
|
70
|
+
});
|
|
62
71
|
if (nextSelection.length === 0) {
|
|
63
72
|
clearSelection();
|
|
64
73
|
}
|
|
@@ -154,6 +163,7 @@ const TimelineDeleteKeybindings = () => {
|
|
|
154
163
|
sequencesRef,
|
|
155
164
|
setGuidesList,
|
|
156
165
|
setPropStatuses,
|
|
166
|
+
timelinePositionRef,
|
|
157
167
|
]);
|
|
158
168
|
return null;
|
|
159
169
|
};
|
|
@@ -71,6 +71,7 @@ const TimelineEffectItem = ({ label, nodePathInfo, effectIndex, effectSchema, do
|
|
|
71
71
|
const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
|
|
72
72
|
const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
|
|
73
73
|
const selection = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
|
|
74
|
+
const containsSelection = (0, TimelineSelection_1.useTimelineRowContainsSelection)(nodePathInfo);
|
|
74
75
|
const [dropIndicator, setDropIndicator] = (0, react_1.useState)(null);
|
|
75
76
|
const effectStatus = (0, react_1.useMemo)(() => remotion_1.Internals.getEffectPropStatusesCtx({
|
|
76
77
|
propStatuses,
|
|
@@ -205,12 +206,14 @@ const TimelineEffectItem = ({ label, nodePathInfo, effectIndex, effectSchema, do
|
|
|
205
206
|
alignSelf: 'stretch',
|
|
206
207
|
alignItems: 'center',
|
|
207
208
|
color: (0, TimelineSelection_1.getTimelineColor)(selection.selected, true),
|
|
208
|
-
display: 'flex',
|
|
209
|
-
|
|
209
|
+
display: 'inline-flex',
|
|
210
|
+
marginRight: timeline_layout_1.EXPANDED_SECTION_PADDING_RIGHT,
|
|
210
211
|
minWidth: 0,
|
|
211
|
-
|
|
212
|
+
boxShadow: containsSelection && !selection.selected
|
|
213
|
+
? `inset 0 0 0 2px ${TimelineSelection_1.TIMELINE_SELECTED_LABEL_BACKGROUND}`
|
|
214
|
+
: undefined,
|
|
212
215
|
};
|
|
213
|
-
}, [selection.selected]);
|
|
216
|
+
}, [containsSelection, selection.selected]);
|
|
214
217
|
const getDropTarget = (0, react_1.useCallback)((e) => {
|
|
215
218
|
const dragData = getEffectReorderDragData(e.dataTransfer);
|
|
216
219
|
if (!dragData || dragData.nodePathKey !== nodePathKey) {
|
|
@@ -316,7 +319,7 @@ const TimelineEffectItem = ({ label, nodePathInfo, effectIndex, effectSchema, do
|
|
|
316
319
|
...(dropIndicator === 'before' ? { top: -1 } : { bottom: -1 }),
|
|
317
320
|
};
|
|
318
321
|
}, [dropIndicator]);
|
|
319
|
-
const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: canToggle ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: "effect", hidden: isDisabled, onInvoked: onToggle })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(nodePathInfo), label: `${label} section`, disabled: false }), style: rowStyle, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, showSelectedBackground: true, containsSelection:
|
|
322
|
+
const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: canToggle ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: "effect", hidden: isDisabled, onInvoked: onToggle })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(nodePathInfo), label: `${label} section`, disabled: false }), style: rowStyle, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, showSelectedBackground: true, containsSelection: containsSelection, outerHeight: null, children: jsx_runtime_1.jsx("span", { title: label, style: labelStyle, children: label }) }));
|
|
320
323
|
const draggableRow = canReorder ? (jsx_runtime_1.jsxs("div", { draggable: true, onDragStart: onDragStart, onDragEnd: onDragEnd, onDragOver: onDragOver, onDragLeave: onDragLeave, onDrop: onDrop, style: reorderWrapper, children: [reorderLineStyle ? jsx_runtime_1.jsx("div", { style: reorderLineStyle }) : null, row] })) : (row);
|
|
321
324
|
return previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selection.selectable ? selection.onSelect : null, children: draggableRow })) : (draggableRow);
|
|
322
325
|
};
|
|
@@ -10,6 +10,7 @@ const modals_1 = require("../../state/modals");
|
|
|
10
10
|
const call_api_1 = require("../call-api");
|
|
11
11
|
const ContextMenu_1 = require("../ContextMenu");
|
|
12
12
|
const call_add_keyframe_1 = require("./call-add-keyframe");
|
|
13
|
+
const get_animation_item_selection_for_frame_1 = require("./get-animation-item-selection-for-frame");
|
|
13
14
|
const get_timeline_keyframes_1 = require("./get-timeline-keyframes");
|
|
14
15
|
const save_effect_prop_1 = require("./save-effect-prop");
|
|
15
16
|
const save_prop_queue_1 = require("./save-prop-queue");
|
|
@@ -22,6 +23,7 @@ const TimelineLayerEye_1 = require("./TimelineLayerEye");
|
|
|
22
23
|
const TimelineRowChrome_1 = require("./TimelineRowChrome");
|
|
23
24
|
const TimelineSchemaField_1 = require("./TimelineSchemaField");
|
|
24
25
|
const TimelineSelection_1 = require("./TimelineSelection");
|
|
26
|
+
const update_selected_easing_1 = require("./update-selected-easing");
|
|
25
27
|
const fieldRowBase = {};
|
|
26
28
|
const isKeyframedStatus = (status) => {
|
|
27
29
|
return status.status === 'keyframed';
|
|
@@ -219,6 +221,9 @@ const TimelineEffectPropItem = ({ field, validatedLocation, rowDepth, nodePath,
|
|
|
219
221
|
const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
|
|
220
222
|
const { getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
|
|
221
223
|
const selection = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
|
|
224
|
+
const { selectItems } = (0, TimelineSelection_1.useTimelineSelection)();
|
|
225
|
+
const setFrame = remotion_1.Internals.useTimelineSetFrame();
|
|
226
|
+
const videoConfig = (0, remotion_1.useVideoConfig)();
|
|
222
227
|
const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
|
|
223
228
|
const sourceFrame = timelinePosition - keyframeDisplayOffset;
|
|
224
229
|
const style = (0, react_1.useMemo)(() => {
|
|
@@ -359,7 +364,83 @@ const TimelineEffectPropItem = ({ field, validatedLocation, rowDepth, nodePath,
|
|
|
359
364
|
previewServerState,
|
|
360
365
|
propStatus,
|
|
361
366
|
]);
|
|
362
|
-
const
|
|
367
|
+
const seekToDisplayFrame = (0, react_1.useCallback)((frame) => {
|
|
368
|
+
setFrame((current) => {
|
|
369
|
+
const next = { ...current, [videoConfig.id]: frame };
|
|
370
|
+
remotion_1.Internals.persistCurrentFrame(next);
|
|
371
|
+
return next;
|
|
372
|
+
});
|
|
373
|
+
}, [setFrame, videoConfig.id]);
|
|
374
|
+
const onPropertyDoubleClick = (0, react_1.useCallback)((event) => {
|
|
375
|
+
if (propStatus === null || propStatus.status === 'computed') {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
const keyframeSelection = {
|
|
379
|
+
type: 'keyframe',
|
|
380
|
+
nodePathInfo,
|
|
381
|
+
frame: sourceFrame + keyframeDisplayOffset,
|
|
382
|
+
};
|
|
383
|
+
if (propStatus.status === 'static') {
|
|
384
|
+
if (!keyframable || previewServerState.type !== 'connected') {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
const value = remotion_1.Internals.getEffectiveVisualModeValue({
|
|
388
|
+
propStatus,
|
|
389
|
+
dragOverrideValue,
|
|
390
|
+
frame: sourceFrame,
|
|
391
|
+
defaultValue: field.fieldSchema.default,
|
|
392
|
+
shouldResortToDefaultValueIfUndefined: true,
|
|
393
|
+
});
|
|
394
|
+
event.stopPropagation();
|
|
395
|
+
(0, call_add_keyframe_1.callAddEffectKeyframe)({
|
|
396
|
+
fileName: validatedLocation.source,
|
|
397
|
+
nodePath,
|
|
398
|
+
effectIndex: field.effectIndex,
|
|
399
|
+
fieldKey: field.key,
|
|
400
|
+
sourceFrame,
|
|
401
|
+
value,
|
|
402
|
+
schema: field.effectSchema,
|
|
403
|
+
setPropStatuses,
|
|
404
|
+
clientId: previewServerState.clientId,
|
|
405
|
+
}).catch(() => undefined);
|
|
406
|
+
selectItems([keyframeSelection], { reveal: true });
|
|
407
|
+
seekToDisplayFrame(keyframeSelection.frame);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
const targetSelection = (0, get_animation_item_selection_for_frame_1.getAnimationItemSelectionForSourceFrame)({
|
|
411
|
+
includeEasings: (0, update_selected_easing_1.canEditEasingForInterpolationFunction)(propStatus.interpolationFunction),
|
|
412
|
+
keyframeDisplayOffset,
|
|
413
|
+
keyframes: propStatus.keyframes,
|
|
414
|
+
nodePathInfo,
|
|
415
|
+
sourceFrame,
|
|
416
|
+
});
|
|
417
|
+
if (targetSelection === null) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
event.stopPropagation();
|
|
421
|
+
selectItems([targetSelection], { reveal: true });
|
|
422
|
+
if (targetSelection.type === 'keyframe') {
|
|
423
|
+
seekToDisplayFrame(targetSelection.frame);
|
|
424
|
+
}
|
|
425
|
+
}, [
|
|
426
|
+
dragOverrideValue,
|
|
427
|
+
field.effectIndex,
|
|
428
|
+
field.effectSchema,
|
|
429
|
+
field.fieldSchema.default,
|
|
430
|
+
field.key,
|
|
431
|
+
keyframeDisplayOffset,
|
|
432
|
+
keyframable,
|
|
433
|
+
nodePath,
|
|
434
|
+
nodePathInfo,
|
|
435
|
+
previewServerState,
|
|
436
|
+
propStatus,
|
|
437
|
+
seekToDisplayFrame,
|
|
438
|
+
selectItems,
|
|
439
|
+
setPropStatuses,
|
|
440
|
+
sourceFrame,
|
|
441
|
+
validatedLocation.source,
|
|
442
|
+
]);
|
|
443
|
+
const row = (jsx_runtime_1.jsxs(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), keyframeControls: keyframeControls, arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: style, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, onDoubleClick: onPropertyDoubleClick, showSelectedBackground: true, containsSelection: false, outerHeight: null, children: [
|
|
363
444
|
jsx_runtime_1.jsx(TimelineFieldLabel_1.TimelineFieldLabel, { rowDepth: rowDepth, selected: selection.selected, label: (_c = field.description) !== null && _c !== void 0 ? _c : field.key }), jsx_runtime_1.jsx("div", { style: timeline_field_row_layout_1.timelineFieldValueColumnStyle, children: jsx_runtime_1.jsx(exports.TimelineEffectPropValue, { field: field, nodePath: nodePath, validatedLocation: validatedLocation, sourceFrame: sourceFrame }) })
|
|
364
445
|
] }));
|
|
365
446
|
return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selection.selectable ? selection.onSelect : null, children: row }));
|
|
@@ -50,11 +50,11 @@ const rowSeparator = {
|
|
|
50
50
|
};
|
|
51
51
|
const TimelineExpandedKeyframeRowUnmemoized = ({ height, keyframes, canEditEasing, nodePathInfo, showSeparator }) => {
|
|
52
52
|
const timelineWidth = (0, react_1.useContext)(TimelineWidthProvider_1.TimelineWidthContext);
|
|
53
|
-
const
|
|
53
|
+
const rowHighlightBackground = (0, TimelineSelection_1.useTimelineRowHighlightBackground)(nodePathInfo);
|
|
54
54
|
const easingSegments = canEditEasing
|
|
55
55
|
? (0, get_timeline_easing_segments_1.getTimelineEasingSegments)(keyframes)
|
|
56
56
|
: [];
|
|
57
|
-
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [showSeparator ? jsx_runtime_1.jsx("div", { style: rowSeparator }) : null, jsx_runtime_1.jsxs("div", { style: { ...row, height }, children: [
|
|
57
|
+
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [showSeparator ? jsx_runtime_1.jsx("div", { style: rowSeparator }) : null, jsx_runtime_1.jsxs("div", { style: { ...row, height }, children: [rowHighlightBackground && timelineWidth !== null ? (jsx_runtime_1.jsx("div", { style: (0, TimelineSelection_1.getTimelineSelectedTrackHighlightStyle)(timelineWidth, rowHighlightBackground) })) : null, easingSegments.map((segment) => (jsx_runtime_1.jsx(TimelineKeyframeEasingLine_1.TimelineKeyframeEasingLine, { fromFrame: segment.fromFrame, toFrame: segment.toFrame, rowHeight: height, nodePathInfo: nodePathInfo, segmentIndex: segment.segmentIndex }, `${segment.segmentIndex}-${segment.fromFrame}-${segment.toFrame}`))), keyframes.map((keyframe) => (jsx_runtime_1.jsx(TimelineKeyframeDiamond_1.TimelineKeyframeDiamond, { frame: keyframe.frame, rowHeight: height, nodePathInfo: nodePathInfo }, keyframe.frame)))] })
|
|
58
58
|
] }));
|
|
59
59
|
};
|
|
60
60
|
exports.TimelineExpandedKeyframeRow = react_1.default.memo(TimelineExpandedKeyframeRowUnmemoized);
|
|
@@ -11,11 +11,13 @@ const timeline_layout_1 = require("../../helpers/timeline-layout");
|
|
|
11
11
|
const timeline_node_path_key_1 = require("../../helpers/timeline-node-path-key");
|
|
12
12
|
const call_add_keyframe_1 = require("./call-add-keyframe");
|
|
13
13
|
const call_delete_keyframe_1 = require("./call-delete-keyframe");
|
|
14
|
+
const get_easing_selection_after_keyframe_delete_1 = require("./get-easing-selection-after-keyframe-delete");
|
|
14
15
|
const get_keyframe_navigation_1 = require("./get-keyframe-navigation");
|
|
15
16
|
const get_timeline_keyframes_1 = require("./get-timeline-keyframes");
|
|
16
17
|
const TimelineKeyframeDiamondIcon_1 = require("./TimelineKeyframeDiamondIcon");
|
|
17
18
|
const TimelineKeyframeTracksContext_1 = require("./TimelineKeyframeTracksContext");
|
|
18
19
|
const TimelineSelection_1 = require("./TimelineSelection");
|
|
20
|
+
const update_selected_easing_1 = require("./update-selected-easing");
|
|
19
21
|
const controlsContainerStyle = {
|
|
20
22
|
alignItems: 'center',
|
|
21
23
|
display: 'flex',
|
|
@@ -262,7 +264,7 @@ const shouldShowTimelineKeyframeNavigation = ({ propStatus, selected, }) => {
|
|
|
262
264
|
return isKeyframedStatus(propStatus);
|
|
263
265
|
};
|
|
264
266
|
exports.shouldShowTimelineKeyframeNavigation = shouldShowTimelineKeyframeNavigation;
|
|
265
|
-
const TimelineKeyframeControls = ({ fieldKey, propStatus, nodePath, fileName, keyframeDisplayOffset, defaultValue, dragOverrideValue, schema, effectIndex, nodePathInfo, }) => {
|
|
267
|
+
const TimelineKeyframeControls = ({ fieldKey, propStatus, nodePath, fileName, keyframeDisplayOffset, defaultValue, dragOverrideValue, schema, effectIndex, nodePathInfo, mode = 'timeline', }) => {
|
|
266
268
|
const videoConfig = (0, remotion_1.useVideoConfig)();
|
|
267
269
|
const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
|
|
268
270
|
const setFrame = remotion_1.Internals.useTimelineSetFrame();
|
|
@@ -270,7 +272,7 @@ const TimelineKeyframeControls = ({ fieldKey, propStatus, nodePath, fileName, ke
|
|
|
270
272
|
const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
|
|
271
273
|
const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
|
|
272
274
|
const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
|
|
273
|
-
const { selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
|
|
275
|
+
const { selectedItems, selectItems } = (0, TimelineSelection_1.useTimelineSelection)();
|
|
274
276
|
const tracks = (0, TimelineKeyframeTracksContext_1.useTimelineKeyframeTracks)();
|
|
275
277
|
const clientId = previewServerState.type === 'connected'
|
|
276
278
|
? previewServerState.clientId
|
|
@@ -385,37 +387,65 @@ const TimelineKeyframeControls = ({ fieldKey, propStatus, nodePath, fileName, ke
|
|
|
385
387
|
return;
|
|
386
388
|
}
|
|
387
389
|
if (hasKeyframeAtCurrentFrame) {
|
|
388
|
-
const
|
|
390
|
+
const deleteTargets = keyframeToggleTargets.flatMap((target) => {
|
|
389
391
|
const change = getDeleteChange(target);
|
|
390
|
-
return change === null ? [] : [change];
|
|
392
|
+
return change === null ? [] : [{ target, change }];
|
|
391
393
|
});
|
|
394
|
+
const singleDeleteTarget = deleteTargets[0];
|
|
395
|
+
const easingSelection = deleteTargets.length === 1 &&
|
|
396
|
+
singleDeleteTarget &&
|
|
397
|
+
isKeyframedStatus(singleDeleteTarget.target.propStatus) &&
|
|
398
|
+
(0, update_selected_easing_1.canEditEasingForInterpolationFunction)(singleDeleteTarget.target.propStatus.interpolationFunction)
|
|
399
|
+
? (0, get_easing_selection_after_keyframe_delete_1.getEasingSelectionAfterKeyframeDelete)({
|
|
400
|
+
deletedSourceFrames: [singleDeleteTarget.target.sourceFrame],
|
|
401
|
+
keyframeDisplayOffset: singleDeleteTarget.target.keyframeDisplayOffset,
|
|
402
|
+
nodePathInfo: singleDeleteTarget.target.nodePathInfo,
|
|
403
|
+
propStatus: singleDeleteTarget.target.propStatus,
|
|
404
|
+
timelinePosition,
|
|
405
|
+
})
|
|
406
|
+
: null;
|
|
407
|
+
const deleteChanges = deleteTargets.map(({ change }) => change);
|
|
392
408
|
await (0, call_delete_keyframe_1.callDeleteKeyframes)({
|
|
393
409
|
sequenceKeyframes: deleteChanges.filter((change) => !hasEffectIndex(change)),
|
|
394
410
|
effectKeyframes: deleteChanges.filter((change) => hasEffectIndex(change)),
|
|
395
411
|
setPropStatuses,
|
|
396
412
|
clientId,
|
|
397
413
|
});
|
|
414
|
+
if (mode === 'timeline' && easingSelection !== null) {
|
|
415
|
+
selectItems([easingSelection], { reveal: true });
|
|
416
|
+
}
|
|
398
417
|
return;
|
|
399
418
|
}
|
|
400
419
|
const addChanges = keyframeToggleTargets.flatMap((target) => {
|
|
401
420
|
const change = getAddChange(target);
|
|
402
|
-
return change === null ? [] : [change];
|
|
421
|
+
return change === null ? [] : [{ target, change }];
|
|
403
422
|
});
|
|
404
423
|
if (addChanges.length === 0) {
|
|
405
424
|
return;
|
|
406
425
|
}
|
|
426
|
+
const addChangeValues = addChanges.map(({ change }) => change);
|
|
407
427
|
await (0, call_add_keyframe_1.callAddKeyframes)({
|
|
408
|
-
sequenceKeyframes:
|
|
409
|
-
effectKeyframes:
|
|
428
|
+
sequenceKeyframes: addChangeValues.filter((change) => !hasEffectIndex(change)),
|
|
429
|
+
effectKeyframes: addChangeValues.filter((change) => hasEffectIndex(change)),
|
|
410
430
|
setPropStatuses,
|
|
411
431
|
clientId,
|
|
412
432
|
});
|
|
433
|
+
if (mode === 'timeline') {
|
|
434
|
+
selectItems(addChanges.map(({ target }) => ({
|
|
435
|
+
type: 'keyframe',
|
|
436
|
+
nodePathInfo: target.nodePathInfo,
|
|
437
|
+
frame: target.sourceFrame + target.keyframeDisplayOffset,
|
|
438
|
+
})), { reveal: true });
|
|
439
|
+
}
|
|
413
440
|
}, [
|
|
414
441
|
canToggleKeyframe,
|
|
415
442
|
clientId,
|
|
416
443
|
hasKeyframeAtCurrentFrame,
|
|
417
444
|
keyframeToggleTargets,
|
|
445
|
+
mode,
|
|
446
|
+
selectItems,
|
|
418
447
|
setPropStatuses,
|
|
448
|
+
timelinePosition,
|
|
419
449
|
]);
|
|
420
450
|
const previousDisabled = previousDisplayFrame === null;
|
|
421
451
|
const nextDisabled = nextDisplayFrame === null;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
|
|
3
|
+
export declare const getTimelineKeyframeEasingLineStyle: (selected: boolean) => React.CSSProperties;
|
|
4
|
+
export declare const TimelineKeyframeEasingLineVisual: React.FC<{
|
|
5
|
+
readonly selected: boolean;
|
|
6
|
+
}>;
|
|
3
7
|
export declare const TimelineKeyframeEasingLine: React.NamedExoticComponent<{
|
|
4
8
|
readonly fromFrame: number;
|
|
5
9
|
readonly toFrame: number;
|
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.TimelineKeyframeEasingLine = void 0;
|
|
36
|
+
exports.TimelineKeyframeEasingLine = exports.TimelineKeyframeEasingLineVisual = exports.getTimelineKeyframeEasingLineStyle = void 0;
|
|
37
37
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
38
38
|
const studio_shared_1 = require("@remotion/studio-shared");
|
|
39
39
|
const react_1 = __importStar(require("react"));
|
|
@@ -67,6 +67,16 @@ const easingLine = {
|
|
|
67
67
|
top: '50%',
|
|
68
68
|
transform: 'translateY(-50%)',
|
|
69
69
|
};
|
|
70
|
+
const getTimelineKeyframeEasingLineStyle = (selected) => ({
|
|
71
|
+
...easingLine,
|
|
72
|
+
outline: selected ? `1px solid ${colors_1.BLUE}` : undefined,
|
|
73
|
+
});
|
|
74
|
+
exports.getTimelineKeyframeEasingLineStyle = getTimelineKeyframeEasingLineStyle;
|
|
75
|
+
const TimelineKeyframeEasingLineVisual = ({ selected }) => {
|
|
76
|
+
const lineStyle = (0, react_1.useMemo)(() => (0, exports.getTimelineKeyframeEasingLineStyle)(selected), [selected]);
|
|
77
|
+
return jsx_runtime_1.jsx("div", { style: lineStyle });
|
|
78
|
+
};
|
|
79
|
+
exports.TimelineKeyframeEasingLineVisual = TimelineKeyframeEasingLineVisual;
|
|
70
80
|
const TimelineKeyframeEasingLineUnmemoized = ({ fromFrame, toFrame, rowHeight, nodePathInfo, segmentIndex }) => {
|
|
71
81
|
const buttonRef = (0, react_1.useRef)(null);
|
|
72
82
|
const videoConfig = (0, remotion_1.useVideoConfig)();
|
|
@@ -176,10 +186,6 @@ const TimelineKeyframeEasingLineUnmemoized = ({ fromFrame, toFrame, rowHeight, n
|
|
|
176
186
|
toFrame,
|
|
177
187
|
videoConfig.durationInFrames,
|
|
178
188
|
]);
|
|
179
|
-
const lineStyle = (0, react_1.useMemo)(() => ({
|
|
180
|
-
...easingLine,
|
|
181
|
-
outline: selected ? `1px solid ${colors_1.BLUE}` : undefined,
|
|
182
|
-
}), [selected]);
|
|
183
189
|
const onPointerDown = (0, use_timeline_keyframe_drag_1.useTimelineEasingKeyframeDrag)({
|
|
184
190
|
onSelect,
|
|
185
191
|
selectable,
|
|
@@ -190,7 +196,7 @@ const TimelineKeyframeEasingLineUnmemoized = ({ fromFrame, toFrame, rowHeight, n
|
|
|
190
196
|
return null;
|
|
191
197
|
}
|
|
192
198
|
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
193
|
-
jsx_runtime_1.jsx("button", { ref: buttonRef, [TimelineSelection_1.TIMELINE_MARQUEE_ITEM_ATTR]: true, type: "button", style: style, title: `Easing from frame ${fromFrame} to ${toFrame}`, "aria-label": `Select easing from frame ${fromFrame} to ${toFrame}`, onPointerDown: selectable ? onPointerDown : undefined, children: jsx_runtime_1.jsx(
|
|
199
|
+
jsx_runtime_1.jsx("button", { ref: buttonRef, [TimelineSelection_1.TIMELINE_MARQUEE_ITEM_ATTR]: true, type: "button", style: style, title: `Easing from frame ${fromFrame} to ${toFrame}`, "aria-label": `Select easing from frame ${fromFrame} to ${toFrame}`, onPointerDown: selectable ? onPointerDown : undefined, children: jsx_runtime_1.jsx(exports.TimelineKeyframeEasingLineVisual, { selected: selected }) }), jsx_runtime_1.jsx(ContextMenu_1.ContextMenuForTarget, { triggerRef: buttonRef, values: contextMenuValues, onOpen: onOpenContextMenu })
|
|
194
200
|
] }));
|
|
195
201
|
};
|
|
196
202
|
exports.TimelineKeyframeEasingLine = react_1.default.memo(TimelineKeyframeEasingLineUnmemoized);
|
|
@@ -11,6 +11,7 @@ const valuesEqual = (left, right) => {
|
|
|
11
11
|
const TimelineKeyframedValue = ({ field, propStatus, sourceFrame, dragOverrideValue, onSave, onDragValueChange, onDragEnd, scaleLockNodePath, }) => {
|
|
12
12
|
const computedValue = (0, react_1.useMemo)(() => {
|
|
13
13
|
const raw = remotion_1.Internals.interpolateKeyframedStatus({
|
|
14
|
+
forceSpringAllowTail: false,
|
|
14
15
|
frame: sourceFrame,
|
|
15
16
|
status: propStatus,
|
|
16
17
|
});
|
|
@@ -51,13 +51,15 @@ const TimelineRowChrome = ({ depth, eye, keyframeControls, arrow, children, styl
|
|
|
51
51
|
e.stopPropagation();
|
|
52
52
|
onSelect();
|
|
53
53
|
}, [onSelect]);
|
|
54
|
-
const highlightBackground =
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
const highlightBackground = (0, TimelineSelection_1.getTimelineRowHighlightBackground)({
|
|
55
|
+
showSelectedBackground,
|
|
56
|
+
selected,
|
|
57
|
+
containsSelection,
|
|
58
|
+
});
|
|
57
59
|
const innerRowStyle = (0, react_1.useMemo)(() => ({
|
|
58
60
|
...rowBase,
|
|
59
61
|
...style,
|
|
60
|
-
backgroundColor: outerHeight ===
|
|
62
|
+
backgroundColor: outerHeight === null ? highlightBackground : undefined,
|
|
61
63
|
}), [style, outerHeight, highlightBackground]);
|
|
62
64
|
const outerStyle = (0, react_1.useMemo)(() => {
|
|
63
65
|
if (outerHeight === null) {
|
|
@@ -8,7 +8,12 @@ export declare const TIMELINE_SELECTED_LABEL_TEXT = "black";
|
|
|
8
8
|
export declare const TIMELINE_SELECTED_LABEL_HORIZONTAL_PADDING = 2;
|
|
9
9
|
export declare const getTimelineSelectedLabelStyle: (selected: boolean, subcategory: boolean) => CSSProperties;
|
|
10
10
|
export declare const getTimelineColor: (selected: boolean, subcategory: boolean) => "black" | "rgba(255, 255, 255, 0.8)";
|
|
11
|
-
export declare const getTimelineSelectedTrackHighlightStyle: (timelineWidth: number) => CSSProperties;
|
|
11
|
+
export declare const getTimelineSelectedTrackHighlightStyle: (timelineWidth: number, backgroundColor?: string) => CSSProperties;
|
|
12
|
+
export declare const getTimelineRowHighlightBackground: ({ showSelectedBackground, selected, containsSelection, }: {
|
|
13
|
+
readonly showSelectedBackground: boolean;
|
|
14
|
+
readonly selected: boolean;
|
|
15
|
+
readonly containsSelection: boolean;
|
|
16
|
+
}) => string | undefined;
|
|
12
17
|
export declare const TIMELINE_BACKGROUND = "#0F1113";
|
|
13
18
|
export declare const TIMELINE_TICKS_BACKGROUND = "rgb(31,36,40)";
|
|
14
19
|
export type TimelineSelection = {
|
|
@@ -204,4 +209,5 @@ export declare const useTimelineGuideSelection: (guideId: string) => {
|
|
|
204
209
|
selectionItem: TimelineSelection;
|
|
205
210
|
};
|
|
206
211
|
export declare const useTimelineRowContainsSelection: (nodePathInfo: SequenceNodePathInfo | null) => boolean;
|
|
212
|
+
export declare const useTimelineRowHighlightBackground: (nodePathInfo: SequenceNodePathInfo | null) => string | undefined;
|
|
207
213
|
export {};
|