@remotion/studio 4.0.486 → 4.0.487
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/ContextMenu.js +2 -1
- package/dist/components/CurrentComposition.js +43 -2
- package/dist/components/EditorContexts.js +2 -1
- package/dist/components/GlobalKeybindings.js +19 -0
- package/dist/components/InspectorSourceLocation.d.ts +1 -0
- package/dist/components/InspectorSourceLocation.js +18 -3
- package/dist/components/KeyboardShortcutsExplainer.js +4 -0
- package/dist/components/Preview.js +1 -1
- package/dist/components/PreviewToolbar.js +2 -1
- package/dist/components/RenderButton.js +1 -0
- package/dist/components/RenderModal/OptionExplainer.d.ts +11 -1
- package/dist/components/RenderModal/OptionExplainer.js +31 -11
- package/dist/components/RenderModal/OptionExplainerBubble.d.ts +15 -1
- package/dist/components/RenderModal/OptionExplainerBubble.js +17 -3
- package/dist/components/RenderModal/SchemaEditor/Fieldset.d.ts +1 -0
- package/dist/components/RenderModal/SchemaEditor/Fieldset.js +6 -1
- package/dist/components/RenderModal/SchemaEditor/SchemaEditor.js +1 -2
- package/dist/components/RenderModal/WebRenderModal.js +5 -2
- package/dist/components/RenderModal/WebRenderModalAdvanced.d.ts +3 -0
- package/dist/components/RenderModal/WebRenderModalAdvanced.js +92 -5
- package/dist/components/RenderModal/WebRenderModalBasic.js +2 -2
- package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +1 -0
- package/dist/components/RenderQueue/client-side-render-types.d.ts +2 -1
- package/dist/components/SelectedOutlineElement.d.ts +4 -0
- package/dist/components/SelectedOutlineElement.js +56 -11
- package/dist/components/SelectedOutlineOverlay.d.ts +2 -0
- package/dist/components/SelectedOutlineOverlay.js +53 -2
- package/dist/components/SelectedOutlineUvControls.js +13 -6
- package/dist/components/SnappingProvider.d.ts +4 -0
- package/dist/components/SnappingProvider.js +24 -0
- package/dist/components/SnappingToggle.d.ts +2 -0
- package/dist/components/SnappingToggle.js +26 -0
- package/dist/components/Splitter/SplitterContext.d.ts +1 -1
- package/dist/components/Timeline/TimelineSelection.js +5 -0
- package/dist/components/VisualControls/ClickableFileName.js +2 -2
- package/dist/components/VisualControls/VisualControlsContent.js +9 -1
- package/dist/components/effect-drag-and-drop.js +30 -9
- package/dist/components/import-assets.d.ts +1 -1
- package/dist/components/options-sidebar-tabs.d.ts +1 -0
- package/dist/components/options-sidebar-tabs.js +6 -1
- package/dist/components/selected-outline-snap.d.ts +36 -0
- package/dist/components/selected-outline-snap.js +158 -0
- package/dist/esm/{chunk-975rp13y.js → chunk-y2t24cx0.js} +4776 -3933
- package/dist/esm/internals.mjs +4776 -3933
- package/dist/esm/previewEntry.mjs +5095 -4252
- package/dist/esm/renderEntry.mjs +1 -1
- package/dist/helpers/retry-payload.js +1 -0
- package/dist/helpers/use-menu-structure.js +43 -2
- package/dist/icons/magnet.d.ts +3 -0
- package/dist/icons/magnet.js +8 -0
- package/dist/icons/react.d.ts +5 -0
- package/dist/icons/react.js +8 -0
- package/dist/state/editor-guides.d.ts +2 -2
- package/dist/state/editor-snapping.d.ts +8 -0
- package/dist/state/editor-snapping.js +18 -0
- package/dist/state/modals.d.ts +2 -1
- package/package.json +12 -12
|
@@ -13,7 +13,24 @@ const OptionExplainerBubble_1 = require("./OptionExplainerBubble");
|
|
|
13
13
|
const tabContainer = {
|
|
14
14
|
flex: 1,
|
|
15
15
|
};
|
|
16
|
-
const
|
|
16
|
+
const paragraph = {
|
|
17
|
+
margin: 0,
|
|
18
|
+
marginBottom: 8,
|
|
19
|
+
};
|
|
20
|
+
const lastParagraph = {
|
|
21
|
+
margin: 0,
|
|
22
|
+
};
|
|
23
|
+
const PageResponsivenessDescription = () => {
|
|
24
|
+
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
25
|
+
jsx_runtime_1.jsx("p", { style: paragraph, children: "The Web Renderer runs in the same browser tab as the Studio. Rendering can block the tab while Remotion captures frames." }), jsx_runtime_1.jsxs("p", { style: paragraph, children: ["The default is ",
|
|
26
|
+
jsx_runtime_1.jsx("code", { children: "Medium" }),
|
|
27
|
+
", which tries to free the event loop every 33ms of rendering work so progress updates and UI interactions can stay responsive."] }), jsx_runtime_1.jsxs("p", { style: lastParagraph, children: ["Choose ",
|
|
28
|
+
jsx_runtime_1.jsx("code", { children: "Disabled" }),
|
|
29
|
+
" to prioritize render speed, or", ' ', jsx_runtime_1.jsx("code", { children: "High" }),
|
|
30
|
+
" to give the browser more chances to update."] })
|
|
31
|
+
] }));
|
|
32
|
+
};
|
|
33
|
+
const WebRenderModalAdvanced = ({ renderMode, delayRenderTimeout, setDelayRenderTimeout, mediaCacheSizeInBytes, setMediaCacheSizeInBytes, hardwareAcceleration, setHardwareAcceleration, allowHtmlInCanvas, setAllowHtmlInCanvas, pageResponsiveness, setPageResponsiveness, }) => {
|
|
17
34
|
const toggleCustomMediaCacheSizeInBytes = (0, react_1.useCallback)(() => {
|
|
18
35
|
setMediaCacheSizeInBytes((previous) => {
|
|
19
36
|
if (previous === null) {
|
|
@@ -73,18 +90,88 @@ const WebRenderModalAdvanced = ({ renderMode, delayRenderTimeout, setDelayRender
|
|
|
73
90
|
},
|
|
74
91
|
];
|
|
75
92
|
}, [hardwareAcceleration, setHardwareAcceleration]);
|
|
93
|
+
const selectedPageResponsiveness = typeof pageResponsiveness === 'number' ? 'custom' : pageResponsiveness;
|
|
94
|
+
const pageResponsivenessOptions = (0, react_1.useMemo)(() => {
|
|
95
|
+
return [
|
|
96
|
+
{
|
|
97
|
+
label: 'Disabled',
|
|
98
|
+
onClick: () => setPageResponsiveness('disabled'),
|
|
99
|
+
leftItem: selectedPageResponsiveness === 'disabled' ? jsx_runtime_1.jsx(Checkmark_1.Checkmark, {}) : null,
|
|
100
|
+
id: 'disabled',
|
|
101
|
+
keyHint: null,
|
|
102
|
+
quickSwitcherLabel: null,
|
|
103
|
+
subMenu: null,
|
|
104
|
+
type: 'item',
|
|
105
|
+
value: 'disabled',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
label: 'Low (100ms)',
|
|
109
|
+
onClick: () => setPageResponsiveness('low'),
|
|
110
|
+
leftItem: selectedPageResponsiveness === 'low' ? jsx_runtime_1.jsx(Checkmark_1.Checkmark, {}) : null,
|
|
111
|
+
id: 'low',
|
|
112
|
+
keyHint: null,
|
|
113
|
+
quickSwitcherLabel: null,
|
|
114
|
+
subMenu: null,
|
|
115
|
+
type: 'item',
|
|
116
|
+
value: 'low',
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
label: 'Medium (33ms)',
|
|
120
|
+
onClick: () => setPageResponsiveness('medium'),
|
|
121
|
+
leftItem: selectedPageResponsiveness === 'medium' ? jsx_runtime_1.jsx(Checkmark_1.Checkmark, {}) : null,
|
|
122
|
+
id: 'medium',
|
|
123
|
+
keyHint: null,
|
|
124
|
+
quickSwitcherLabel: null,
|
|
125
|
+
subMenu: null,
|
|
126
|
+
type: 'item',
|
|
127
|
+
value: 'medium',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
label: 'High (16ms)',
|
|
131
|
+
onClick: () => setPageResponsiveness('high'),
|
|
132
|
+
leftItem: selectedPageResponsiveness === 'high' ? jsx_runtime_1.jsx(Checkmark_1.Checkmark, {}) : null,
|
|
133
|
+
id: 'high',
|
|
134
|
+
keyHint: null,
|
|
135
|
+
quickSwitcherLabel: null,
|
|
136
|
+
subMenu: null,
|
|
137
|
+
type: 'item',
|
|
138
|
+
value: 'high',
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
label: 'Custom',
|
|
142
|
+
onClick: () => setPageResponsiveness((previous) => typeof previous === 'number' ? previous : 33),
|
|
143
|
+
leftItem: selectedPageResponsiveness === 'custom' ? jsx_runtime_1.jsx(Checkmark_1.Checkmark, {}) : null,
|
|
144
|
+
id: 'custom',
|
|
145
|
+
keyHint: null,
|
|
146
|
+
quickSwitcherLabel: null,
|
|
147
|
+
subMenu: null,
|
|
148
|
+
type: 'item',
|
|
149
|
+
value: 'custom',
|
|
150
|
+
},
|
|
151
|
+
];
|
|
152
|
+
}, [selectedPageResponsiveness, setPageResponsiveness]);
|
|
153
|
+
const setCustomPageResponsiveness = (0, react_1.useCallback)((value) => {
|
|
154
|
+
setPageResponsiveness((previous) => {
|
|
155
|
+
const currentValue = typeof previous === 'number' ? previous : 33;
|
|
156
|
+
return typeof value === 'function' ? value(currentValue) : value;
|
|
157
|
+
});
|
|
158
|
+
}, [setPageResponsiveness]);
|
|
76
159
|
return (jsx_runtime_1.jsxs("div", { style: tabContainer, children: [
|
|
77
160
|
jsx_runtime_1.jsx(NumberSetting_1.NumberSetting, { name: "Delay Render Timeout", formatter: (v) => `${v}ms`, min: 0, max: 1000000000, step: 1000, value: delayRenderTimeout, onValueChanged: setDelayRenderTimeout, hint: "delayRenderTimeoutInMillisecondsOption" }), jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
|
|
78
161
|
jsx_runtime_1.jsxs("div", { style: layout_2.label, children: ["Custom @remotion/media cache size ",
|
|
79
|
-
jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(OptionExplainerBubble_1.
|
|
162
|
+
jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(OptionExplainerBubble_1.WebRendererOptionExplainerBubble, { apiName: "mediaCacheSizeInBytes", id: "mediaCacheSizeInBytesOption" })
|
|
80
163
|
] }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(Checkbox_1.Checkbox, { checked: mediaCacheSizeInBytes !== null, onChange: toggleCustomMediaCacheSizeInBytes, name: "media-cache-size" }) })
|
|
81
164
|
] }), mediaCacheSizeInBytes === null ? null : (jsx_runtime_1.jsx(NumberSetting_1.NumberSetting, { name: "@remotion/media cache size", formatter: (w) => `${w} bytes`, min: 0, max: 10000000000, step: 10 * 1024 * 1024, value: mediaCacheSizeInBytes, onValueChanged: changeMediaCacheSizeInBytes })), renderMode === 'video' ? (jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
|
|
82
165
|
jsx_runtime_1.jsx("div", { style: layout_2.label, children: "Hardware Acceleration" }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { values: hardwareAccelerationOptions, selectedId: hardwareAcceleration, title: "Hardware Acceleration" }) })
|
|
83
166
|
] })) : null, jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
|
|
84
167
|
jsx_runtime_1.jsxs("div", { style: layout_2.label, children: ["Allow HTML-in-canvas ",
|
|
85
|
-
jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(OptionExplainerBubble_1.
|
|
168
|
+
jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(OptionExplainerBubble_1.WebRendererOptionExplainerBubble, { apiName: "allowHtmlInCanvas", id: "allowHtmlInCanvasOption" })
|
|
86
169
|
] }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(Checkbox_1.Checkbox, { checked: allowHtmlInCanvas, onChange: toggleAllowHtmlInCanvas, name: "allow-html-in-canvas" }) })
|
|
87
|
-
] })
|
|
88
|
-
|
|
170
|
+
] }), renderMode === 'still' ? null : (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
171
|
+
jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
|
|
172
|
+
jsx_runtime_1.jsxs("div", { style: layout_2.label, children: ["Page Responsiveness ",
|
|
173
|
+
jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(OptionExplainerBubble_1.WebRendererCustomOptionExplainerBubble, { apiName: "pageResponsiveness", description: jsx_runtime_1.jsx(PageResponsivenessDescription, {}), docLink: "https://www.remotion.dev/docs/client-side-rendering/page-responsiveness", name: "Page responsiveness" })
|
|
174
|
+
] }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { values: pageResponsivenessOptions, selectedId: selectedPageResponsiveness, title: "Page Responsiveness" }) })
|
|
175
|
+
] }), typeof pageResponsiveness === 'number' ? (jsx_runtime_1.jsx(NumberSetting_1.NumberSetting, { name: "Responsiveness Interval", formatter: (v) => `${v}ms`, min: 1, max: 1000000000, step: 1, value: pageResponsiveness, onValueChanged: setCustomPageResponsiveness })) : null] }))] }));
|
|
89
176
|
};
|
|
90
177
|
exports.WebRenderModalAdvanced = WebRenderModalAdvanced;
|
|
@@ -118,12 +118,12 @@ const WebRenderModalBasic = ({ renderMode, resolvedComposition, imageFormat, set
|
|
|
118
118
|
jsx_runtime_1.jsx("div", { style: layout_2.label, children: "Container" }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { values: containerOptions, selectedId: container, title: "Container" }) })
|
|
119
119
|
] }), renderMode === 'video' ? (jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
|
|
120
120
|
jsx_runtime_1.jsxs("div", { style: layout_2.label, children: ["Codec",
|
|
121
|
-
jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(OptionExplainerBubble_1.
|
|
121
|
+
jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(OptionExplainerBubble_1.WebRendererOptionExplainerBubble, { apiName: "codec", id: "videoCodecOption" })
|
|
122
122
|
] }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { values: codecOptions, selectedId: effectiveVideoCodec, title: "Codec" }) })
|
|
123
123
|
] })) : null, jsx_runtime_1.jsx(FrameRangeSetting_1.FrameRangeSetting, { durationInFrames: resolvedComposition.durationInFrames, startFrame: startFrame !== null && startFrame !== void 0 ? startFrame : 0, endFrame: endFrame !== null && endFrame !== void 0 ? endFrame : resolvedComposition.durationInFrames - 1, setStartFrame: setStartFrame, setEndFrame: setEndFrame })
|
|
124
124
|
] })), jsx_runtime_1.jsx(RenderModalOutputName_1.RenderModalOutputName, { existence: false, inputStyle: layout_2.input, outName: outName, onValueChange: onOutNameChange, validationMessage: validationMessage, label: window.remotion_isReadOnlyStudio ? 'Download name' : 'Output name' }), jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
|
|
125
125
|
jsx_runtime_1.jsxs("div", { style: layout_2.label, children: ["Log Level ",
|
|
126
|
-
jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(OptionExplainerBubble_1.
|
|
126
|
+
jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(OptionExplainerBubble_1.WebRendererOptionExplainerBubble, { apiName: "logLevel", id: "logLevelOption" })
|
|
127
127
|
] }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { values: logLevelOptions, selectedId: logLevel, title: "Log Level" }) })
|
|
128
128
|
] })
|
|
129
129
|
] }));
|
|
@@ -98,6 +98,7 @@ const ClientRenderQueueProcessor = () => {
|
|
|
98
98
|
outputTarget: 'web-fs',
|
|
99
99
|
licenseKey: (_c = job.licenseKey) !== null && _c !== void 0 ? _c : undefined,
|
|
100
100
|
allowHtmlInCanvas: job.allowHtmlInCanvas,
|
|
101
|
+
pageResponsiveness: job.pageResponsiveness,
|
|
101
102
|
});
|
|
102
103
|
return {
|
|
103
104
|
getBlob,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CompletedClientRender } from '@remotion/studio-shared';
|
|
2
|
-
import type { RenderStillOnWebImageFormat, WebRendererAudioCodec, WebRendererContainer, WebRendererQuality, WebRendererVideoCodec } from '@remotion/web-renderer';
|
|
2
|
+
import type { RenderStillOnWebImageFormat, WebRendererAudioCodec, WebRendererContainer, WebRendererPageResponsiveness, WebRendererQuality, WebRendererVideoCodec } from '@remotion/web-renderer';
|
|
3
3
|
import type { LogLevel } from 'remotion';
|
|
4
4
|
export type ClientRenderJobProgress = {
|
|
5
5
|
encodedFrames: number;
|
|
@@ -60,6 +60,7 @@ export type ClientVideoRenderJob = ClientRenderJobBase & {
|
|
|
60
60
|
keyframeIntervalInSeconds: number;
|
|
61
61
|
transparent: boolean;
|
|
62
62
|
muted: boolean;
|
|
63
|
+
pageResponsiveness: WebRendererPageResponsiveness;
|
|
63
64
|
} & ClientRenderJobDynamicStatus;
|
|
64
65
|
export type RestoredClientRenderJob = CompletedClientRender & {
|
|
65
66
|
status: 'done';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { SelectedOutline } from './selected-outline-geometry';
|
|
3
|
+
import { type SelectedOutlineSnapPoint, type SelectedOutlineSnapTarget } from './selected-outline-snap';
|
|
3
4
|
import { type SelectedOutlineDragTarget, type SelectedOutlineRotationDragTarget, type SelectedOutlineScaleDragTarget, type SelectedOutlineTarget } from './selected-outline-types';
|
|
4
5
|
import type { TimelineSelection, TimelineSelectionInteraction } from './Timeline/TimelineSelection';
|
|
5
6
|
export declare const SelectedOutlineTransformOriginHandle: React.FC<{
|
|
@@ -9,6 +10,7 @@ export declare const SelectedOutlineTransformOriginHandle: React.FC<{
|
|
|
9
10
|
}>;
|
|
10
11
|
export declare const SelectedOutlineElement: React.FC<{
|
|
11
12
|
readonly allDragTargets: readonly SelectedOutlineDragTarget[];
|
|
13
|
+
readonly allDragOutlines: readonly SelectedOutline[];
|
|
12
14
|
readonly allRotationDragTargets: readonly SelectedOutlineRotationDragTarget[];
|
|
13
15
|
readonly allScaleDragTargets: readonly SelectedOutlineScaleDragTarget[];
|
|
14
16
|
readonly dragging: boolean;
|
|
@@ -16,7 +18,9 @@ export declare const SelectedOutlineElement: React.FC<{
|
|
|
16
18
|
readonly outline: SelectedOutline;
|
|
17
19
|
readonly onDraggingChange: (dragging: boolean) => void;
|
|
18
20
|
readonly onHoverChange: (key: string | null) => void;
|
|
21
|
+
readonly onSnapPointsChange: (snapPoints: readonly SelectedOutlineSnapPoint[]) => void;
|
|
19
22
|
readonly onSelect: (item: TimelineSelection, interaction: TimelineSelectionInteraction) => void;
|
|
20
23
|
readonly scale: number;
|
|
24
|
+
readonly snapTargets: readonly SelectedOutlineSnapTarget[];
|
|
21
25
|
readonly target: SelectedOutlineTarget | undefined;
|
|
22
26
|
}>;
|
|
@@ -43,6 +43,7 @@ const client_id_1 = require("../helpers/client-id");
|
|
|
43
43
|
const colors_1 = require("../helpers/colors");
|
|
44
44
|
const format_file_location_1 = require("../helpers/format-file-location");
|
|
45
45
|
const open_in_editor_1 = require("../helpers/open-in-editor");
|
|
46
|
+
const editor_snapping_1 = require("../state/editor-snapping");
|
|
46
47
|
const modals_1 = require("../state/modals");
|
|
47
48
|
const call_api_1 = require("./call-api");
|
|
48
49
|
const ConfirmationDialog_1 = require("./ConfirmationDialog");
|
|
@@ -53,6 +54,7 @@ const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
|
|
53
54
|
const options_sidebar_tabs_1 = require("./options-sidebar-tabs");
|
|
54
55
|
const selected_outline_drag_1 = require("./selected-outline-drag");
|
|
55
56
|
const selected_outline_measurement_1 = require("./selected-outline-measurement");
|
|
57
|
+
const selected_outline_snap_1 = require("./selected-outline-snap");
|
|
56
58
|
const selected_outline_types_1 = require("./selected-outline-types");
|
|
57
59
|
const selected_outline_uv_1 = require("./selected-outline-uv");
|
|
58
60
|
const call_add_keyframe_1 = require("./Timeline/call-add-keyframe");
|
|
@@ -70,6 +72,7 @@ const emptyContextMenuValues = [];
|
|
|
70
72
|
const SelectedOutlineTransformOriginHandle = ({ outline, onDraggingChange, target }) => {
|
|
71
73
|
var _a;
|
|
72
74
|
const { setDragOverrides, clearDragOverrides, setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
|
|
75
|
+
const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
|
|
73
76
|
const transformOriginDrag = (_a = target === null || target === void 0 ? void 0 : target.transformOriginDrag) !== null && _a !== void 0 ? _a : null;
|
|
74
77
|
const parsed = (0, react_1.useMemo)(() => transformOriginDrag === null
|
|
75
78
|
? null
|
|
@@ -142,11 +145,13 @@ const SelectedOutlineTransformOriginHandle = ({ outline, onDraggingChange, targe
|
|
|
142
145
|
const snapPoint = lockedAxis === null
|
|
143
146
|
? point
|
|
144
147
|
: (0, selected_outline_uv_1.getUvHandlePosition)(outline.points, axisLockedUv);
|
|
145
|
-
const snappedUv =
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
const snappedUv = editorSnapping
|
|
149
|
+
? (0, selected_outline_drag_1.snapSelectedOutlineTransformOriginUv)({
|
|
150
|
+
point: snapPoint,
|
|
151
|
+
points: outline.points,
|
|
152
|
+
uv: axisLockedUv,
|
|
153
|
+
})
|
|
154
|
+
: axisLockedUv;
|
|
150
155
|
const nextUv = (0, selected_outline_drag_1.applySelectedOutlineTransformOriginAxisLock)({
|
|
151
156
|
lockedAxis,
|
|
152
157
|
startUv: uv,
|
|
@@ -293,6 +298,7 @@ const SelectedOutlineTransformOriginHandle = ({ outline, onDraggingChange, targe
|
|
|
293
298
|
window.addEventListener('keyup', onKeyChange);
|
|
294
299
|
}, [
|
|
295
300
|
clearDragOverrides,
|
|
301
|
+
editorSnapping,
|
|
296
302
|
onDraggingChange,
|
|
297
303
|
outline,
|
|
298
304
|
parsed,
|
|
@@ -314,10 +320,11 @@ const SelectedOutlineTransformOriginHandle = ({ outline, onDraggingChange, targe
|
|
|
314
320
|
] }));
|
|
315
321
|
};
|
|
316
322
|
exports.SelectedOutlineTransformOriginHandle = SelectedOutlineTransformOriginHandle;
|
|
317
|
-
const SelectedOutlinePolygon = ({ allDragTargets, contextMenuValues, dragging, hovered, onContextMenuOpen, outline, onDraggingChange, onHoverChange, onSelect, onTextEditStart, scale, target, }) => {
|
|
323
|
+
const SelectedOutlinePolygon = ({ allDragTargets, allDragOutlines, contextMenuValues, dragging, hovered, onContextMenuOpen, outline, onDraggingChange, onHoverChange, onSnapPointsChange, onSelect, onTextEditStart, scale, snapTargets, target, }) => {
|
|
318
324
|
var _a, _b, _c, _d;
|
|
319
325
|
const { getDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
|
|
320
326
|
const { setPropStatuses, setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
|
|
327
|
+
const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
|
|
321
328
|
const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
|
|
322
329
|
const timelinePositionRef = (0, react_1.useRef)(timelinePosition);
|
|
323
330
|
timelinePositionRef.current = timelinePosition;
|
|
@@ -358,6 +365,7 @@ const SelectedOutlinePolygon = ({ allDragTargets, contextMenuValues, dragging, h
|
|
|
358
365
|
let currentPointerY = startPointerY;
|
|
359
366
|
let axisLocked = false;
|
|
360
367
|
let dragStarted = false;
|
|
368
|
+
let snappingDisabled = event.metaKey || event.ctrlKey;
|
|
361
369
|
const updateDragOverrides = () => {
|
|
362
370
|
const screenDeltaX = currentPointerX - startPointerX;
|
|
363
371
|
const screenDeltaY = currentPointerY - startPointerY;
|
|
@@ -370,16 +378,44 @@ const SelectedOutlinePolygon = ({ allDragTargets, contextMenuValues, dragging, h
|
|
|
370
378
|
}
|
|
371
379
|
dragStarted = true;
|
|
372
380
|
onDraggingChange(true);
|
|
381
|
+
(0, ForceSpecificCursor_1.forceSpecificCursor)('default');
|
|
373
382
|
}
|
|
383
|
+
const axisLockedDirection = axisLocked
|
|
384
|
+
? Math.abs(screenDeltaX) >= Math.abs(screenDeltaY)
|
|
385
|
+
? 'horizontal'
|
|
386
|
+
: 'vertical'
|
|
387
|
+
: null;
|
|
374
388
|
const dragDelta = (0, selected_outline_drag_1.applySelectedOutlineDragAxisLock)({
|
|
375
389
|
deltaX: screenDeltaX / scale,
|
|
376
390
|
deltaY: screenDeltaY / scale,
|
|
377
391
|
axisLocked,
|
|
378
392
|
});
|
|
393
|
+
let { deltaX, deltaY } = dragDelta;
|
|
394
|
+
if (editorSnapping && !snappingDisabled) {
|
|
395
|
+
const snapResult = (0, selected_outline_snap_1.findSelectedOutlineSnap)({
|
|
396
|
+
allowX: axisLockedDirection !== 'vertical',
|
|
397
|
+
allowY: axisLockedDirection !== 'horizontal',
|
|
398
|
+
deltaX,
|
|
399
|
+
deltaY,
|
|
400
|
+
outlines: selected ? allDragOutlines : [outline],
|
|
401
|
+
scale,
|
|
402
|
+
targets: snapTargets,
|
|
403
|
+
});
|
|
404
|
+
if (snapResult.snapOffsetX !== null) {
|
|
405
|
+
deltaX += snapResult.snapOffsetX;
|
|
406
|
+
}
|
|
407
|
+
if (snapResult.snapOffsetY !== null) {
|
|
408
|
+
deltaY += snapResult.snapOffsetY;
|
|
409
|
+
}
|
|
410
|
+
onSnapPointsChange(snapResult.activeSnapPoints);
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
onSnapPointsChange([]);
|
|
414
|
+
}
|
|
379
415
|
lastValues = (0, selected_outline_drag_1.getSelectedOutlineDragValues)({
|
|
380
416
|
dragStates,
|
|
381
|
-
deltaX
|
|
382
|
-
deltaY
|
|
417
|
+
deltaX,
|
|
418
|
+
deltaY,
|
|
383
419
|
});
|
|
384
420
|
for (const dragState of dragStates) {
|
|
385
421
|
const value = lastValues.get(dragState.key);
|
|
@@ -403,6 +439,7 @@ const SelectedOutlinePolygon = ({ allDragTargets, contextMenuValues, dragging, h
|
|
|
403
439
|
currentPointerX = moveEvent.clientX;
|
|
404
440
|
currentPointerY = moveEvent.clientY;
|
|
405
441
|
axisLocked = moveEvent.shiftKey;
|
|
442
|
+
snappingDisabled = moveEvent.metaKey || moveEvent.ctrlKey;
|
|
406
443
|
updateDragOverrides();
|
|
407
444
|
};
|
|
408
445
|
const onKeyChange = (keyEvent) => {
|
|
@@ -423,6 +460,7 @@ const SelectedOutlinePolygon = ({ allDragTargets, contextMenuValues, dragging, h
|
|
|
423
460
|
window.removeEventListener('keydown', onKeyChange);
|
|
424
461
|
window.removeEventListener('keyup', onKeyChange);
|
|
425
462
|
if (dragStarted) {
|
|
463
|
+
(0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
|
|
426
464
|
onDraggingChange(false);
|
|
427
465
|
}
|
|
428
466
|
const changes = (0, selected_outline_drag_1.getSelectedOutlineDragChanges)({
|
|
@@ -474,15 +512,20 @@ const SelectedOutlinePolygon = ({ allDragTargets, contextMenuValues, dragging, h
|
|
|
474
512
|
window.addEventListener('keyup', onKeyChange);
|
|
475
513
|
}, [
|
|
476
514
|
allDragTargets,
|
|
515
|
+
allDragOutlines,
|
|
477
516
|
clearDragOverrides,
|
|
478
517
|
drag,
|
|
518
|
+
editorSnapping,
|
|
479
519
|
getDragOverrides,
|
|
480
520
|
onDraggingChange,
|
|
481
521
|
onSelect,
|
|
522
|
+
onSnapPointsChange,
|
|
523
|
+
outline,
|
|
482
524
|
scale,
|
|
483
525
|
selected,
|
|
484
526
|
setPropStatuses,
|
|
485
527
|
setDragOverrides,
|
|
528
|
+
snapTargets,
|
|
486
529
|
target,
|
|
487
530
|
]);
|
|
488
531
|
const onDoubleClick = react_1.default.useCallback((event) => {
|
|
@@ -718,6 +761,7 @@ const SelectedOutlineRotationCornerHandle = ({ allRotationDragTargets, contextMe
|
|
|
718
761
|
var _a, _b;
|
|
719
762
|
const { getDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
|
|
720
763
|
const { setPropStatuses, setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
|
|
764
|
+
const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
|
|
721
765
|
const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
|
|
722
766
|
const timelinePositionRef = (0, react_1.useRef)(timelinePosition);
|
|
723
767
|
timelinePositionRef.current = timelinePosition;
|
|
@@ -770,7 +814,7 @@ const SelectedOutlineRotationCornerHandle = ({ allRotationDragTargets, contextMe
|
|
|
770
814
|
let lastValues = new Map();
|
|
771
815
|
let dragStarted = false;
|
|
772
816
|
const updateRotationDragOverrides = () => {
|
|
773
|
-
const rotationDeltaDegrees = rotationLocked
|
|
817
|
+
const rotationDeltaDegrees = rotationLocked && editorSnapping
|
|
774
818
|
? (0, selected_outline_drag_1.snapSelectedOutlineRotationDeltaDegrees)({
|
|
775
819
|
dragStates,
|
|
776
820
|
rotationDeltaDegrees: accumulatedDelta,
|
|
@@ -904,6 +948,7 @@ const SelectedOutlineRotationCornerHandle = ({ allRotationDragTargets, contextMe
|
|
|
904
948
|
allRotationDragTargets,
|
|
905
949
|
clearDragOverrides,
|
|
906
950
|
cornerInfo,
|
|
951
|
+
editorSnapping,
|
|
907
952
|
getDragOverrides,
|
|
908
953
|
onDraggingChange,
|
|
909
954
|
outline.dimensions,
|
|
@@ -930,7 +975,7 @@ const SelectedOutlineRotationCornerHandle = ({ allRotationDragTargets, contextMe
|
|
|
930
975
|
}, onPointerDown: onPointerDown }), jsx_runtime_1.jsx(ContextMenu_1.ContextMenuForTarget, { triggerRef: circleRef, values: [...contextMenuValues], onOpen: onContextMenuOpen })
|
|
931
976
|
] }));
|
|
932
977
|
};
|
|
933
|
-
const SelectedOutlineElement = ({ allDragTargets, allRotationDragTargets, allScaleDragTargets, dragging, hovered, outline, onDraggingChange, onHoverChange, onSelect, scale, target, }) => {
|
|
978
|
+
const SelectedOutlineElement = ({ allDragTargets, allDragOutlines, allRotationDragTargets, allScaleDragTargets, dragging, hovered, outline, onDraggingChange, onHoverChange, onSnapPointsChange, onSelect, scale, snapTargets, target, }) => {
|
|
934
979
|
const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
|
|
935
980
|
const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
|
|
936
981
|
const updateResolvedStackTrace = (0, react_1.useContext)(remotion_1.Internals.SequenceStackTracesUpdateContext);
|
|
@@ -1114,7 +1159,7 @@ const SelectedOutlineElement = ({ allDragTargets, allRotationDragTargets, allSca
|
|
|
1114
1159
|
updateResolvedStackTrace,
|
|
1115
1160
|
]);
|
|
1116
1161
|
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
1117
|
-
jsx_runtime_1.jsx(SelectedOutlinePolygon, { allDragTargets: allDragTargets, contextMenuValues: emptyContextMenuValues, dragging: dragging, hovered: hovered, outline: outline, onContextMenuOpen: onContextMenuOpen, onDraggingChange: onDraggingChange, onHoverChange: onHoverChange, onSelect: onSelect, onTextEditStart: onTextEditStart, scale: scale, target: target }), (target === null || target === void 0 ? void 0 : target.containsSelection) || hovered
|
|
1162
|
+
jsx_runtime_1.jsx(SelectedOutlinePolygon, { allDragTargets: allDragTargets, allDragOutlines: allDragOutlines, contextMenuValues: emptyContextMenuValues, dragging: dragging, hovered: hovered, outline: outline, onContextMenuOpen: onContextMenuOpen, onDraggingChange: onDraggingChange, onHoverChange: onHoverChange, onSnapPointsChange: onSnapPointsChange, onSelect: onSelect, onTextEditStart: onTextEditStart, scale: scale, snapTargets: snapTargets, target: target }), (target === null || target === void 0 ? void 0 : target.containsSelection) || hovered
|
|
1118
1163
|
? ['top', 'right', 'bottom', 'left'].map((edge) => (jsx_runtime_1.jsx(SelectedOutlineScaleEdgeLine, { allScaleDragTargets: allScaleDragTargets, contextMenuValues: emptyContextMenuValues, dragging: dragging, edge: edge, outline: outline, onContextMenuOpen: onContextMenuOpen, onDraggingChange: onDraggingChange, onHoverChange: onHoverChange, onSelect: onSelect, target: target }, edge)))
|
|
1119
1164
|
: null, (target === null || target === void 0 ? void 0 : target.containsSelection) || hovered
|
|
1120
1165
|
? ['top-left', 'top-right', 'bottom-right', 'bottom-left'].map((corner) => (jsx_runtime_1.jsx(SelectedOutlineRotationCornerHandle, { allRotationDragTargets: allRotationDragTargets, contextMenuValues: emptyContextMenuValues, corner: corner, dragging: dragging, outline: outline, onContextMenuOpen: onContextMenuOpen, onDraggingChange: onDraggingChange, onHoverChange: onHoverChange, onSelect: onSelect, target: target }, corner)))
|
|
@@ -10,6 +10,8 @@ export declare const orderOutlinesForRendering: ({ outlines, targetsByKey, }: {
|
|
|
10
10
|
readonly targetsByKey: ReadonlyMap<string, SelectedOutlineTarget>;
|
|
11
11
|
}) => readonly SelectedOutline[];
|
|
12
12
|
export declare const SelectedOutlineOverlay: React.FC<{
|
|
13
|
+
readonly compositionHeight: number;
|
|
14
|
+
readonly compositionWidth: number;
|
|
13
15
|
readonly scale: number;
|
|
14
16
|
readonly translationX: number;
|
|
15
17
|
readonly translationY: number;
|
|
@@ -41,11 +41,13 @@ const remotion_1 = require("remotion");
|
|
|
41
41
|
const no_react_1 = require("remotion/no-react");
|
|
42
42
|
const client_id_1 = require("../helpers/client-id");
|
|
43
43
|
const use_keybinding_1 = require("../helpers/use-keybinding");
|
|
44
|
+
const editor_guides_1 = require("../state/editor-guides");
|
|
44
45
|
const editor_outlines_1 = require("../state/editor-outlines");
|
|
45
46
|
const scale_lock_1 = require("../state/scale-lock");
|
|
46
47
|
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
|
47
48
|
const selected_outline_drag_1 = require("./selected-outline-drag");
|
|
48
49
|
const selected_outline_measurement_1 = require("./selected-outline-measurement");
|
|
50
|
+
const selected_outline_snap_1 = require("./selected-outline-snap");
|
|
49
51
|
const selected_outline_types_1 = require("./selected-outline-types");
|
|
50
52
|
const selected_outline_uv_1 = require("./selected-outline-uv");
|
|
51
53
|
const SelectedOutlineElement_1 = require("./SelectedOutlineElement");
|
|
@@ -95,6 +97,19 @@ const outlineContainer = {
|
|
|
95
97
|
pointerEvents: 'none',
|
|
96
98
|
overflow: 'visible',
|
|
97
99
|
};
|
|
100
|
+
const SelectedOutlineSnapIndicators = ({ activeSnapPoints, compositionHeight, compositionWidth, scale }) => {
|
|
101
|
+
if (activeSnapPoints.length === 0) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
return (jsx_runtime_1.jsx("g", { pointerEvents: "none", children: activeSnapPoints.map((snapPoint) => {
|
|
105
|
+
if (snapPoint.target.axis === 'x') {
|
|
106
|
+
const x = snapPoint.target.position * scale;
|
|
107
|
+
return (jsx_runtime_1.jsx("line", { x1: x, x2: x, y1: 0, y2: compositionHeight * scale, stroke: selected_outline_snap_1.selectedOutlineSnapIndicatorColor, strokeWidth: 1, vectorEffect: "non-scaling-stroke" }, `${snapPoint.target.axis}-${snapPoint.target.type}-${snapPoint.target.position}-${snapPoint.edge}`));
|
|
108
|
+
}
|
|
109
|
+
const y = snapPoint.target.position * scale;
|
|
110
|
+
return (jsx_runtime_1.jsx("line", { x1: 0, x2: compositionWidth * scale, y1: y, y2: y, stroke: selected_outline_snap_1.selectedOutlineSnapIndicatorColor, strokeWidth: 1, vectorEffect: "non-scaling-stroke" }, `${snapPoint.target.axis}-${snapPoint.target.type}-${snapPoint.target.position}-${snapPoint.edge}`));
|
|
111
|
+
}) }));
|
|
112
|
+
};
|
|
98
113
|
const orderOutlinesForRendering = ({ outlines, targetsByKey, }) => {
|
|
99
114
|
return [...outlines].sort((a, b) => {
|
|
100
115
|
var _a, _b;
|
|
@@ -105,9 +120,10 @@ const orderOutlinesForRendering = ({ outlines, targetsByKey, }) => {
|
|
|
105
120
|
});
|
|
106
121
|
};
|
|
107
122
|
exports.orderOutlinesForRendering = orderOutlinesForRendering;
|
|
108
|
-
const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
|
|
123
|
+
const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, translationX, translationY, }) => {
|
|
109
124
|
const { selectedItems, selectItem } = (0, TimelineSelection_1.useTimelineSelection)();
|
|
110
125
|
const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
|
|
126
|
+
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
|
111
127
|
const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
|
|
112
128
|
const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
|
|
113
129
|
const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
|
|
@@ -115,12 +131,14 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
|
|
|
115
131
|
const { setPropStatuses, setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
|
|
116
132
|
const { getScaleLockState } = (0, react_1.useContext)(scale_lock_1.ScaleLockContext);
|
|
117
133
|
const { editorShowOutlines } = (0, react_1.useContext)(editor_outlines_1.EditorShowOutlinesContext);
|
|
134
|
+
const { editorShowGuides, guidesList } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
|
|
118
135
|
const { frameBack, frameForward, getCurrentFrame, seek } = player_1.PlayerInternals.usePlayer();
|
|
119
136
|
const keybindings = (0, use_keybinding_1.useKeybinding)();
|
|
120
137
|
const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
|
|
121
138
|
const [outlines, setOutlines] = (0, react_1.useState)([]);
|
|
122
139
|
const [hoveredOutlineKey, setHoveredOutlineKey] = (0, react_1.useState)(null);
|
|
123
140
|
const [draggingOutline, setDraggingOutline] = (0, react_1.useState)(false);
|
|
141
|
+
const [activeSnapPoints, setActiveSnapPoints] = (0, react_1.useState)([]);
|
|
124
142
|
const overlayRef = (0, react_1.useRef)(null);
|
|
125
143
|
const keyboardNudgeSessionRef = (0, react_1.useRef)(null);
|
|
126
144
|
const saveKeyboardNudgeSessionRef = (0, react_1.useRef)(() => undefined);
|
|
@@ -129,6 +147,12 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
|
|
|
129
147
|
if (dragging) {
|
|
130
148
|
setHoveredOutlineKey(null);
|
|
131
149
|
}
|
|
150
|
+
else {
|
|
151
|
+
setActiveSnapPoints([]);
|
|
152
|
+
}
|
|
153
|
+
}, []);
|
|
154
|
+
const onSnapPointsChange = (0, react_1.useCallback)((snapPoints) => {
|
|
155
|
+
setActiveSnapPoints(snapPoints);
|
|
132
156
|
}, []);
|
|
133
157
|
const selectOutlineItem = (0, react_1.useCallback)((item, interaction) => {
|
|
134
158
|
selectItem(item, interaction, undefined, { reveal: true });
|
|
@@ -391,11 +415,24 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
|
|
|
391
415
|
const outlinesForRendering = (0, react_1.useMemo)(() => {
|
|
392
416
|
return (0, exports.orderOutlinesForRendering)({ outlines, targetsByKey });
|
|
393
417
|
}, [outlines, targetsByKey]);
|
|
418
|
+
const outlinesByKey = (0, react_1.useMemo)(() => {
|
|
419
|
+
return new Map(outlines.map((outline) => [outline.key, outline]));
|
|
420
|
+
}, [outlines]);
|
|
394
421
|
const allDragTargets = (0, react_1.useMemo)(() => {
|
|
395
422
|
return outlineTargets.flatMap((target) => (target.selected || target.containsSelection) && target.drag !== null
|
|
396
423
|
? [target.drag]
|
|
397
424
|
: []);
|
|
398
425
|
}, [outlineTargets]);
|
|
426
|
+
const allDragOutlines = (0, react_1.useMemo)(() => {
|
|
427
|
+
return outlineTargets.flatMap((target) => {
|
|
428
|
+
if ((!target.selected && !target.containsSelection) ||
|
|
429
|
+
target.drag === null) {
|
|
430
|
+
return [];
|
|
431
|
+
}
|
|
432
|
+
const outline = outlinesByKey.get(target.key);
|
|
433
|
+
return outline === undefined ? [] : [outline];
|
|
434
|
+
});
|
|
435
|
+
}, [outlineTargets, outlinesByKey]);
|
|
399
436
|
const allScaleDragTargets = (0, react_1.useMemo)(() => {
|
|
400
437
|
return outlineTargets.flatMap((target) => target.selected && target.scaleDrag !== null ? [target.scaleDrag] : []);
|
|
401
438
|
}, [outlineTargets]);
|
|
@@ -404,6 +441,19 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
|
|
|
404
441
|
? [target.rotationDrag]
|
|
405
442
|
: []);
|
|
406
443
|
}, [outlineTargets]);
|
|
444
|
+
const guidesForSnap = (0, react_1.useMemo)(() => {
|
|
445
|
+
if (!editorShowGuides || (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) !== 'composition') {
|
|
446
|
+
return [];
|
|
447
|
+
}
|
|
448
|
+
return guidesList.filter((guide) => guide.compositionId === canvasContent.compositionId);
|
|
449
|
+
}, [canvasContent, editorShowGuides, guidesList]);
|
|
450
|
+
const snapTargets = (0, react_1.useMemo)(() => {
|
|
451
|
+
return (0, selected_outline_snap_1.getSelectedOutlineSnapTargets)({
|
|
452
|
+
compositionHeight,
|
|
453
|
+
compositionWidth,
|
|
454
|
+
guides: guidesForSnap,
|
|
455
|
+
});
|
|
456
|
+
}, [compositionHeight, compositionWidth, guidesForSnap]);
|
|
407
457
|
const saveKeyboardNudgeSession = (0, react_1.useCallback)(() => {
|
|
408
458
|
const session = keyboardNudgeSessionRef.current;
|
|
409
459
|
if (session === null) {
|
|
@@ -671,6 +721,7 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
|
|
|
671
721
|
if (outlineTargets.length === 0) {
|
|
672
722
|
return null;
|
|
673
723
|
}
|
|
674
|
-
return (jsx_runtime_1.jsxs("svg", { ref: overlayRef, style: outlineContainer, width: "100%", height: "100%", "aria-hidden": "true", children: [
|
|
724
|
+
return (jsx_runtime_1.jsxs("svg", { ref: overlayRef, style: outlineContainer, width: "100%", height: "100%", "aria-hidden": "true", children: [
|
|
725
|
+
jsx_runtime_1.jsx(SelectedOutlineSnapIndicators, { activeSnapPoints: activeSnapPoints, compositionHeight: compositionHeight, compositionWidth: compositionWidth, scale: scale }), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineElement_1.SelectedOutlineElement, { allDragTargets: allDragTargets, allDragOutlines: allDragOutlines, allRotationDragTargets: allRotationDragTargets, allScaleDragTargets: allScaleDragTargets, dragging: draggingOutline, hovered: hoveredOutlineKey === outline.key, outline: outline, onDraggingChange: onDraggingChange, onHoverChange: setHoveredOutlineKey, onSnapPointsChange: onSnapPointsChange, onSelect: selectOutlineItem, scale: scale, snapTargets: snapTargets, target: targetsByKey.get(outline.key) }, outline.key))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineElement_1.SelectedOutlineTransformOriginHandle, { outline: outline, onDraggingChange: onDraggingChange, target: targetsByKey.get(outline.key) }, `${outline.key}-transform-origin`))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineUvControls_1.SelectedOutlineUvHandleConnectionLayer, { outline: outline, target: targetsByKey.get(outline.key) }, `${outline.key}-uv-connection-lines`))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineUvControls_1.SelectedOutlineUvHandleCircleLayer, { onDraggingChange: onDraggingChange, onSelect: selectOutlineItem, outline: outline, target: targetsByKey.get(outline.key) }, `${outline.key}-uv-handles`)))] }));
|
|
675
726
|
};
|
|
676
727
|
exports.SelectedOutlineOverlay = SelectedOutlineOverlay;
|
|
@@ -38,6 +38,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
38
38
|
const react_1 = __importStar(require("react"));
|
|
39
39
|
const remotion_1 = require("remotion");
|
|
40
40
|
const colors_1 = require("../helpers/colors");
|
|
41
|
+
const editor_snapping_1 = require("../state/editor-snapping");
|
|
41
42
|
const ForceSpecificCursor_1 = require("./ForceSpecificCursor");
|
|
42
43
|
const selected_outline_drag_1 = require("./selected-outline-drag");
|
|
43
44
|
const selected_outline_measurement_1 = require("./selected-outline-measurement");
|
|
@@ -384,6 +385,7 @@ const trimLineToCircleEdges = ({ from, fromRadius, to, toRadius, }) => {
|
|
|
384
385
|
};
|
|
385
386
|
const SelectedUvEllipseRotationHandle = ({ control, onDraggingChange }) => {
|
|
386
387
|
const { setEffectDragOverrides, clearEffectDragOverrides, setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
|
|
388
|
+
const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
|
|
387
389
|
const { rotationControl } = control;
|
|
388
390
|
const field = rotationControl === null || rotationControl === void 0 ? void 0 : rotationControl.field;
|
|
389
391
|
const onPointerDown = react_1.default.useCallback((event) => {
|
|
@@ -413,7 +415,7 @@ const SelectedUvEllipseRotationHandle = ({ control, onDraggingChange }) => {
|
|
|
413
415
|
let lastValue = null;
|
|
414
416
|
const updateRotationDragOverride = () => {
|
|
415
417
|
const rawValue = control.rotation + accumulatedDelta;
|
|
416
|
-
const snappedValue = rotationLocked
|
|
418
|
+
const snappedValue = rotationLocked && editorSnapping
|
|
417
419
|
? snapRotationDegrees(rawValue)
|
|
418
420
|
: rawValue;
|
|
419
421
|
const nextValue = (0, selected_outline_uv_1.roundNumericUvEllipseValue)(snappedValue, field.fieldSchema);
|
|
@@ -497,6 +499,7 @@ const SelectedUvEllipseRotationHandle = ({ control, onDraggingChange }) => {
|
|
|
497
499
|
}, [
|
|
498
500
|
clearEffectDragOverrides,
|
|
499
501
|
control,
|
|
502
|
+
editorSnapping,
|
|
500
503
|
field,
|
|
501
504
|
onDraggingChange,
|
|
502
505
|
rotationControl,
|
|
@@ -522,6 +525,7 @@ const SelectedUvEllipseRotationHandle = ({ control, onDraggingChange }) => {
|
|
|
522
525
|
};
|
|
523
526
|
const SelectedUvHandleCircle = ({ handle, nodePathInfo, onDraggingChange, onSelect, outline }) => {
|
|
524
527
|
const { setEffectDragOverrides, clearEffectDragOverrides, setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
|
|
528
|
+
const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
|
|
525
529
|
const position = (0, react_1.useMemo)(() => (0, selected_outline_uv_1.getUvHandlePosition)(outline.points, handle.value), [handle.value, outline.points]);
|
|
526
530
|
const onPointerDown = react_1.default.useCallback((event) => {
|
|
527
531
|
if (event.button !== 0) {
|
|
@@ -556,11 +560,13 @@ const SelectedUvHandleCircle = ({ handle, nodePathInfo, onDraggingChange, onSele
|
|
|
556
560
|
rect: svgRect,
|
|
557
561
|
});
|
|
558
562
|
const rawUv = (0, selected_outline_uv_1.getUvCoordinateForPoint)(outline.points, point);
|
|
559
|
-
const snappedUv =
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
563
|
+
const snappedUv = editorSnapping
|
|
564
|
+
? (0, selected_outline_drag_1.snapSelectedOutlineUv)({
|
|
565
|
+
point,
|
|
566
|
+
points: outline.points,
|
|
567
|
+
uv: rawUv,
|
|
568
|
+
})
|
|
569
|
+
: rawUv;
|
|
564
570
|
const nextValue = (0, selected_outline_uv_1.roundUvCoordinate)((0, selected_outline_uv_1.constrainUv)(snappedUv, handle.fieldSchema), handle.fieldSchema);
|
|
565
571
|
lastValue = nextValue;
|
|
566
572
|
setEffectDragOverrides(handle.nodePath, handle.effectIndex, handle.fieldKey, handle.propStatus.status === 'keyframed'
|
|
@@ -644,6 +650,7 @@ const SelectedUvHandleCircle = ({ handle, nodePathInfo, onDraggingChange, onSele
|
|
|
644
650
|
window.addEventListener('pointercancel', onPointerUp);
|
|
645
651
|
}, [
|
|
646
652
|
clearEffectDragOverrides,
|
|
653
|
+
editorSnapping,
|
|
647
654
|
handle,
|
|
648
655
|
nodePathInfo,
|
|
649
656
|
onDraggingChange,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SnappingProvider = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const editor_snapping_1 = require("../state/editor-snapping");
|
|
7
|
+
const SnappingProvider = ({ children }) => {
|
|
8
|
+
const [editorSnapping, setEditorSnappingState] = (0, react_1.useState)(() => (0, editor_snapping_1.loadEditorSnappingOption)());
|
|
9
|
+
const setEditorSnapping = (0, react_1.useCallback)((newValue) => {
|
|
10
|
+
setEditorSnappingState((prevState) => {
|
|
11
|
+
const newVal = newValue(prevState);
|
|
12
|
+
(0, editor_snapping_1.persistEditorSnappingOption)(newVal);
|
|
13
|
+
return newVal;
|
|
14
|
+
});
|
|
15
|
+
}, []);
|
|
16
|
+
const editorSnappingCtx = (0, react_1.useMemo)(() => {
|
|
17
|
+
return {
|
|
18
|
+
editorSnapping,
|
|
19
|
+
setEditorSnapping,
|
|
20
|
+
};
|
|
21
|
+
}, [editorSnapping, setEditorSnapping]);
|
|
22
|
+
return (jsx_runtime_1.jsx(editor_snapping_1.EditorSnappingContext.Provider, { value: editorSnappingCtx, children: children }));
|
|
23
|
+
};
|
|
24
|
+
exports.SnappingProvider = SnappingProvider;
|