@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
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SnappingToggle = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const no_react_1 = require("remotion/no-react");
|
|
7
|
+
const colors_1 = require("../helpers/colors");
|
|
8
|
+
const use_keybinding_1 = require("../helpers/use-keybinding");
|
|
9
|
+
const magnet_1 = require("../icons/magnet");
|
|
10
|
+
const editor_snapping_1 = require("../state/editor-snapping");
|
|
11
|
+
const ControlButton_1 = require("./ControlButton");
|
|
12
|
+
const SnappingToggle = () => {
|
|
13
|
+
const { editorSnapping, setEditorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
|
|
14
|
+
const onClick = (0, react_1.useCallback)(() => {
|
|
15
|
+
setEditorSnapping((current) => !current);
|
|
16
|
+
}, [setEditorSnapping]);
|
|
17
|
+
const color = editorSnapping ? colors_1.BLUE : colors_1.WHITE;
|
|
18
|
+
const accessibilityLabel = [
|
|
19
|
+
editorSnapping ? 'Disable snapping' : 'Enable snapping',
|
|
20
|
+
(0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? null : '(Shift+M)',
|
|
21
|
+
]
|
|
22
|
+
.filter(no_react_1.NoReactInternals.truthy)
|
|
23
|
+
.join(' ');
|
|
24
|
+
return (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: accessibilityLabel, "aria-label": accessibilityLabel, "aria-pressed": editorSnapping, "aria-keyshortcuts": "Shift+M", onClick: onClick, children: jsx_runtime_1.jsx(magnet_1.MagnetIcon, { style: { width: 17, height: 17 }, fill: color, "aria-hidden": "true", focusable: "false" }) }));
|
|
25
|
+
};
|
|
26
|
+
exports.SnappingToggle = SnappingToggle;
|
|
@@ -12,6 +12,7 @@ const timeline_node_path_key_1 = require("../../helpers/timeline-node-path-key")
|
|
|
12
12
|
const use_keybinding_1 = require("../../helpers/use-keybinding");
|
|
13
13
|
const z_index_1 = require("../../state/z-index");
|
|
14
14
|
const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
|
|
15
|
+
const options_sidebar_tabs_1 = require("../options-sidebar-tabs");
|
|
15
16
|
const get_node_keyframes_1 = require("./get-node-keyframes");
|
|
16
17
|
const get_timeline_easing_segments_1 = require("./get-timeline-easing-segments");
|
|
17
18
|
const timeline_expanded_filter_1 = require("./timeline-expanded-filter");
|
|
@@ -684,6 +685,7 @@ const TimelineSelectionProvider = ({ children }) => {
|
|
|
684
685
|
if (!canSelectItem(item)) {
|
|
685
686
|
return;
|
|
686
687
|
}
|
|
688
|
+
(0, options_sidebar_tabs_1.selectOptionsSidebarInspectorPanel)();
|
|
687
689
|
expandParentsForSelectionItem(item);
|
|
688
690
|
if (options.reveal) {
|
|
689
691
|
requestRevealSelectionItem(item);
|
|
@@ -714,6 +716,9 @@ const TimelineSelectionProvider = ({ children }) => {
|
|
|
714
716
|
if (!items.every(canSelectItem)) {
|
|
715
717
|
return;
|
|
716
718
|
}
|
|
719
|
+
if (items.length > 0) {
|
|
720
|
+
(0, options_sidebar_tabs_1.selectOptionsSidebarInspectorPanel)();
|
|
721
|
+
}
|
|
717
722
|
selectionScope.current = timelineSelectionScope;
|
|
718
723
|
selectionAnchor.current =
|
|
719
724
|
items.length === 0 ? null : items[items.length - 1];
|
|
@@ -8,8 +8,8 @@ const open_in_editor_1 = require("../../helpers/open-in-editor");
|
|
|
8
8
|
const Fieldset_1 = require("../RenderModal/SchemaEditor/Fieldset");
|
|
9
9
|
const source_attribution_1 = require("../Timeline/TimelineStack/source-attribution");
|
|
10
10
|
const container = {
|
|
11
|
-
paddingLeft: Fieldset_1.
|
|
12
|
-
paddingTop: Fieldset_1.
|
|
11
|
+
paddingLeft: (0, Fieldset_1.getSchemaEditorFieldsetPadding)(),
|
|
12
|
+
paddingTop: (0, Fieldset_1.getSchemaEditorFieldsetPadding)() / 2,
|
|
13
13
|
};
|
|
14
14
|
const ClickableFileName = ({ originalFileName, }) => {
|
|
15
15
|
const [titleHovered, setTitleHovered] = (0, react_1.useState)(false);
|
|
@@ -37,15 +37,23 @@ exports.VisualControlsContent = void 0;
|
|
|
37
37
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
38
38
|
const react_1 = __importStar(require("react"));
|
|
39
39
|
const VisualControls_1 = require("../../visual-controls/VisualControls");
|
|
40
|
+
const InspectorPanelLayout_1 = require("../InspectorPanelLayout");
|
|
41
|
+
const Fieldset_1 = require("../RenderModal/SchemaEditor/Fieldset");
|
|
40
42
|
const SchemaSeparationLine_1 = require("../RenderModal/SchemaEditor/SchemaSeparationLine");
|
|
41
43
|
const VisualControlHandle_1 = require("./VisualControlHandle");
|
|
44
|
+
const rootInset = (0, Fieldset_1.getSchemaEditorRootInset)(InspectorPanelLayout_1.INSPECTOR_PANEL_HORIZONTAL_PADDING);
|
|
45
|
+
const container = {
|
|
46
|
+
boxSizing: 'border-box',
|
|
47
|
+
paddingLeft: rootInset,
|
|
48
|
+
paddingRight: rootInset,
|
|
49
|
+
};
|
|
42
50
|
const VisualControlsContent = () => {
|
|
43
51
|
const { handles } = (0, react_1.useContext)(VisualControls_1.VisualControlsContext);
|
|
44
52
|
const entries = Object.entries(handles);
|
|
45
53
|
if (entries.length === 0) {
|
|
46
54
|
return null;
|
|
47
55
|
}
|
|
48
|
-
return (jsx_runtime_1.jsx("div", { children: entries.map(([key, value], i) => {
|
|
56
|
+
return (jsx_runtime_1.jsx("div", { style: container, children: entries.map(([key, value], i) => {
|
|
49
57
|
return (jsx_runtime_1.jsxs(react_1.default.Fragment, { children: [
|
|
50
58
|
jsx_runtime_1.jsx(VisualControlHandle_1.VisualControlHandle, { keyName: key, value: value }), i === entries.length - 1 ? null : jsx_runtime_1.jsx(SchemaSeparationLine_1.SchemaSeparationLine, {})] }, key));
|
|
51
59
|
}) }));
|
|
@@ -8,7 +8,9 @@ const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
|
|
8
8
|
const hasEffectDragType = (dataTransfer) => {
|
|
9
9
|
const types = Array.from(dataTransfer.types);
|
|
10
10
|
const hasExplicitEffectType = types.includes(studio_shared_1.EFFECT_DRAG_MIME_TYPE);
|
|
11
|
-
if (!hasExplicitEffectType &&
|
|
11
|
+
if (!hasExplicitEffectType &&
|
|
12
|
+
(hasNonEffectRemotionDragType(dataTransfer) ||
|
|
13
|
+
hasNonRemotionImportableAssetDragType(dataTransfer))) {
|
|
12
14
|
return false;
|
|
13
15
|
}
|
|
14
16
|
return types.some((type) => type === studio_shared_1.EFFECT_DRAG_MIME_TYPE || isGenericDragType(type));
|
|
@@ -21,14 +23,33 @@ exports.hasExplicitEffectDragType = hasExplicitEffectDragType;
|
|
|
21
23
|
const isGenericDragType = (type) => {
|
|
22
24
|
return type === 'application/json' || type === 'text/plain';
|
|
23
25
|
};
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
const isNonEffectRemotionDragType = (mimeType) => {
|
|
27
|
+
switch (mimeType) {
|
|
28
|
+
case studio_shared_1.EFFECT_DRAG_MIME_TYPE:
|
|
29
|
+
return false;
|
|
30
|
+
case studio_shared_1.ASSET_DRAG_MIME_TYPE:
|
|
31
|
+
case studio_shared_1.COMPOSITION_DRAG_MIME_TYPE:
|
|
32
|
+
case studio_shared_1.COMPONENT_DRAG_MIME_TYPE:
|
|
33
|
+
case studio_shared_1.ELEMENT_DRAG_MIME_TYPE:
|
|
34
|
+
case studio_shared_1.SFX_DRAG_MIME_TYPE:
|
|
35
|
+
return true;
|
|
36
|
+
default:
|
|
37
|
+
mimeType;
|
|
38
|
+
throw new Error(`Unhandled Remotion drag MIME type: ${mimeType}`);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const hasNonEffectRemotionDragType = (dataTransfer) => {
|
|
42
|
+
return Array.from(dataTransfer.types).some((type) => {
|
|
43
|
+
if (!(0, studio_shared_1.isRemotionDragMimeType)(type)) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return isNonEffectRemotionDragType(type);
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
const hasNonRemotionImportableAssetDragType = (dataTransfer) => {
|
|
50
|
+
return Array.from(dataTransfer.types).some((type) => {
|
|
51
|
+
return type === 'Files' || type === 'text/uri-list' || type === 'text/html';
|
|
52
|
+
});
|
|
32
53
|
};
|
|
33
54
|
const getEffectDragData = (dataTransfer) => {
|
|
34
55
|
for (const type of [
|
|
@@ -86,6 +86,6 @@ export declare const insertElement: ({ compositionFile, compositionId, dropPosit
|
|
|
86
86
|
slug: string;
|
|
87
87
|
displayName: string;
|
|
88
88
|
sourceCode: string;
|
|
89
|
-
dimensions: import("@remotion/studio-shared").ComponentDimensions;
|
|
89
|
+
dimensions: import("@remotion/studio-shared").ComponentDimensions | null;
|
|
90
90
|
};
|
|
91
91
|
}) => Promise<void>;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.optionsSidebarTabs = void 0;
|
|
3
|
+
exports.selectOptionsSidebarInspectorPanel = exports.optionsSidebarTabs = void 0;
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
exports.optionsSidebarTabs = (0, react_1.createRef)();
|
|
6
|
+
const selectOptionsSidebarInspectorPanel = () => {
|
|
7
|
+
var _a;
|
|
8
|
+
(_a = exports.optionsSidebarTabs.current) === null || _a === void 0 ? void 0 : _a.selectInspectorPanel();
|
|
9
|
+
};
|
|
10
|
+
exports.selectOptionsSidebarInspectorPanel = selectOptionsSidebarInspectorPanel;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Guide } from '../state/editor-guides';
|
|
2
|
+
import type { SelectedOutline } from './selected-outline-geometry';
|
|
3
|
+
export declare const selectedOutlineSnapThresholdPx = 10;
|
|
4
|
+
export declare const selectedOutlineSnapIndicatorColor = "#ff00ff";
|
|
5
|
+
export type SelectedOutlineSnapAxis = 'x' | 'y';
|
|
6
|
+
export type SelectedOutlineSnapTargetType = 'canvas-left' | 'canvas-right' | 'canvas-top' | 'canvas-bottom' | 'canvas-horizontal-center' | 'canvas-vertical-center' | 'guide-vertical' | 'guide-horizontal';
|
|
7
|
+
export type SelectedOutlineSnapTarget = {
|
|
8
|
+
readonly axis: SelectedOutlineSnapAxis;
|
|
9
|
+
readonly position: number;
|
|
10
|
+
readonly type: SelectedOutlineSnapTargetType;
|
|
11
|
+
};
|
|
12
|
+
export type SelectedOutlineSnapEdge = 'left' | 'right' | 'center-x' | 'top' | 'bottom' | 'center-y';
|
|
13
|
+
export type SelectedOutlineSnapPoint = {
|
|
14
|
+
readonly distance: number;
|
|
15
|
+
readonly edge: SelectedOutlineSnapEdge;
|
|
16
|
+
readonly target: SelectedOutlineSnapTarget;
|
|
17
|
+
};
|
|
18
|
+
export type SelectedOutlineSnapResult = {
|
|
19
|
+
readonly activeSnapPoints: readonly SelectedOutlineSnapPoint[];
|
|
20
|
+
readonly snapOffsetX: number | null;
|
|
21
|
+
readonly snapOffsetY: number | null;
|
|
22
|
+
};
|
|
23
|
+
export declare const getSelectedOutlineSnapTargets: ({ compositionHeight, compositionWidth, guides, }: {
|
|
24
|
+
readonly compositionHeight: number;
|
|
25
|
+
readonly compositionWidth: number;
|
|
26
|
+
readonly guides: readonly Guide[];
|
|
27
|
+
}) => readonly SelectedOutlineSnapTarget[];
|
|
28
|
+
export declare const findSelectedOutlineSnap: ({ allowX, allowY, deltaX, deltaY, outlines, scale, targets, }: {
|
|
29
|
+
readonly allowX: boolean;
|
|
30
|
+
readonly allowY: boolean;
|
|
31
|
+
readonly deltaX: number;
|
|
32
|
+
readonly deltaY: number;
|
|
33
|
+
readonly outlines: readonly SelectedOutline[];
|
|
34
|
+
readonly scale: number;
|
|
35
|
+
readonly targets: readonly SelectedOutlineSnapTarget[];
|
|
36
|
+
}) => SelectedOutlineSnapResult;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findSelectedOutlineSnap = exports.getSelectedOutlineSnapTargets = exports.selectedOutlineSnapIndicatorColor = exports.selectedOutlineSnapThresholdPx = void 0;
|
|
4
|
+
exports.selectedOutlineSnapThresholdPx = 10;
|
|
5
|
+
exports.selectedOutlineSnapIndicatorColor = '#ff00ff';
|
|
6
|
+
const EPSILON = 0.000001;
|
|
7
|
+
const getSelectedOutlineSnapTargets = ({ compositionHeight, compositionWidth, guides, }) => {
|
|
8
|
+
return [
|
|
9
|
+
{ axis: 'x', position: 0, type: 'canvas-left' },
|
|
10
|
+
{
|
|
11
|
+
axis: 'x',
|
|
12
|
+
position: compositionWidth / 2,
|
|
13
|
+
type: 'canvas-horizontal-center',
|
|
14
|
+
},
|
|
15
|
+
{ axis: 'x', position: compositionWidth, type: 'canvas-right' },
|
|
16
|
+
{ axis: 'y', position: 0, type: 'canvas-top' },
|
|
17
|
+
{
|
|
18
|
+
axis: 'y',
|
|
19
|
+
position: compositionHeight / 2,
|
|
20
|
+
type: 'canvas-vertical-center',
|
|
21
|
+
},
|
|
22
|
+
{ axis: 'y', position: compositionHeight, type: 'canvas-bottom' },
|
|
23
|
+
...guides.flatMap((guide) => {
|
|
24
|
+
if (!guide.show) {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
return [
|
|
28
|
+
guide.orientation === 'vertical'
|
|
29
|
+
? {
|
|
30
|
+
axis: 'x',
|
|
31
|
+
position: guide.position,
|
|
32
|
+
type: 'guide-vertical',
|
|
33
|
+
}
|
|
34
|
+
: {
|
|
35
|
+
axis: 'y',
|
|
36
|
+
position: guide.position,
|
|
37
|
+
type: 'guide-horizontal',
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
}),
|
|
41
|
+
];
|
|
42
|
+
};
|
|
43
|
+
exports.getSelectedOutlineSnapTargets = getSelectedOutlineSnapTargets;
|
|
44
|
+
const getSelectedOutlineBounds = ({ deltaX, deltaY, outlines, scale, }) => {
|
|
45
|
+
if (outlines.length === 0) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const points = outlines.flatMap((outline) => outline.points);
|
|
49
|
+
const left = Math.min(...points.map((point) => point.x)) / scale + deltaX;
|
|
50
|
+
const right = Math.max(...points.map((point) => point.x)) / scale + deltaX;
|
|
51
|
+
const top = Math.min(...points.map((point) => point.y)) / scale + deltaY;
|
|
52
|
+
const bottom = Math.max(...points.map((point) => point.y)) / scale + deltaY;
|
|
53
|
+
return {
|
|
54
|
+
left,
|
|
55
|
+
right,
|
|
56
|
+
top,
|
|
57
|
+
bottom,
|
|
58
|
+
centerX: left + (right - left) / 2,
|
|
59
|
+
centerY: top + (bottom - top) / 2,
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
const canSnapEdgeToTarget = (edge, target) => {
|
|
63
|
+
if (target.type === 'canvas-horizontal-center') {
|
|
64
|
+
return edge === 'center-x';
|
|
65
|
+
}
|
|
66
|
+
if (target.type === 'canvas-vertical-center') {
|
|
67
|
+
return edge === 'center-y';
|
|
68
|
+
}
|
|
69
|
+
if (target.type === 'canvas-left' || target.type === 'canvas-right') {
|
|
70
|
+
return edge === 'left' || edge === 'right';
|
|
71
|
+
}
|
|
72
|
+
if (target.type === 'guide-vertical') {
|
|
73
|
+
return edge === 'left' || edge === 'right' || edge === 'center-x';
|
|
74
|
+
}
|
|
75
|
+
if (target.type === 'canvas-top' || target.type === 'canvas-bottom') {
|
|
76
|
+
return edge === 'top' || edge === 'bottom';
|
|
77
|
+
}
|
|
78
|
+
return edge === 'top' || edge === 'bottom' || edge === 'center-y';
|
|
79
|
+
};
|
|
80
|
+
const findBestSnapForAxis = ({ edges, targets, threshold, }) => {
|
|
81
|
+
var _a;
|
|
82
|
+
let bestDistance = Infinity;
|
|
83
|
+
let bestSnaps = [];
|
|
84
|
+
for (const target of targets) {
|
|
85
|
+
for (const edge of edges) {
|
|
86
|
+
if (!canSnapEdgeToTarget(edge.edge, target)) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const distance = Math.abs(edge.position - target.position);
|
|
90
|
+
if (distance > threshold || distance > bestDistance + EPSILON) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (distance < bestDistance - EPSILON) {
|
|
94
|
+
bestSnaps = [];
|
|
95
|
+
bestDistance = distance;
|
|
96
|
+
}
|
|
97
|
+
bestSnaps.push({
|
|
98
|
+
offset: target.position - edge.position,
|
|
99
|
+
snapPoint: {
|
|
100
|
+
distance,
|
|
101
|
+
edge: edge.edge,
|
|
102
|
+
target,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (bestSnaps.length > 1) {
|
|
108
|
+
const centerSnap = bestSnaps.find((snap) => snap.snapPoint.target.type === 'canvas-horizontal-center' ||
|
|
109
|
+
snap.snapPoint.target.type === 'canvas-vertical-center');
|
|
110
|
+
if (centerSnap) {
|
|
111
|
+
return centerSnap;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return (_a = bestSnaps[0]) !== null && _a !== void 0 ? _a : null;
|
|
115
|
+
};
|
|
116
|
+
const findSelectedOutlineSnap = ({ allowX, allowY, deltaX, deltaY, outlines, scale, targets, }) => {
|
|
117
|
+
var _a, _b, _c, _d;
|
|
118
|
+
const bounds = getSelectedOutlineBounds({ deltaX, deltaY, outlines, scale });
|
|
119
|
+
if (bounds === null) {
|
|
120
|
+
return {
|
|
121
|
+
activeSnapPoints: [],
|
|
122
|
+
snapOffsetX: null,
|
|
123
|
+
snapOffsetY: null,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
const threshold = exports.selectedOutlineSnapThresholdPx / scale;
|
|
127
|
+
const snapX = allowX
|
|
128
|
+
? findBestSnapForAxis({
|
|
129
|
+
edges: [
|
|
130
|
+
{ edge: 'left', position: bounds.left },
|
|
131
|
+
{ edge: 'center-x', position: bounds.centerX },
|
|
132
|
+
{ edge: 'right', position: bounds.right },
|
|
133
|
+
],
|
|
134
|
+
targets: targets.filter((target) => target.axis === 'x'),
|
|
135
|
+
threshold,
|
|
136
|
+
})
|
|
137
|
+
: null;
|
|
138
|
+
const snapY = allowY
|
|
139
|
+
? findBestSnapForAxis({
|
|
140
|
+
edges: [
|
|
141
|
+
{ edge: 'top', position: bounds.top },
|
|
142
|
+
{ edge: 'center-y', position: bounds.centerY },
|
|
143
|
+
{ edge: 'bottom', position: bounds.bottom },
|
|
144
|
+
],
|
|
145
|
+
targets: targets.filter((target) => target.axis === 'y'),
|
|
146
|
+
threshold,
|
|
147
|
+
})
|
|
148
|
+
: null;
|
|
149
|
+
return {
|
|
150
|
+
activeSnapPoints: [
|
|
151
|
+
(_a = snapX === null || snapX === void 0 ? void 0 : snapX.snapPoint) !== null && _a !== void 0 ? _a : null,
|
|
152
|
+
(_b = snapY === null || snapY === void 0 ? void 0 : snapY.snapPoint) !== null && _b !== void 0 ? _b : null,
|
|
153
|
+
].filter((snapPoint) => snapPoint !== null),
|
|
154
|
+
snapOffsetX: (_c = snapX === null || snapX === void 0 ? void 0 : snapX.offset) !== null && _c !== void 0 ? _c : null,
|
|
155
|
+
snapOffsetY: (_d = snapY === null || snapY === void 0 ? void 0 : snapY.offset) !== null && _d !== void 0 ? _d : null,
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
exports.findSelectedOutlineSnap = findSelectedOutlineSnap;
|