@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
|
@@ -41,6 +41,7 @@ const colors_1 = require("../helpers/colors");
|
|
|
41
41
|
const ForceSpecificCursor_1 = require("./ForceSpecificCursor");
|
|
42
42
|
const selected_outline_drag_1 = require("./selected-outline-drag");
|
|
43
43
|
const selected_outline_measurement_1 = require("./selected-outline-measurement");
|
|
44
|
+
const selected_outline_measurement_2 = require("./selected-outline-measurement");
|
|
44
45
|
const selected_outline_uv_1 = require("./selected-outline-uv");
|
|
45
46
|
const call_add_keyframe_1 = require("./Timeline/call-add-keyframe");
|
|
46
47
|
const save_effect_prop_1 = require("./Timeline/save-effect-prop");
|
|
@@ -52,6 +53,7 @@ const getSvgPointFromPointerEvent = ({ event, rect, }) => {
|
|
|
52
53
|
};
|
|
53
54
|
const uvHandleRadius = 4.25;
|
|
54
55
|
const selectedUvHandleRadius = 6.8;
|
|
56
|
+
const ellipseControlRadius = 5.2;
|
|
55
57
|
const uvHandleStyle = {
|
|
56
58
|
filter: 'drop-shadow(0 1px 2px rgba(0, 0, 0, 0.28))',
|
|
57
59
|
};
|
|
@@ -69,7 +71,454 @@ const getSelectedOutlineUvHandleTimelineSelection = ({ effectIndex, fieldKey, no
|
|
|
69
71
|
exports.getSelectedOutlineUvHandleTimelineSelection = getSelectedOutlineUvHandleTimelineSelection;
|
|
70
72
|
const SelectedUvHandleConnectionLines = ({ handles, outline }) => {
|
|
71
73
|
const lines = (0, react_1.useMemo)(() => (0, selected_outline_uv_1.getUvHandleConnectionLines)({ handles, points: outline.points }), [handles, outline.points]);
|
|
72
|
-
|
|
74
|
+
const ellipses = (0, react_1.useMemo)(() => (0, selected_outline_uv_1.getUvHandleConnectionEllipses)({
|
|
75
|
+
handles,
|
|
76
|
+
dimensions: outline.dimensions,
|
|
77
|
+
points: outline.points,
|
|
78
|
+
}), [handles, outline.dimensions, outline.points]);
|
|
79
|
+
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [ellipses.map((ellipse) => (jsx_runtime_1.jsx("polyline", { points: ellipse.points
|
|
80
|
+
.map((point) => `${point.x},${point.y}`)
|
|
81
|
+
.join(' '), fill: "none", stroke: colors_1.BLUE, strokeWidth: 2, vectorEffect: "non-scaling-stroke", pointerEvents: "none" }, ellipse.key))), lines.map((line) => (jsx_runtime_1.jsx("line", { x1: line.from.x, y1: line.from.y, x2: line.to.x, y2: line.to.y, stroke: colors_1.BLUE, strokeWidth: 2, vectorEffect: "non-scaling-stroke", pointerEvents: "none" }, line.key)))] }));
|
|
82
|
+
};
|
|
83
|
+
const fieldDefaultToString = (value) => value !== undefined ? JSON.stringify(value) : null;
|
|
84
|
+
const shouldSaveNumericEffectValue = ({ defaultValue, field, value, }) => {
|
|
85
|
+
if (value === null) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
if (field.propStatus.status === 'keyframed') {
|
|
89
|
+
return field.value !== value;
|
|
90
|
+
}
|
|
91
|
+
const stringifiedValue = JSON.stringify(value);
|
|
92
|
+
return (field.propStatus.codeValue !== value &&
|
|
93
|
+
!(defaultValue === stringifiedValue &&
|
|
94
|
+
field.propStatus.codeValue === undefined));
|
|
95
|
+
};
|
|
96
|
+
const saveNumericEffectField = ({ clearEffectDragOverrides, clientId, effectIndex, field, lastValue, nodePath, schema, setPropStatuses, sourceFrame, }) => {
|
|
97
|
+
const defaultValue = fieldDefaultToString(field.fieldDefault);
|
|
98
|
+
if (!shouldSaveNumericEffectValue({
|
|
99
|
+
defaultValue,
|
|
100
|
+
field,
|
|
101
|
+
value: lastValue,
|
|
102
|
+
})) {
|
|
103
|
+
clearEffectDragOverrides(nodePath, effectIndex);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
(field.propStatus.status === 'keyframed'
|
|
107
|
+
? (0, call_add_keyframe_1.callAddEffectKeyframe)({
|
|
108
|
+
fileName: nodePath.absolutePath,
|
|
109
|
+
nodePath,
|
|
110
|
+
effectIndex,
|
|
111
|
+
fieldKey: field.fieldKey,
|
|
112
|
+
sourceFrame,
|
|
113
|
+
value: lastValue,
|
|
114
|
+
schema,
|
|
115
|
+
setPropStatuses,
|
|
116
|
+
clientId,
|
|
117
|
+
})
|
|
118
|
+
: (0, save_effect_prop_1.saveEffectProp)({
|
|
119
|
+
type: 'value',
|
|
120
|
+
fileName: nodePath.absolutePath,
|
|
121
|
+
nodePath,
|
|
122
|
+
effectIndex,
|
|
123
|
+
fieldKey: field.fieldKey,
|
|
124
|
+
value: lastValue,
|
|
125
|
+
defaultValue,
|
|
126
|
+
schema,
|
|
127
|
+
setPropStatuses,
|
|
128
|
+
clientId,
|
|
129
|
+
})).finally(() => {
|
|
130
|
+
clearEffectDragOverrides(nodePath, effectIndex);
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
const getLocalEllipseAxisValue = ({ axis, center, dimensions, point, rotation, }) => {
|
|
134
|
+
const radians = (rotation / 180) * Math.PI;
|
|
135
|
+
const deltaX = point[0] - center[0];
|
|
136
|
+
const deltaY = point[1] - center[1];
|
|
137
|
+
const axisX = axis === 'width' ? Math.cos(radians) : -Math.sin(radians);
|
|
138
|
+
const axisY = axis === 'width' ? Math.sin(radians) : Math.cos(radians);
|
|
139
|
+
if (dimensions !== null && dimensions.width > 0 && dimensions.height > 0) {
|
|
140
|
+
const pixelDeltaX = deltaX * dimensions.width;
|
|
141
|
+
const pixelDeltaY = deltaY * dimensions.height;
|
|
142
|
+
const pixelAxisValue = pixelDeltaX * axisX + pixelDeltaY * axisY;
|
|
143
|
+
return (pixelAxisValue / (axis === 'width' ? dimensions.width : dimensions.height));
|
|
144
|
+
}
|
|
145
|
+
return deltaX * axisX + deltaY * axisY;
|
|
146
|
+
};
|
|
147
|
+
const getLocalEllipseWidthProgress = ({ center, dimensions, point, rotation, width, }) => {
|
|
148
|
+
if (width <= 0.000001) {
|
|
149
|
+
return 0;
|
|
150
|
+
}
|
|
151
|
+
return (getLocalEllipseAxisValue({
|
|
152
|
+
axis: 'width',
|
|
153
|
+
center,
|
|
154
|
+
dimensions,
|
|
155
|
+
point,
|
|
156
|
+
rotation,
|
|
157
|
+
}) /
|
|
158
|
+
(width / 2));
|
|
159
|
+
};
|
|
160
|
+
const SelectedUvEllipseStartHandle = ({ control, onDraggingChange, outline }) => {
|
|
161
|
+
const { setEffectDragOverrides, clearEffectDragOverrides, setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
|
|
162
|
+
const { startControl } = control;
|
|
163
|
+
const field = startControl === null || startControl === void 0 ? void 0 : startControl.field;
|
|
164
|
+
const onPointerDown = react_1.default.useCallback((event) => {
|
|
165
|
+
if (startControl === null || field === undefined) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (event.button !== 0) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
event.preventDefault();
|
|
172
|
+
event.stopPropagation();
|
|
173
|
+
const svg = event.currentTarget.ownerSVGElement;
|
|
174
|
+
if (svg === null) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const svgRect = svg.getBoundingClientRect();
|
|
178
|
+
const startPointerX = event.clientX;
|
|
179
|
+
const startPointerY = event.clientY;
|
|
180
|
+
let dragging = false;
|
|
181
|
+
let lastValue = null;
|
|
182
|
+
const updateFromPointerEvent = (pointerEvent) => {
|
|
183
|
+
const point = getSvgPointFromPointerEvent({
|
|
184
|
+
event: pointerEvent,
|
|
185
|
+
rect: svgRect,
|
|
186
|
+
});
|
|
187
|
+
const uv = (0, selected_outline_uv_1.getUvCoordinateForPoint)(outline.points, point);
|
|
188
|
+
const nextValue = (0, selected_outline_uv_1.roundNumericUvEllipseValue)(getLocalEllipseWidthProgress({
|
|
189
|
+
center: control.handle.value,
|
|
190
|
+
dimensions: outline.dimensions,
|
|
191
|
+
point: uv,
|
|
192
|
+
rotation: control.rotation,
|
|
193
|
+
width: control.width,
|
|
194
|
+
}), field.fieldSchema);
|
|
195
|
+
lastValue = nextValue;
|
|
196
|
+
setEffectDragOverrides(control.handle.nodePath, control.handle.effectIndex, field.fieldKey, field.propStatus.status === 'keyframed'
|
|
197
|
+
? remotion_1.Internals.makeKeyframedDragOverride({
|
|
198
|
+
status: field.propStatus,
|
|
199
|
+
frame: control.handle.sourceFrame,
|
|
200
|
+
value: nextValue,
|
|
201
|
+
})
|
|
202
|
+
: remotion_1.Internals.makeStaticDragOverride(nextValue));
|
|
203
|
+
};
|
|
204
|
+
const onPointerMove = (moveEvent) => {
|
|
205
|
+
moveEvent.preventDefault();
|
|
206
|
+
const deltaX = moveEvent.clientX - startPointerX;
|
|
207
|
+
const deltaY = moveEvent.clientY - startPointerY;
|
|
208
|
+
if (!dragging) {
|
|
209
|
+
if (!(0, selected_outline_drag_1.isSelectedOutlineDragPastThreshold)({ deltaX, deltaY })) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
dragging = true;
|
|
213
|
+
(0, ForceSpecificCursor_1.forceSpecificCursor)(startControl.cursor);
|
|
214
|
+
onDraggingChange(true);
|
|
215
|
+
}
|
|
216
|
+
updateFromPointerEvent(moveEvent);
|
|
217
|
+
};
|
|
218
|
+
const onPointerUp = () => {
|
|
219
|
+
window.removeEventListener('pointermove', onPointerMove);
|
|
220
|
+
window.removeEventListener('pointerup', onPointerUp);
|
|
221
|
+
window.removeEventListener('pointercancel', onPointerUp);
|
|
222
|
+
if (dragging) {
|
|
223
|
+
(0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
|
|
224
|
+
onDraggingChange(false);
|
|
225
|
+
}
|
|
226
|
+
saveNumericEffectField({
|
|
227
|
+
clearEffectDragOverrides,
|
|
228
|
+
clientId: control.handle.clientId,
|
|
229
|
+
effectIndex: control.handle.effectIndex,
|
|
230
|
+
field,
|
|
231
|
+
lastValue,
|
|
232
|
+
nodePath: control.handle.nodePath,
|
|
233
|
+
schema: control.handle.schema,
|
|
234
|
+
setPropStatuses,
|
|
235
|
+
sourceFrame: control.handle.sourceFrame,
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
window.addEventListener('pointermove', onPointerMove);
|
|
239
|
+
window.addEventListener('pointerup', onPointerUp);
|
|
240
|
+
window.addEventListener('pointercancel', onPointerUp);
|
|
241
|
+
}, [
|
|
242
|
+
clearEffectDragOverrides,
|
|
243
|
+
control.handle,
|
|
244
|
+
control.rotation,
|
|
245
|
+
control.width,
|
|
246
|
+
field,
|
|
247
|
+
onDraggingChange,
|
|
248
|
+
outline.dimensions,
|
|
249
|
+
outline.points,
|
|
250
|
+
setEffectDragOverrides,
|
|
251
|
+
setPropStatuses,
|
|
252
|
+
startControl,
|
|
253
|
+
]);
|
|
254
|
+
if (startControl === null || field === undefined) {
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
return (jsx_runtime_1.jsx("circle", { cx: startControl.position.x, cy: startControl.position.y, r: ellipseControlRadius, fill: "white", stroke: colors_1.BLUE, strokeWidth: 2, style: uvHandleStyle, vectorEffect: "non-scaling-stroke", pointerEvents: "all", cursor: startControl.cursor, onPointerDown: onPointerDown }));
|
|
258
|
+
};
|
|
259
|
+
const SelectedUvEllipseResizeHandle = ({ axis, control, onDraggingChange, outline }) => {
|
|
260
|
+
const { setEffectDragOverrides, clearEffectDragOverrides, setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
|
|
261
|
+
const resizeControl = control.resize.find((item) => item.axis === axis);
|
|
262
|
+
const field = resizeControl === null || resizeControl === void 0 ? void 0 : resizeControl.field;
|
|
263
|
+
const onPointerDown = react_1.default.useCallback((event) => {
|
|
264
|
+
if (resizeControl === undefined || field === undefined) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (event.button !== 0) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
event.preventDefault();
|
|
271
|
+
event.stopPropagation();
|
|
272
|
+
const svg = event.currentTarget.ownerSVGElement;
|
|
273
|
+
if (svg === null) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const svgRect = svg.getBoundingClientRect();
|
|
277
|
+
const startPointerX = event.clientX;
|
|
278
|
+
const startPointerY = event.clientY;
|
|
279
|
+
let dragging = false;
|
|
280
|
+
let lastValue = null;
|
|
281
|
+
const updateFromPointerEvent = (pointerEvent) => {
|
|
282
|
+
const point = getSvgPointFromPointerEvent({
|
|
283
|
+
event: pointerEvent,
|
|
284
|
+
rect: svgRect,
|
|
285
|
+
});
|
|
286
|
+
const uv = (0, selected_outline_uv_1.getUvCoordinateForPoint)(outline.points, point);
|
|
287
|
+
const axisValue = getLocalEllipseAxisValue({
|
|
288
|
+
axis,
|
|
289
|
+
center: control.handle.value,
|
|
290
|
+
dimensions: outline.dimensions,
|
|
291
|
+
point: uv,
|
|
292
|
+
rotation: control.rotation,
|
|
293
|
+
});
|
|
294
|
+
const nextValue = (0, selected_outline_uv_1.roundNumericUvEllipseValue)(Math.max(0, axisValue * 2), field.fieldSchema);
|
|
295
|
+
lastValue = nextValue;
|
|
296
|
+
setEffectDragOverrides(control.handle.nodePath, control.handle.effectIndex, field.fieldKey, field.propStatus.status === 'keyframed'
|
|
297
|
+
? remotion_1.Internals.makeKeyframedDragOverride({
|
|
298
|
+
status: field.propStatus,
|
|
299
|
+
frame: control.handle.sourceFrame,
|
|
300
|
+
value: nextValue,
|
|
301
|
+
})
|
|
302
|
+
: remotion_1.Internals.makeStaticDragOverride(nextValue));
|
|
303
|
+
};
|
|
304
|
+
const onPointerMove = (moveEvent) => {
|
|
305
|
+
moveEvent.preventDefault();
|
|
306
|
+
const deltaX = moveEvent.clientX - startPointerX;
|
|
307
|
+
const deltaY = moveEvent.clientY - startPointerY;
|
|
308
|
+
if (!dragging) {
|
|
309
|
+
if (!(0, selected_outline_drag_1.isSelectedOutlineDragPastThreshold)({ deltaX, deltaY })) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
dragging = true;
|
|
313
|
+
(0, ForceSpecificCursor_1.forceSpecificCursor)(resizeControl.cursor);
|
|
314
|
+
onDraggingChange(true);
|
|
315
|
+
}
|
|
316
|
+
updateFromPointerEvent(moveEvent);
|
|
317
|
+
};
|
|
318
|
+
const onPointerUp = () => {
|
|
319
|
+
window.removeEventListener('pointermove', onPointerMove);
|
|
320
|
+
window.removeEventListener('pointerup', onPointerUp);
|
|
321
|
+
window.removeEventListener('pointercancel', onPointerUp);
|
|
322
|
+
if (dragging) {
|
|
323
|
+
(0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
|
|
324
|
+
onDraggingChange(false);
|
|
325
|
+
}
|
|
326
|
+
saveNumericEffectField({
|
|
327
|
+
clearEffectDragOverrides,
|
|
328
|
+
clientId: control.handle.clientId,
|
|
329
|
+
effectIndex: control.handle.effectIndex,
|
|
330
|
+
field,
|
|
331
|
+
lastValue,
|
|
332
|
+
nodePath: control.handle.nodePath,
|
|
333
|
+
schema: control.handle.schema,
|
|
334
|
+
setPropStatuses,
|
|
335
|
+
sourceFrame: control.handle.sourceFrame,
|
|
336
|
+
});
|
|
337
|
+
};
|
|
338
|
+
window.addEventListener('pointermove', onPointerMove);
|
|
339
|
+
window.addEventListener('pointerup', onPointerUp);
|
|
340
|
+
window.addEventListener('pointercancel', onPointerUp);
|
|
341
|
+
}, [
|
|
342
|
+
axis,
|
|
343
|
+
clearEffectDragOverrides,
|
|
344
|
+
control.handle,
|
|
345
|
+
control.rotation,
|
|
346
|
+
field,
|
|
347
|
+
onDraggingChange,
|
|
348
|
+
outline.dimensions,
|
|
349
|
+
outline.points,
|
|
350
|
+
resizeControl,
|
|
351
|
+
setEffectDragOverrides,
|
|
352
|
+
setPropStatuses,
|
|
353
|
+
]);
|
|
354
|
+
if (resizeControl === undefined || field === undefined) {
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
return (jsx_runtime_1.jsx("circle", { cx: resizeControl.position.x, cy: resizeControl.position.y, r: ellipseControlRadius, fill: "white", stroke: colors_1.BLUE, strokeWidth: 2, style: uvHandleStyle, vectorEffect: "non-scaling-stroke", pointerEvents: "all", cursor: resizeControl.cursor, onPointerDown: onPointerDown }));
|
|
358
|
+
};
|
|
359
|
+
const snapRotationDegrees = (value) => Math.round(value / selected_outline_drag_1.selectedOutlineRotationSnapStepDegrees) *
|
|
360
|
+
selected_outline_drag_1.selectedOutlineRotationSnapStepDegrees;
|
|
361
|
+
const trimLineToCircleEdges = ({ from, fromRadius, to, toRadius, }) => {
|
|
362
|
+
const deltaX = to.x - from.x;
|
|
363
|
+
const deltaY = to.y - from.y;
|
|
364
|
+
const distance = Math.hypot(deltaX, deltaY);
|
|
365
|
+
if (distance <= fromRadius + toRadius || distance <= 0.000001) {
|
|
366
|
+
const middle = {
|
|
367
|
+
x: (from.x + to.x) / 2,
|
|
368
|
+
y: (from.y + to.y) / 2,
|
|
369
|
+
};
|
|
370
|
+
return { from: middle, to: middle };
|
|
371
|
+
}
|
|
372
|
+
const unitX = deltaX / distance;
|
|
373
|
+
const unitY = deltaY / distance;
|
|
374
|
+
return {
|
|
375
|
+
from: {
|
|
376
|
+
x: from.x + unitX * fromRadius,
|
|
377
|
+
y: from.y + unitY * fromRadius,
|
|
378
|
+
},
|
|
379
|
+
to: {
|
|
380
|
+
x: to.x - unitX * toRadius,
|
|
381
|
+
y: to.y - unitY * toRadius,
|
|
382
|
+
},
|
|
383
|
+
};
|
|
384
|
+
};
|
|
385
|
+
const SelectedUvEllipseRotationHandle = ({ control, onDraggingChange }) => {
|
|
386
|
+
const { setEffectDragOverrides, clearEffectDragOverrides, setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
|
|
387
|
+
const { rotationControl } = control;
|
|
388
|
+
const field = rotationControl === null || rotationControl === void 0 ? void 0 : rotationControl.field;
|
|
389
|
+
const onPointerDown = react_1.default.useCallback((event) => {
|
|
390
|
+
if (rotationControl === null || field === undefined) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
if (event.button !== 0) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
event.preventDefault();
|
|
397
|
+
event.stopPropagation();
|
|
398
|
+
const svg = event.currentTarget.ownerSVGElement;
|
|
399
|
+
if (svg === null) {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
const svgRect = svg.getBoundingClientRect();
|
|
403
|
+
const { center } = control;
|
|
404
|
+
const startPointer = { x: event.clientX, y: event.clientY };
|
|
405
|
+
let previousAngle = (0, selected_outline_measurement_2.getAngleDegrees)(center, {
|
|
406
|
+
x: event.clientX - svgRect.left,
|
|
407
|
+
y: event.clientY - svgRect.top,
|
|
408
|
+
});
|
|
409
|
+
const startCursorDegrees = previousAngle;
|
|
410
|
+
let accumulatedDelta = 0;
|
|
411
|
+
let rotationLocked = event.shiftKey;
|
|
412
|
+
let dragging = false;
|
|
413
|
+
let lastValue = null;
|
|
414
|
+
const updateRotationDragOverride = () => {
|
|
415
|
+
const rawValue = control.rotation + accumulatedDelta;
|
|
416
|
+
const snappedValue = rotationLocked
|
|
417
|
+
? snapRotationDegrees(rawValue)
|
|
418
|
+
: rawValue;
|
|
419
|
+
const nextValue = (0, selected_outline_uv_1.roundNumericUvEllipseValue)(snappedValue, field.fieldSchema);
|
|
420
|
+
const cursorDelta = (0, selected_outline_measurement_2.getSelectedOutlineRotationDeltaDegrees)({
|
|
421
|
+
from: control.rotation,
|
|
422
|
+
to: nextValue,
|
|
423
|
+
});
|
|
424
|
+
lastValue = nextValue;
|
|
425
|
+
(0, ForceSpecificCursor_1.forceSpecificCursor)((0, selected_outline_measurement_2.getRotationCursor)(startCursorDegrees + cursorDelta));
|
|
426
|
+
setEffectDragOverrides(control.handle.nodePath, control.handle.effectIndex, field.fieldKey, field.propStatus.status === 'keyframed'
|
|
427
|
+
? remotion_1.Internals.makeKeyframedDragOverride({
|
|
428
|
+
status: field.propStatus,
|
|
429
|
+
frame: control.handle.sourceFrame,
|
|
430
|
+
value: nextValue,
|
|
431
|
+
})
|
|
432
|
+
: remotion_1.Internals.makeStaticDragOverride(nextValue));
|
|
433
|
+
};
|
|
434
|
+
const onPointerMove = (moveEvent) => {
|
|
435
|
+
moveEvent.preventDefault();
|
|
436
|
+
const deltaX = moveEvent.clientX - startPointer.x;
|
|
437
|
+
const deltaY = moveEvent.clientY - startPointer.y;
|
|
438
|
+
if (!dragging) {
|
|
439
|
+
if (!(0, selected_outline_drag_1.isSelectedOutlineDragPastThreshold)({ deltaX, deltaY })) {
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
dragging = true;
|
|
443
|
+
onDraggingChange(true);
|
|
444
|
+
}
|
|
445
|
+
const nextAngle = (0, selected_outline_measurement_2.getAngleDegrees)(center, {
|
|
446
|
+
x: moveEvent.clientX - svgRect.left,
|
|
447
|
+
y: moveEvent.clientY - svgRect.top,
|
|
448
|
+
});
|
|
449
|
+
accumulatedDelta += (0, selected_outline_measurement_2.getSelectedOutlineRotationDeltaDegrees)({
|
|
450
|
+
from: previousAngle,
|
|
451
|
+
to: nextAngle,
|
|
452
|
+
});
|
|
453
|
+
previousAngle = nextAngle;
|
|
454
|
+
rotationLocked = moveEvent.shiftKey;
|
|
455
|
+
updateRotationDragOverride();
|
|
456
|
+
};
|
|
457
|
+
const onKeyChange = (keyEvent) => {
|
|
458
|
+
if (keyEvent.key !== 'Shift') {
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
const nextRotationLocked = keyEvent.type === 'keydown';
|
|
462
|
+
if (nextRotationLocked === rotationLocked) {
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
rotationLocked = nextRotationLocked;
|
|
466
|
+
if (dragging) {
|
|
467
|
+
updateRotationDragOverride();
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
const onPointerUp = () => {
|
|
471
|
+
window.removeEventListener('pointermove', onPointerMove);
|
|
472
|
+
window.removeEventListener('pointerup', onPointerUp);
|
|
473
|
+
window.removeEventListener('pointercancel', onPointerUp);
|
|
474
|
+
window.removeEventListener('keydown', onKeyChange);
|
|
475
|
+
window.removeEventListener('keyup', onKeyChange);
|
|
476
|
+
if (dragging) {
|
|
477
|
+
(0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
|
|
478
|
+
onDraggingChange(false);
|
|
479
|
+
}
|
|
480
|
+
saveNumericEffectField({
|
|
481
|
+
clearEffectDragOverrides,
|
|
482
|
+
clientId: control.handle.clientId,
|
|
483
|
+
effectIndex: control.handle.effectIndex,
|
|
484
|
+
field,
|
|
485
|
+
lastValue,
|
|
486
|
+
nodePath: control.handle.nodePath,
|
|
487
|
+
schema: control.handle.schema,
|
|
488
|
+
setPropStatuses,
|
|
489
|
+
sourceFrame: control.handle.sourceFrame,
|
|
490
|
+
});
|
|
491
|
+
};
|
|
492
|
+
window.addEventListener('pointermove', onPointerMove);
|
|
493
|
+
window.addEventListener('pointerup', onPointerUp);
|
|
494
|
+
window.addEventListener('pointercancel', onPointerUp);
|
|
495
|
+
window.addEventListener('keydown', onKeyChange);
|
|
496
|
+
window.addEventListener('keyup', onKeyChange);
|
|
497
|
+
}, [
|
|
498
|
+
clearEffectDragOverrides,
|
|
499
|
+
control,
|
|
500
|
+
field,
|
|
501
|
+
onDraggingChange,
|
|
502
|
+
rotationControl,
|
|
503
|
+
setEffectDragOverrides,
|
|
504
|
+
setPropStatuses,
|
|
505
|
+
]);
|
|
506
|
+
if (rotationControl === null || field === undefined) {
|
|
507
|
+
return null;
|
|
508
|
+
}
|
|
509
|
+
const heightControl = control.resize.find((item) => item.axis === 'height');
|
|
510
|
+
if (heightControl === undefined) {
|
|
511
|
+
return null;
|
|
512
|
+
}
|
|
513
|
+
const connector = trimLineToCircleEdges({
|
|
514
|
+
from: heightControl.position,
|
|
515
|
+
fromRadius: ellipseControlRadius,
|
|
516
|
+
to: rotationControl.position,
|
|
517
|
+
toRadius: ellipseControlRadius,
|
|
518
|
+
});
|
|
519
|
+
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
520
|
+
jsx_runtime_1.jsx("line", { x1: connector.from.x, y1: connector.from.y, x2: connector.to.x, y2: connector.to.y, stroke: colors_1.BLUE, strokeWidth: 2, vectorEffect: "non-scaling-stroke", pointerEvents: "none" }), jsx_runtime_1.jsx("circle", { cx: rotationControl.position.x, cy: rotationControl.position.y, r: ellipseControlRadius, fill: "white", stroke: colors_1.BLUE, strokeWidth: 2, style: uvHandleStyle, vectorEffect: "non-scaling-stroke", pointerEvents: "all", cursor: (0, selected_outline_measurement_2.getRotationCursor)((0, selected_outline_measurement_2.getAngleDegrees)(control.center, rotationControl.position)), onPointerDown: onPointerDown })
|
|
521
|
+
] }));
|
|
73
522
|
};
|
|
74
523
|
const SelectedUvHandleCircle = ({ handle, nodePathInfo, onDraggingChange, onSelect, outline }) => {
|
|
75
524
|
const { setEffectDragOverrides, clearEffectDragOverrides, setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
|
|
@@ -213,9 +662,19 @@ const SelectedOutlineUvHandleConnectionLayer = ({ outline, target }) => {
|
|
|
213
662
|
};
|
|
214
663
|
exports.SelectedOutlineUvHandleConnectionLayer = SelectedOutlineUvHandleConnectionLayer;
|
|
215
664
|
const SelectedOutlineUvHandleCircleLayer = ({ onDraggingChange, onSelect, outline, target }) => {
|
|
665
|
+
const ellipseControls = (0, react_1.useMemo)(() => {
|
|
666
|
+
var _a;
|
|
667
|
+
return (0, selected_outline_uv_1.getUvEllipseInteractiveControls)({
|
|
668
|
+
handles: (_a = target === null || target === void 0 ? void 0 : target.uvHandles) !== null && _a !== void 0 ? _a : [],
|
|
669
|
+
dimensions: outline.dimensions,
|
|
670
|
+
points: outline.points,
|
|
671
|
+
});
|
|
672
|
+
}, [outline.dimensions, outline.points, target === null || target === void 0 ? void 0 : target.uvHandles]);
|
|
216
673
|
if (!(target === null || target === void 0 ? void 0 : target.containsSelection) || target.uvHandles.length === 0) {
|
|
217
674
|
return null;
|
|
218
675
|
}
|
|
219
|
-
return (jsx_runtime_1.
|
|
676
|
+
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [ellipseControls.map((control) => (jsx_runtime_1.jsxs(react_1.default.Fragment, { children: [
|
|
677
|
+
jsx_runtime_1.jsx(SelectedUvEllipseStartHandle, { control: control, onDraggingChange: onDraggingChange, outline: outline }), jsx_runtime_1.jsx(SelectedUvEllipseResizeHandle, { axis: "width", control: control, onDraggingChange: onDraggingChange, outline: outline }), jsx_runtime_1.jsx(SelectedUvEllipseResizeHandle, { axis: "height", control: control, onDraggingChange: onDraggingChange, outline: outline }), jsx_runtime_1.jsx(SelectedUvEllipseRotationHandle, { control: control, onDraggingChange: onDraggingChange })
|
|
678
|
+
] }, `${control.handle.effectIndex}-${control.handle.fieldKey}-ellipse-controls`))), target.uvHandles.map((handle) => (jsx_runtime_1.jsx(SelectedUvHandleCircle, { handle: handle, nodePathInfo: target.nodePathInfo, onDraggingChange: onDraggingChange, onSelect: onSelect, outline: outline }, `${handle.effectIndex}-${handle.fieldKey}`)))] }));
|
|
220
679
|
};
|
|
221
680
|
exports.SelectedOutlineUvHandleCircleLayer = SelectedOutlineUvHandleCircleLayer;
|