@yuzhouu/canvas-kit 0.1.2
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/README.md +145 -0
- package/_vendor/canvas-core/bindings/BindingUtil.ts +92 -0
- package/_vendor/canvas-core/bindings/BindingUtilRegistry.ts +22 -0
- package/_vendor/canvas-core/bindings/arrow/arrowBindingHelpers.ts +52 -0
- package/_vendor/canvas-core/contextMenu.ts +85 -0
- package/_vendor/canvas-core/editor/Editor.ts +2614 -0
- package/_vendor/canvas-core/editor/HistoryManager.ts +83 -0
- package/_vendor/canvas-core/editor/StateNode.ts +162 -0
- package/_vendor/canvas-core/editor/camera.ts +6 -0
- package/_vendor/canvas-core/editor/clipboard.ts +478 -0
- package/_vendor/canvas-core/editor/commands.ts +833 -0
- package/_vendor/canvas-core/editor/edgeScroll.ts +37 -0
- package/_vendor/canvas-core/editor/editorComputedHelpers.ts +257 -0
- package/_vendor/canvas-core/editor/editorSelectionTransforms.ts +116 -0
- package/_vendor/canvas-core/editor/events.ts +93 -0
- package/_vendor/canvas-core/editor/index.ts +12 -0
- package/_vendor/canvas-core/editor/interactions.ts +101 -0
- package/_vendor/canvas-core/editor/internal.ts +22 -0
- package/_vendor/canvas-core/editor/managers/BindingManager.ts +262 -0
- package/_vendor/canvas-core/editor/managers/CameraManager.ts +147 -0
- package/_vendor/canvas-core/editor/managers/ClipboardManager.ts +32 -0
- package/_vendor/canvas-core/editor/managers/DocumentSnapshotManager.ts +256 -0
- package/_vendor/canvas-core/editor/managers/InputsManager.ts +319 -0
- package/_vendor/canvas-core/editor/managers/InteractionTransientManager.ts +218 -0
- package/_vendor/canvas-core/editor/managers/QueryManager.ts +837 -0
- package/_vendor/canvas-core/editor/managers/RenderWindowManager.ts +347 -0
- package/_vendor/canvas-core/editor/managers/SelectionLayoutManager.ts +196 -0
- package/_vendor/canvas-core/editor/managers/SelectionManager.ts +98 -0
- package/_vendor/canvas-core/editor/managers/SelectionOverlayManager.ts +308 -0
- package/_vendor/canvas-core/editor/managers/ShapeEditingManager.ts +226 -0
- package/_vendor/canvas-core/editor/managers/ShapeGeometryManager.ts +162 -0
- package/_vendor/canvas-core/editor/managers/ShapeHierarchyManager.ts +797 -0
- package/_vendor/canvas-core/editor/managers/SideEffectManager.ts +83 -0
- package/_vendor/canvas-core/editor/managers/SnapManager.ts +433 -0
- package/_vendor/canvas-core/editor/managers/SnapSnapshotBuilder.ts +430 -0
- package/_vendor/canvas-core/editor/managers/SpatialIndexManager.ts +354 -0
- package/_vendor/canvas-core/editor/managers/ToolManager.ts +81 -0
- package/_vendor/canvas-core/editor/managers/queryState.ts +583 -0
- package/_vendor/canvas-core/editor/managers/selectionGeometry.ts +287 -0
- package/_vendor/canvas-core/editor/managers/shapeOrder.ts +350 -0
- package/_vendor/canvas-core/editor/managers/shapeReparenting.ts +160 -0
- package/_vendor/canvas-core/editor/managers/snapCalculations.ts +412 -0
- package/_vendor/canvas-core/editor/managers/snapGeometry.ts +202 -0
- package/_vendor/canvas-core/editor/managers/snapIndicators.ts +403 -0
- package/_vendor/canvas-core/editor/managers/snapTypes.ts +122 -0
- package/_vendor/canvas-core/editor/queries/shapeTransforms.ts +171 -0
- package/_vendor/canvas-core/editor/renderWindow.ts +439 -0
- package/_vendor/canvas-core/editor/resizeGeometry.ts +654 -0
- package/_vendor/canvas-core/editor/selection.ts +489 -0
- package/_vendor/canvas-core/editor/selectionHandleInteractions.ts +43 -0
- package/_vendor/canvas-core/editor/selectionOverlay.ts +567 -0
- package/_vendor/canvas-core/exports/integrity.ts +174 -0
- package/_vendor/canvas-core/exports/svg.ts +494 -0
- package/_vendor/canvas-core/geometry/Box.ts +80 -0
- package/_vendor/canvas-core/geometry/Ellipse2d.ts +67 -0
- package/_vendor/canvas-core/geometry/Geometry2d.ts +52 -0
- package/_vendor/canvas-core/geometry/Mat.ts +92 -0
- package/_vendor/canvas-core/geometry/Polyline2d.ts +63 -0
- package/_vendor/canvas-core/geometry/Rectangle2d.ts +64 -0
- package/_vendor/canvas-core/geometry/Vec.ts +123 -0
- package/_vendor/canvas-core/geometry/index.ts +13 -0
- package/_vendor/canvas-core/geometry/segments.ts +65 -0
- package/_vendor/canvas-core/index.ts +391 -0
- package/_vendor/canvas-core/plugins/index.ts +5 -0
- package/_vendor/canvas-core/plugins/types.ts +53 -0
- package/_vendor/canvas-core/reactivity.ts +16 -0
- package/_vendor/canvas-core/schema/records.ts +221 -0
- package/_vendor/canvas-core/schema/snapshots.ts +527 -0
- package/_vendor/canvas-core/shapes/ShapeUtil.ts +516 -0
- package/_vendor/canvas-core/shapes/ShapeUtilRegistry.ts +26 -0
- package/_vendor/canvas-core/shapes/capabilities.ts +67 -0
- package/_vendor/canvas-core/shapes/types.ts +20 -0
- package/_vendor/canvas-core/toolbar.ts +148 -0
- package/_vendor/canvas-core/tools/hand/HandTool.ts +75 -0
- package/_vendor/canvas-core/tools/index.ts +2 -0
- package/_vendor/canvas-core/tools/select/SelectTool.ts +33 -0
- package/_vendor/canvas-core/tools/select/selectContainment.ts +104 -0
- package/_vendor/canvas-core/tools/select/selectToolHelpers.ts +801 -0
- package/_vendor/canvas-core/tools/select/states/BrushingState.ts +145 -0
- package/_vendor/canvas-core/tools/select/states/DraggingSelectionHandleInteractionState.ts +116 -0
- package/_vendor/canvas-core/tools/select/states/IdleState.ts +159 -0
- package/_vendor/canvas-core/tools/select/states/PointingCanvasState.ts +41 -0
- package/_vendor/canvas-core/tools/select/states/PointingResizeHandleState.ts +78 -0
- package/_vendor/canvas-core/tools/select/states/PointingRotateHandleState.ts +64 -0
- package/_vendor/canvas-core/tools/select/states/PointingSelectionHandleInteractionState.ts +34 -0
- package/_vendor/canvas-core/tools/select/states/PointingShapeState.ts +140 -0
- package/_vendor/canvas-core/tools/select/states/ResizingState.ts +171 -0
- package/_vendor/canvas-core/tools/select/states/RotatingState.ts +124 -0
- package/_vendor/canvas-core/tools/select/states/SelectStateNode.ts +128 -0
- package/_vendor/canvas-core/tools/select/states/TranslatingState.ts +139 -0
- package/_vendor/canvas-core/tools/select/states/index.ts +11 -0
- package/_vendor/canvas-plugin-api/feature.ts +204 -0
- package/_vendor/canvas-plugin-api/index.ts +142 -0
- package/_vendor/canvas-product-react/api/apiRegistry.ts +35 -0
- package/_vendor/canvas-product-react/api/canvasProductApi.ts +422 -0
- package/_vendor/canvas-product-react/api/index.ts +31 -0
- package/_vendor/canvas-product-react/capabilities/clipboard/clipboardService.ts +36 -0
- package/_vendor/canvas-product-react/capabilities/clipboard/systemClipboard.ts +245 -0
- package/_vendor/canvas-product-react/capabilities/context-menu/systemContextMenu.ts +396 -0
- package/_vendor/canvas-product-react/capabilities/context-menu/useContextMenuSurface.ts +59 -0
- package/_vendor/canvas-product-react/capabilities/export/useSvgExport.ts +156 -0
- package/_vendor/canvas-product-react/capabilities/history/useHistoryControls.ts +23 -0
- package/_vendor/canvas-product-react/capabilities/pages/usePageControls.ts +41 -0
- package/_vendor/canvas-product-react/capabilities/toolbar/systemToolbar.ts +490 -0
- package/_vendor/canvas-product-react/capabilities/toolbar/useToolbarSurfaces.ts +92 -0
- package/_vendor/canvas-product-react/capabilities/zoom/useZoomControls.ts +27 -0
- package/_vendor/canvas-product-react/index.ts +84 -0
- package/_vendor/canvas-product-react/persistence/index.ts +18 -0
- package/_vendor/canvas-product-react/persistence/localSnapshotPersistence.ts +294 -0
- package/_vendor/canvas-product-react/runtime/CanvasProductRoot.tsx +250 -0
- package/_vendor/canvas-product-react/runtime/productDefinition.ts +72 -0
- package/_vendor/canvas-product-react/runtime/productServices.ts +96 -0
- package/_vendor/canvas-react/components/CanvasView.tsx +796 -0
- package/_vendor/canvas-react/components/OverlayLayer.tsx +879 -0
- package/_vendor/canvas-react/components/PageSpace.tsx +34 -0
- package/_vendor/canvas-react/components/ShapeLayer.tsx +428 -0
- package/_vendor/canvas-react/components/index.ts +4 -0
- package/_vendor/canvas-react/hooks/useEditor.ts +11 -0
- package/_vendor/canvas-react/hooks/useValue.ts +14 -0
- package/_vendor/canvas-react/host/CanvasRendererRegistryContext.tsx +14 -0
- package/_vendor/canvas-react/host/contextMenuRegistry.ts +61 -0
- package/_vendor/canvas-react/host/domEventGuards.ts +61 -0
- package/_vendor/canvas-react/host/index.ts +38 -0
- package/_vendor/canvas-react/host/pluginHost.ts +635 -0
- package/_vendor/canvas-react/host/rendererRegistry.tsx +58 -0
- package/_vendor/canvas-react/host/toolbarRegistry.ts +100 -0
- package/_vendor/canvas-react/index.ts +3 -0
- package/_vendor/plugin-arrow/ArrowBindingUtil.ts +239 -0
- package/_vendor/plugin-arrow/ArrowShapeUtil.ts +311 -0
- package/_vendor/plugin-arrow/ArrowTool.ts +208 -0
- package/_vendor/plugin-arrow/arrowGeometry.ts +441 -0
- package/_vendor/plugin-arrow/arrowTerminalBindingResolver.ts +253 -0
- package/_vendor/plugin-arrow/arrowTerminalCommands.ts +230 -0
- package/_vendor/plugin-arrow/canvas.tsx +92 -0
- package/_vendor/plugin-arrow/core.ts +409 -0
- package/_vendor/plugin-arrow/feature.ts +20 -0
- package/_vendor/plugin-arrow/index.ts +28 -0
- package/_vendor/plugin-arrow/selectionHandleInteractions.ts +154 -0
- package/_vendor/plugin-arrow/types.ts +63 -0
- package/_vendor/plugin-draw/DrawShapeRenderer.tsx +60 -0
- package/_vendor/plugin-draw/DrawShapeUtil.ts +372 -0
- package/_vendor/plugin-draw/DrawTool.ts +444 -0
- package/_vendor/plugin-draw/canvas.tsx +24 -0
- package/_vendor/plugin-draw/core.ts +515 -0
- package/_vendor/plugin-draw/drawGeometry.ts +491 -0
- package/_vendor/plugin-draw/drawHitTest.ts +271 -0
- package/_vendor/plugin-draw/drawInterpolation.ts +250 -0
- package/_vendor/plugin-draw/drawPath.ts +550 -0
- package/_vendor/plugin-draw/drawSegments.ts +106 -0
- package/_vendor/plugin-draw/drawSelectionTransform.ts +67 -0
- package/_vendor/plugin-draw/drawShapeGeometry.ts +307 -0
- package/_vendor/plugin-draw/drawStrokeGeometry.ts +454 -0
- package/_vendor/plugin-draw/feature.ts +20 -0
- package/_vendor/plugin-draw/index.ts +31 -0
- package/_vendor/plugin-draw/types.ts +36 -0
- package/_vendor/plugin-eraser/EraserTool.ts +297 -0
- package/_vendor/plugin-eraser/canvas.tsx +616 -0
- package/_vendor/plugin-eraser/core.ts +49 -0
- package/_vendor/plugin-eraser/feature.ts +20 -0
- package/_vendor/plugin-eraser/index.ts +4 -0
- package/_vendor/plugin-frame/FrameShapeUtil.ts +173 -0
- package/_vendor/plugin-frame/FrameTool.ts +225 -0
- package/_vendor/plugin-frame/canvas.tsx +75 -0
- package/_vendor/plugin-frame/core.ts +534 -0
- package/_vendor/plugin-frame/feature.ts +20 -0
- package/_vendor/plugin-frame/index.ts +6 -0
- package/_vendor/plugin-geo/GeoShapeUtil.ts +463 -0
- package/_vendor/plugin-geo/GeoTools.ts +247 -0
- package/_vendor/plugin-geo/canvas.tsx +90 -0
- package/_vendor/plugin-geo/core.ts +495 -0
- package/_vendor/plugin-geo/feature.ts +20 -0
- package/_vendor/plugin-geo/index.ts +7 -0
- package/_vendor/plugin-geo/types.ts +27 -0
- package/_vendor/plugin-group/GroupShapeUtil.ts +59 -0
- package/_vendor/plugin-group/canvas.tsx +59 -0
- package/_vendor/plugin-group/core.ts +40 -0
- package/_vendor/plugin-group/feature.ts +20 -0
- package/_vendor/plugin-group/index.ts +5 -0
- package/_vendor/plugin-image/ImageShapeUtil.ts +95 -0
- package/_vendor/plugin-image/canvas.tsx +212 -0
- package/_vendor/plugin-image/core.ts +542 -0
- package/_vendor/plugin-image/crop.ts +770 -0
- package/_vendor/plugin-image/cropInteractions.ts +350 -0
- package/_vendor/plugin-image/cropSession.ts +38 -0
- package/_vendor/plugin-image/feature.ts +20 -0
- package/_vendor/plugin-image/index.ts +29 -0
- package/_vendor/plugin-image/types.ts +55 -0
- package/_vendor/plugin-image-product-react/ImageImportController.tsx +143 -0
- package/_vendor/plugin-image-product-react/imageAssetService.ts +52 -0
- package/_vendor/plugin-image-product-react/imageBlobStore.ts +315 -0
- package/_vendor/plugin-image-product-react/imageHostActions.ts +438 -0
- package/_vendor/plugin-image-product-react/imageProductApi.ts +88 -0
- package/_vendor/plugin-image-product-react/imageToolbarHostBridge.ts +48 -0
- package/_vendor/plugin-image-product-react/imageToolbarRuntime.ts +21 -0
- package/_vendor/plugin-image-product-react/index.ts +60 -0
- package/_vendor/plugin-image-product-react/snapshotGuards.ts +33 -0
- package/_vendor/plugin-image-product-react/svgImageAssetInliner.ts +54 -0
- package/_vendor/plugin-image-product-react/useImageImport.ts +64 -0
- package/_vendor/plugin-laser/LaserTool.ts +154 -0
- package/_vendor/plugin-laser/canvas.tsx +645 -0
- package/_vendor/plugin-laser/core.ts +49 -0
- package/_vendor/plugin-laser/feature.ts +20 -0
- package/_vendor/plugin-laser/index.ts +4 -0
- package/_vendor/plugin-text/ArrowLabelBindingUtil.ts +336 -0
- package/_vendor/plugin-text/GeoLabelBindingUtil.ts +391 -0
- package/_vendor/plugin-text/TextShapeSvgExporter.ts +101 -0
- package/_vendor/plugin-text/TextShapeUtil.ts +284 -0
- package/_vendor/plugin-text/TextTool.ts +228 -0
- package/_vendor/plugin-text/canvas.tsx +115 -0
- package/_vendor/plugin-text/core.ts +422 -0
- package/_vendor/plugin-text/feature.ts +20 -0
- package/_vendor/plugin-text/host/RichTextEditingBox.tsx +144 -0
- package/_vendor/plugin-text/host/RichTextToolbar.tsx +266 -0
- package/_vendor/plugin-text/host/TiptapTextEditor.tsx +191 -0
- package/_vendor/plugin-text/host/richTextRendering.tsx +49 -0
- package/_vendor/plugin-text/host/textDomSelection.ts +93 -0
- package/_vendor/plugin-text/host/textEditingBoxStyle.ts +36 -0
- package/_vendor/plugin-text/host/textEntryFocus.ts +307 -0
- package/_vendor/plugin-text/host/textFontLoader.ts +149 -0
- package/_vendor/plugin-text/host/textMeasurement.ts +258 -0
- package/_vendor/plugin-text/host/textMeasurementSync.ts +77 -0
- package/_vendor/plugin-text/host/textRangeSelection.ts +134 -0
- package/_vendor/plugin-text/host/textShapeRendererRuntime.tsx +89 -0
- package/_vendor/plugin-text/host/textShapeSync.ts +173 -0
- package/_vendor/plugin-text/host/tiptapTextEditorController.ts +148 -0
- package/_vendor/plugin-text/index.ts +18 -0
- package/_vendor/plugin-text/richTextUtils.ts +259 -0
- package/_vendor/plugin-text/textInteractions.ts +366 -0
- package/_vendor/plugin-text/textLabelHelpers.ts +235 -0
- package/_vendor/plugin-text/textShapeHelpers.ts +123 -0
- package/_vendor/plugin-text/textStyle.ts +96 -0
- package/_vendor/plugin-text/textTypes.ts +48 -0
- package/_vendor/signals/atom.ts +74 -0
- package/_vendor/signals/computed.ts +132 -0
- package/_vendor/signals/core.ts +130 -0
- package/_vendor/signals/effect.ts +117 -0
- package/_vendor/signals/index.ts +9 -0
- package/_vendor/signals/types.ts +17 -0
- package/_vendor/store/Store.ts +171 -0
- package/_vendor/store/diff.ts +229 -0
- package/_vendor/store/history.ts +177 -0
- package/_vendor/store/index.ts +32 -0
- package/_vendor/store/types.ts +37 -0
- package/api/canvasKitApi.d.ts +29 -0
- package/index.css +3 -0
- package/index.d.ts +16 -0
- package/index.mjs +1 -0
- package/internal-modules.d.ts +187 -0
- package/package.json +48 -0
- package/product/Shell.d.ts +19 -0
- package/product/chromeContext.d.ts +70 -0
- package/product/createCanvasKitEditor.d.ts +6 -0
- package/product/index.d.ts +7 -0
- package/product/persistence.d.ts +3 -0
- package/product/product.d.ts +22 -0
- package/product/useCanvasClipboardShortcuts.d.ts +6 -0
- package/product-iyBbEPIs.mjs +4 -0
- package/product.mjs +1 -0
- package/standard/extensions.d.ts +1 -0
- package/standard/index.d.ts +3 -0
- package/standard/standardApi.d.ts +91 -0
- package/standard-BmrxwqpJ.mjs +44 -0
- package/standard.mjs +1 -0
|
@@ -0,0 +1,801 @@
|
|
|
1
|
+
import { Box } from "../../geometry/Box";
|
|
2
|
+
import { Vec } from "../../geometry/Vec";
|
|
3
|
+
import type { ShapeUpdate } from "../../editor/commands";
|
|
4
|
+
import type { Editor } from "../../editor/Editor";
|
|
5
|
+
import { getEdgeScrollDelta } from "../../editor/edgeScroll";
|
|
6
|
+
import type { PointerEditorEvent, TickEditorEvent } from "../../editor/events";
|
|
7
|
+
import {
|
|
8
|
+
mapSelectionLocalBoundsBetweenBounds,
|
|
9
|
+
rotateSelectionPagePoint,
|
|
10
|
+
selectionLocalPointToPagePoint,
|
|
11
|
+
} from "../../editor/selection";
|
|
12
|
+
import {
|
|
13
|
+
selectionResizeHandleMovesBottomEdge,
|
|
14
|
+
selectionResizeHandleMovesLeftEdge,
|
|
15
|
+
selectionResizeHandleMovesRightEdge,
|
|
16
|
+
selectionResizeHandleMovesTopEdge,
|
|
17
|
+
} from "../../editor/resizeGeometry";
|
|
18
|
+
import type {
|
|
19
|
+
SelectionResizeHandleId,
|
|
20
|
+
SelectionResizePointShapeSnapshot,
|
|
21
|
+
SelectionResizeShapeSnapshot,
|
|
22
|
+
SelectionRotationTransform,
|
|
23
|
+
SelectionRotatePointShapeSnapshot,
|
|
24
|
+
SelectionRotateShapeSnapshot,
|
|
25
|
+
} from "../../editor/selection";
|
|
26
|
+
import type {
|
|
27
|
+
HandleSnapSnapshot,
|
|
28
|
+
ResizeSnapSnapshot,
|
|
29
|
+
TranslateSnapSnapshot,
|
|
30
|
+
} from "../../editor/managers/snapTypes";
|
|
31
|
+
import type { SelectionHandleInteractionSession } from "../../editor/selectionHandleInteractions";
|
|
32
|
+
import type { ShapeId, ShapeParentId, ShapeRecord } from "../../schema/records";
|
|
33
|
+
|
|
34
|
+
export const DRAG_START_DISTANCE = 3;
|
|
35
|
+
export const DRAG_START_DISTANCE_SQUARED = DRAG_START_DISTANCE * DRAG_START_DISTANCE;
|
|
36
|
+
export const ROTATION_SNAP_STEP = (Math.PI / 180) * 15;
|
|
37
|
+
export const ROTATION_SOFT_SNAP_STEP = Math.PI / 2;
|
|
38
|
+
export const ROTATION_SOFT_SNAP_THRESHOLD = (Math.PI / 180) * 5;
|
|
39
|
+
export const ROTATION_SOFT_SNAP_MAX_SCREEN_VELOCITY = 0.5;
|
|
40
|
+
export const GROUP_CHILD_QUICK_SELECT_DURATION_MS = 250;
|
|
41
|
+
export const TRANSLATE_SNAP_DISTANCE_SCREEN = 8;
|
|
42
|
+
export const TRANSLATE_SNAP_MAX_SCREEN_VELOCITY = 0.5;
|
|
43
|
+
export const RESIZE_SNAP_DISTANCE_SCREEN = 8;
|
|
44
|
+
export const HANDLE_SNAP_DISTANCE_SCREEN = 8;
|
|
45
|
+
export const TRANSLATE_HISTORY_MARK = "select.translate";
|
|
46
|
+
export const RESIZE_HISTORY_MARK = "select.resize";
|
|
47
|
+
export const ROTATE_HISTORY_MARK = "select.rotate";
|
|
48
|
+
|
|
49
|
+
export type TranslateAxis = "x" | "y";
|
|
50
|
+
|
|
51
|
+
export interface PointingCanvasInfo {
|
|
52
|
+
originPagePoint: Vec;
|
|
53
|
+
previousSelection: ShapeId[];
|
|
54
|
+
additiveSelection: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface PointingShapeInfo {
|
|
58
|
+
shapeId: ShapeId;
|
|
59
|
+
translateTargetId: ShapeId;
|
|
60
|
+
originPagePoint: Vec;
|
|
61
|
+
originTimestamp: number;
|
|
62
|
+
previousSelection: ShapeId[];
|
|
63
|
+
additiveSelection: boolean;
|
|
64
|
+
wasSelected: boolean;
|
|
65
|
+
fromSelectionBounds: boolean;
|
|
66
|
+
quickClickSelectionTargetId: ShapeId | null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface TranslatingShapeSnapshot {
|
|
70
|
+
id: ShapeId;
|
|
71
|
+
x: number;
|
|
72
|
+
y: number;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface TranslatingInfo {
|
|
76
|
+
originPagePoint: Vec;
|
|
77
|
+
previousSelection: ShapeId[];
|
|
78
|
+
selectedShapeIds: ShapeId[];
|
|
79
|
+
startBounds: Box | null;
|
|
80
|
+
snapSnapshot: TranslateSnapSnapshot;
|
|
81
|
+
snapRotation: number;
|
|
82
|
+
selectedShapes: TranslatingShapeSnapshot[];
|
|
83
|
+
updates: ShapeUpdate[];
|
|
84
|
+
lockedAxis: TranslateAxis | null;
|
|
85
|
+
lastDeltaX: number;
|
|
86
|
+
lastDeltaY: number;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface BrushInfo {
|
|
90
|
+
originPagePoint: Vec;
|
|
91
|
+
previousSelection: ShapeId[];
|
|
92
|
+
additiveSelection: boolean;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface PointingResizeHandleInfo {
|
|
96
|
+
handleId: SelectionResizeHandleId;
|
|
97
|
+
originPagePoint: Vec;
|
|
98
|
+
cursorHandleOffset: Vec;
|
|
99
|
+
previousSelection: ShapeId[];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface ResizingInfo extends PointingResizeHandleInfo {
|
|
103
|
+
startBounds: Box;
|
|
104
|
+
rotation: number;
|
|
105
|
+
rotationCenter: Vec;
|
|
106
|
+
aspectRatio: number;
|
|
107
|
+
snapSnapshot: ResizeSnapSnapshot;
|
|
108
|
+
shapes: SelectionResizeShapeSnapshot[];
|
|
109
|
+
pointShapes: SelectionResizePointShapeSnapshot[];
|
|
110
|
+
updates: ShapeUpdate[];
|
|
111
|
+
aspectRatioLockOverride: boolean | null;
|
|
112
|
+
lastPagePointX: number;
|
|
113
|
+
lastPagePointY: number;
|
|
114
|
+
lastShiftKey: boolean;
|
|
115
|
+
lastAltKey: boolean;
|
|
116
|
+
lastAccelKey: boolean;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface PointingRotateHandleInfo {
|
|
120
|
+
originPagePoint: Vec;
|
|
121
|
+
previousSelection: ShapeId[];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface RotatingInfo extends PointingRotateHandleInfo {
|
|
125
|
+
center: Vec;
|
|
126
|
+
startAngle: number;
|
|
127
|
+
initialSelectionRotation: number;
|
|
128
|
+
shapes: SelectionRotateShapeSnapshot[];
|
|
129
|
+
pointShapes: SelectionRotatePointShapeSnapshot[];
|
|
130
|
+
updates: ShapeUpdate[];
|
|
131
|
+
lastPointerX: number;
|
|
132
|
+
lastPointerY: number;
|
|
133
|
+
lastShiftKey: boolean;
|
|
134
|
+
lastAccelKey: boolean;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface PointingSelectionHandleInteractionInfo {
|
|
138
|
+
originPagePoint: Vec;
|
|
139
|
+
previousSelection: ShapeId[];
|
|
140
|
+
session: SelectionHandleInteractionSession;
|
|
141
|
+
snapSnapshot: HandleSnapSnapshot | null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface DraggingSelectionHandleInteractionInfo
|
|
145
|
+
extends PointingSelectionHandleInteractionInfo {
|
|
146
|
+
lastPagePointX: number;
|
|
147
|
+
lastPagePointY: number;
|
|
148
|
+
lastAccelKey: boolean;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface SelectionDragInput {
|
|
152
|
+
pagePoint: Vec;
|
|
153
|
+
shiftKey: boolean;
|
|
154
|
+
altKey: boolean;
|
|
155
|
+
accelKey: boolean;
|
|
156
|
+
ctrlKey: boolean;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export type EdgeScrollTickMode =
|
|
160
|
+
| "always_apply"
|
|
161
|
+
| "apply_after_scroll_or_without_screen_point"
|
|
162
|
+
| "apply_after_scroll";
|
|
163
|
+
|
|
164
|
+
export function getSelectionDragInputFromCurrentInputs(
|
|
165
|
+
editor: Editor,
|
|
166
|
+
): SelectionDragInput | null {
|
|
167
|
+
const inputs = editor.inputs.state.get();
|
|
168
|
+
if (inputs.dragPhase !== "dragging" || !inputs.currentPagePoint) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
pagePoint: inputs.currentPagePoint,
|
|
174
|
+
shiftKey: inputs.shiftKey,
|
|
175
|
+
altKey: inputs.altKey,
|
|
176
|
+
accelKey: inputs.accelKey,
|
|
177
|
+
ctrlKey: inputs.ctrlKey,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function getSelectionDragInputForTick(
|
|
182
|
+
editor: Editor,
|
|
183
|
+
event: TickEditorEvent,
|
|
184
|
+
mode: EdgeScrollTickMode,
|
|
185
|
+
): SelectionDragInput | null {
|
|
186
|
+
const inputs = editor.inputs.state.get();
|
|
187
|
+
if (inputs.dragPhase !== "dragging" || !inputs.currentPagePoint) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
let pagePoint = inputs.currentPagePoint;
|
|
192
|
+
|
|
193
|
+
if (!inputs.currentScreenPoint) {
|
|
194
|
+
return mode === "apply_after_scroll"
|
|
195
|
+
? null
|
|
196
|
+
: {
|
|
197
|
+
pagePoint,
|
|
198
|
+
shiftKey: inputs.shiftKey,
|
|
199
|
+
altKey: inputs.altKey,
|
|
200
|
+
accelKey: inputs.accelKey,
|
|
201
|
+
ctrlKey: inputs.ctrlKey,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const edgeScrollDelta = getEdgeScrollDelta(
|
|
206
|
+
inputs.currentScreenPoint,
|
|
207
|
+
editor.viewportScreenSizeSignal.get(),
|
|
208
|
+
event.elapsed,
|
|
209
|
+
);
|
|
210
|
+
const didScroll = edgeScrollDelta.x !== 0 || edgeScrollDelta.y !== 0;
|
|
211
|
+
if (!didScroll && mode !== "always_apply") {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (didScroll) {
|
|
216
|
+
editor.panCamera(edgeScrollDelta);
|
|
217
|
+
pagePoint = editor.screenToPage(inputs.currentScreenPoint);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
pagePoint,
|
|
222
|
+
shiftKey: inputs.shiftKey,
|
|
223
|
+
altKey: inputs.altKey,
|
|
224
|
+
accelKey: inputs.accelKey,
|
|
225
|
+
ctrlKey: inputs.ctrlKey,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function applySelectionDragFromCurrentInputs(
|
|
230
|
+
editor: Editor,
|
|
231
|
+
apply: (input: SelectionDragInput) => void,
|
|
232
|
+
): void {
|
|
233
|
+
const input = getSelectionDragInputFromCurrentInputs(editor);
|
|
234
|
+
if (input) {
|
|
235
|
+
apply(input);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export function createBrushBounds(origin: Vec, current: Vec): Box {
|
|
240
|
+
const minX = Math.min(origin.x, current.x);
|
|
241
|
+
const minY = Math.min(origin.y, current.y);
|
|
242
|
+
const maxX = Math.max(origin.x, current.x);
|
|
243
|
+
const maxY = Math.max(origin.y, current.y);
|
|
244
|
+
return new Box(minX, minY, maxX - minX, maxY - minY);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export function hasExceededDragThreshold(origin: Vec, point: Vec): boolean {
|
|
248
|
+
return origin.dist2(point) >= DRAG_START_DISTANCE_SQUARED;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export function arePagePointsApproximatelyEqual(
|
|
252
|
+
left: Vec,
|
|
253
|
+
right: Vec,
|
|
254
|
+
): boolean {
|
|
255
|
+
return left.dist2(right) <= 1e-6;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export function toggleIds(base: ShapeId[], toggled: ShapeId[]): ShapeId[] {
|
|
259
|
+
const next = new Set(base);
|
|
260
|
+
for (const id of toggled) {
|
|
261
|
+
if (next.has(id)) {
|
|
262
|
+
next.delete(id);
|
|
263
|
+
} else {
|
|
264
|
+
next.add(id);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return Array.from(next);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export function getOutermostSelectableShapeIds(
|
|
271
|
+
editor: Editor,
|
|
272
|
+
shapeIds: Iterable<ShapeId>,
|
|
273
|
+
): ShapeId[] {
|
|
274
|
+
const ids: ShapeId[] = [];
|
|
275
|
+
const seen = new Set<ShapeId>();
|
|
276
|
+
|
|
277
|
+
for (const shapeId of shapeIds) {
|
|
278
|
+
const selectableId = editor.getOutermostSelectableShapeId(shapeId);
|
|
279
|
+
if (seen.has(selectableId)) {
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
seen.add(selectableId);
|
|
283
|
+
ids.push(selectableId);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return ids;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export function getSelectableShapeIdForHit(
|
|
290
|
+
editor: Editor,
|
|
291
|
+
shapeId: ShapeId,
|
|
292
|
+
selectedShapeIds: readonly ShapeId[],
|
|
293
|
+
): ShapeId {
|
|
294
|
+
const selectedShapeIdSet = new Set(selectedShapeIds);
|
|
295
|
+
if (selectedShapeIdSet.has(shapeId)) {
|
|
296
|
+
return shapeId;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const transformAncestorPath = getTransformDescendantAncestorPath(
|
|
300
|
+
editor,
|
|
301
|
+
shapeId,
|
|
302
|
+
);
|
|
303
|
+
for (const entry of transformAncestorPath) {
|
|
304
|
+
if (selectedShapeIdSet.has(entry.ancestorId)) {
|
|
305
|
+
return entry.childId;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const nearestTransformAncestorId = transformAncestorPath[0]?.ancestorId;
|
|
310
|
+
if (nearestTransformAncestorId) {
|
|
311
|
+
if (
|
|
312
|
+
selectedShapeIds.some(
|
|
313
|
+
(selectedShapeId) =>
|
|
314
|
+
getNearestTransformDescendantAncestorId(editor, selectedShapeId) ===
|
|
315
|
+
nearestTransformAncestorId,
|
|
316
|
+
)
|
|
317
|
+
) {
|
|
318
|
+
return shapeId;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return (
|
|
323
|
+
transformAncestorPath[transformAncestorPath.length - 1]?.ancestorId ??
|
|
324
|
+
shapeId
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export function getSelectedTransformAncestorIdForHit(
|
|
329
|
+
editor: Editor,
|
|
330
|
+
shapeId: ShapeId,
|
|
331
|
+
selectedShapeIds: readonly ShapeId[],
|
|
332
|
+
): ShapeId | null {
|
|
333
|
+
const selectedShapeIdSet = new Set(selectedShapeIds);
|
|
334
|
+
for (const entry of getTransformDescendantAncestorPath(editor, shapeId)) {
|
|
335
|
+
if (selectedShapeIdSet.has(entry.ancestorId)) {
|
|
336
|
+
return entry.ancestorId;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export interface TransformDescendantAncestorPathEntry {
|
|
343
|
+
ancestorId: ShapeId;
|
|
344
|
+
childId: ShapeId;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export function getNearestTransformDescendantAncestorId(
|
|
348
|
+
editor: Editor,
|
|
349
|
+
shapeId: ShapeId,
|
|
350
|
+
): ShapeId | null {
|
|
351
|
+
return (
|
|
352
|
+
getTransformDescendantAncestorPath(editor, shapeId)[0]?.ancestorId ?? null
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export function getTransformDescendantAncestorPath(
|
|
357
|
+
editor: Editor,
|
|
358
|
+
shapeId: ShapeId,
|
|
359
|
+
): TransformDescendantAncestorPathEntry[] {
|
|
360
|
+
const path: TransformDescendantAncestorPathEntry[] = [];
|
|
361
|
+
let shape = editor.getShape(shapeId);
|
|
362
|
+
let childId = shapeId;
|
|
363
|
+
const seen = new Set<ShapeId>([shapeId]);
|
|
364
|
+
|
|
365
|
+
while (shape?.parentId.startsWith("shape:")) {
|
|
366
|
+
const parentId = shape.parentId as ShapeId;
|
|
367
|
+
if (seen.has(parentId)) {
|
|
368
|
+
return path;
|
|
369
|
+
}
|
|
370
|
+
seen.add(parentId);
|
|
371
|
+
|
|
372
|
+
const parent = editor.getShape(parentId);
|
|
373
|
+
if (!parent) {
|
|
374
|
+
return path;
|
|
375
|
+
}
|
|
376
|
+
if (editor.getShapeUtil(parent).shouldTransformDescendants(parent)) {
|
|
377
|
+
path.push({ ancestorId: parent.id, childId });
|
|
378
|
+
}
|
|
379
|
+
childId = parent.id;
|
|
380
|
+
shape = parent;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
return path;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
export function isAdditiveSelectionActive({
|
|
387
|
+
shiftKey,
|
|
388
|
+
accelKey,
|
|
389
|
+
}: {
|
|
390
|
+
shiftKey: boolean;
|
|
391
|
+
accelKey: boolean;
|
|
392
|
+
}): boolean {
|
|
393
|
+
return shiftKey || accelKey;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
export function isBrushWrappingSelection({ ctrlKey }: { ctrlKey: boolean }): boolean {
|
|
397
|
+
return ctrlKey;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
export function isQuickClick(info: PointingShapeInfo, event: PointerEditorEvent): boolean {
|
|
401
|
+
return (
|
|
402
|
+
event.timestamp - info.originTimestamp <=
|
|
403
|
+
GROUP_CHILD_QUICK_SELECT_DURATION_MS
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
export function normalizeAngle(angle: number): number {
|
|
408
|
+
let next = angle;
|
|
409
|
+
while (next <= -Math.PI) next += Math.PI * 2;
|
|
410
|
+
while (next > Math.PI) next -= Math.PI * 2;
|
|
411
|
+
return next;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export function snapAngle(angle: number, step: number): number {
|
|
415
|
+
return Math.round(angle / step) * step;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
export function getBoxCorners(bounds: Box): Vec[] {
|
|
419
|
+
return [
|
|
420
|
+
new Vec(bounds.minX, bounds.minY),
|
|
421
|
+
new Vec(bounds.maxX, bounds.minY),
|
|
422
|
+
new Vec(bounds.maxX, bounds.maxY),
|
|
423
|
+
new Vec(bounds.minX, bounds.maxY),
|
|
424
|
+
];
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
export function getShapeSelectionResizePageOutlineVertices(
|
|
428
|
+
editor: Editor,
|
|
429
|
+
shape: ShapeRecord,
|
|
430
|
+
): Vec[] {
|
|
431
|
+
const util = editor.getShapeUtil(shape);
|
|
432
|
+
const bounds = util.getSelectionResizeLocalBounds(shape);
|
|
433
|
+
const transform = editor.computeShapeLocalToPageTransform(shape);
|
|
434
|
+
return getBoxCorners(bounds).map((point) => transform.applyToPoint(point));
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
export function getResizedShapeUpdate(
|
|
438
|
+
editor: Editor,
|
|
439
|
+
shape: SelectionResizeShapeSnapshot,
|
|
440
|
+
startBounds: Box,
|
|
441
|
+
nextBounds: Box,
|
|
442
|
+
scaleX: number,
|
|
443
|
+
scaleY: number,
|
|
444
|
+
handleId: SelectionResizeHandleId,
|
|
445
|
+
isResizingFromCenter: boolean,
|
|
446
|
+
rotationCenter: Vec,
|
|
447
|
+
selectionRotation: number,
|
|
448
|
+
update: ShapeUpdate,
|
|
449
|
+
): void {
|
|
450
|
+
const selectionTransform = getSelectionTransform(
|
|
451
|
+
rotationCenter,
|
|
452
|
+
selectionRotation,
|
|
453
|
+
);
|
|
454
|
+
const nextLocalBounds = mapSelectionLocalBoundsBetweenBounds({
|
|
455
|
+
bounds: shape.localBounds,
|
|
456
|
+
fromBounds: startBounds,
|
|
457
|
+
toBounds: nextBounds,
|
|
458
|
+
});
|
|
459
|
+
const nextCenter = selectionLocalPointToPagePoint(
|
|
460
|
+
nextLocalBounds.center,
|
|
461
|
+
selectionTransform,
|
|
462
|
+
);
|
|
463
|
+
|
|
464
|
+
const util = editor.getShapeUtil(shape.shape);
|
|
465
|
+
const nextShapeUpdate = util.resizeSelectionBounds(shape.shape, {
|
|
466
|
+
handleId,
|
|
467
|
+
pageCenter: nextCenter,
|
|
468
|
+
selectionLocalBounds: nextLocalBounds,
|
|
469
|
+
scaleX,
|
|
470
|
+
scaleY,
|
|
471
|
+
isResizingFromCenter,
|
|
472
|
+
selectionRotation,
|
|
473
|
+
selectionRotationCenter: rotationCenter,
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
update.id = shape.shape.id;
|
|
477
|
+
update.x = nextShapeUpdate.x;
|
|
478
|
+
update.y = nextShapeUpdate.y;
|
|
479
|
+
update.rotation = nextShapeUpdate.rotation ?? shape.rotation;
|
|
480
|
+
update.scaleX = nextShapeUpdate.scaleX;
|
|
481
|
+
update.scaleY = nextShapeUpdate.scaleY;
|
|
482
|
+
update.props = nextShapeUpdate.props;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
export function getSelectionTransform(
|
|
486
|
+
rotationCenter: Vec,
|
|
487
|
+
selectionRotation: number,
|
|
488
|
+
): SelectionRotationTransform {
|
|
489
|
+
return {
|
|
490
|
+
rotation: selectionRotation,
|
|
491
|
+
rotationCenter,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
export function getResizedPagePointsUpdate(
|
|
496
|
+
editor: Editor,
|
|
497
|
+
shape: SelectionResizePointShapeSnapshot,
|
|
498
|
+
startBounds: Box,
|
|
499
|
+
nextBounds: Box,
|
|
500
|
+
scaleX: number,
|
|
501
|
+
scaleY: number,
|
|
502
|
+
handleId: SelectionResizeHandleId,
|
|
503
|
+
isResizingFromCenter: boolean,
|
|
504
|
+
rotationCenter: Vec,
|
|
505
|
+
selectionRotation: number,
|
|
506
|
+
update: ShapeUpdate,
|
|
507
|
+
): void {
|
|
508
|
+
const selectionTransform = getSelectionTransform(
|
|
509
|
+
rotationCenter,
|
|
510
|
+
selectionRotation,
|
|
511
|
+
);
|
|
512
|
+
const nextStartPagePoint = selectionLocalPointToPagePoint(
|
|
513
|
+
mapSelectionLocalPointForResize({
|
|
514
|
+
point: shape.startLocalPagePoint,
|
|
515
|
+
startBounds,
|
|
516
|
+
scaleX,
|
|
517
|
+
scaleY,
|
|
518
|
+
handleId,
|
|
519
|
+
isResizingFromCenter,
|
|
520
|
+
}),
|
|
521
|
+
selectionTransform,
|
|
522
|
+
);
|
|
523
|
+
const nextEndPagePoint = selectionLocalPointToPagePoint(
|
|
524
|
+
mapSelectionLocalPointForResize({
|
|
525
|
+
point: shape.endLocalPagePoint,
|
|
526
|
+
startBounds,
|
|
527
|
+
scaleX,
|
|
528
|
+
scaleY,
|
|
529
|
+
handleId,
|
|
530
|
+
isResizingFromCenter,
|
|
531
|
+
}),
|
|
532
|
+
selectionTransform,
|
|
533
|
+
);
|
|
534
|
+
const nextShapeUpdate = editor
|
|
535
|
+
.getShapeUtil(shape.shape)
|
|
536
|
+
.updateSelectionPagePoints(shape.shape, {
|
|
537
|
+
pagePoints: [nextStartPagePoint, nextEndPagePoint],
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
update.id = shape.shape.id;
|
|
541
|
+
update.x = nextShapeUpdate.x;
|
|
542
|
+
update.y = nextShapeUpdate.y;
|
|
543
|
+
update.rotation = nextShapeUpdate.rotation;
|
|
544
|
+
update.scaleX = nextShapeUpdate.scaleX;
|
|
545
|
+
update.scaleY = nextShapeUpdate.scaleY;
|
|
546
|
+
update.props = nextShapeUpdate.props;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
function mapSelectionLocalPointForResize({
|
|
550
|
+
point,
|
|
551
|
+
startBounds,
|
|
552
|
+
scaleX,
|
|
553
|
+
scaleY,
|
|
554
|
+
handleId,
|
|
555
|
+
isResizingFromCenter,
|
|
556
|
+
}: {
|
|
557
|
+
point: Vec;
|
|
558
|
+
startBounds: Box;
|
|
559
|
+
scaleX: number;
|
|
560
|
+
scaleY: number;
|
|
561
|
+
handleId: SelectionResizeHandleId;
|
|
562
|
+
isResizingFromCenter: boolean;
|
|
563
|
+
}): Vec {
|
|
564
|
+
const anchorX = getSelectionResizeAnchorX({
|
|
565
|
+
startBounds,
|
|
566
|
+
handleId,
|
|
567
|
+
isResizingFromCenter,
|
|
568
|
+
});
|
|
569
|
+
const anchorY = getSelectionResizeAnchorY({
|
|
570
|
+
startBounds,
|
|
571
|
+
handleId,
|
|
572
|
+
isResizingFromCenter,
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
return new Vec(
|
|
576
|
+
anchorX + (point.x - anchorX) * scaleX,
|
|
577
|
+
anchorY + (point.y - anchorY) * scaleY,
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
function getSelectionResizeAnchorX({
|
|
582
|
+
startBounds,
|
|
583
|
+
handleId,
|
|
584
|
+
isResizingFromCenter,
|
|
585
|
+
}: {
|
|
586
|
+
startBounds: Box;
|
|
587
|
+
handleId: SelectionResizeHandleId;
|
|
588
|
+
isResizingFromCenter: boolean;
|
|
589
|
+
}): number {
|
|
590
|
+
if (isResizingFromCenter) {
|
|
591
|
+
return startBounds.center.x;
|
|
592
|
+
}
|
|
593
|
+
if (selectionResizeHandleMovesLeftEdge(handleId)) {
|
|
594
|
+
return startBounds.maxX;
|
|
595
|
+
}
|
|
596
|
+
if (selectionResizeHandleMovesRightEdge(handleId)) {
|
|
597
|
+
return startBounds.minX;
|
|
598
|
+
}
|
|
599
|
+
return startBounds.center.x;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
function getSelectionResizeAnchorY({
|
|
603
|
+
startBounds,
|
|
604
|
+
handleId,
|
|
605
|
+
isResizingFromCenter,
|
|
606
|
+
}: {
|
|
607
|
+
startBounds: Box;
|
|
608
|
+
handleId: SelectionResizeHandleId;
|
|
609
|
+
isResizingFromCenter: boolean;
|
|
610
|
+
}): number {
|
|
611
|
+
if (isResizingFromCenter) {
|
|
612
|
+
return startBounds.center.y;
|
|
613
|
+
}
|
|
614
|
+
if (selectionResizeHandleMovesTopEdge(handleId)) {
|
|
615
|
+
return startBounds.maxY;
|
|
616
|
+
}
|
|
617
|
+
if (selectionResizeHandleMovesBottomEdge(handleId)) {
|
|
618
|
+
return startBounds.minY;
|
|
619
|
+
}
|
|
620
|
+
return startBounds.center.y;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
export function getSelectionResizeAspectRatioLockOverride(
|
|
624
|
+
editor: Editor,
|
|
625
|
+
shapes: readonly ShapeRecord[],
|
|
626
|
+
handleId: SelectionResizeHandleId,
|
|
627
|
+
): boolean | null {
|
|
628
|
+
const isOnlySelected = shapes.length === 1;
|
|
629
|
+
let override: boolean | null = null;
|
|
630
|
+
|
|
631
|
+
for (const shape of shapes) {
|
|
632
|
+
const nextOverride = editor
|
|
633
|
+
.getShapeUtil(shape)
|
|
634
|
+
.getSelectionResizeAspectRatioLock(shape, {
|
|
635
|
+
editor,
|
|
636
|
+
handleId,
|
|
637
|
+
isOnlySelected,
|
|
638
|
+
});
|
|
639
|
+
if (nextOverride === null) {
|
|
640
|
+
continue;
|
|
641
|
+
}
|
|
642
|
+
if (override !== null && override !== nextOverride) {
|
|
643
|
+
return null;
|
|
644
|
+
}
|
|
645
|
+
override = nextOverride;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
return override;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
export function getRotatedShapeUpdate(
|
|
652
|
+
shape: SelectionRotateShapeSnapshot,
|
|
653
|
+
center: Vec,
|
|
654
|
+
delta: number,
|
|
655
|
+
update: ShapeUpdate,
|
|
656
|
+
): void {
|
|
657
|
+
const localCenter = shape.localBounds.center;
|
|
658
|
+
const shapeCenter = new Vec(shape.x + localCenter.x, shape.y + localCenter.y);
|
|
659
|
+
const nextCenter = rotateSelectionPagePoint(shapeCenter, {
|
|
660
|
+
rotation: delta,
|
|
661
|
+
rotationCenter: center,
|
|
662
|
+
});
|
|
663
|
+
update.id = shape.id;
|
|
664
|
+
update.x = nextCenter.x - localCenter.x;
|
|
665
|
+
update.y = nextCenter.y - localCenter.y;
|
|
666
|
+
update.rotation = shape.rotation + delta;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
export function getRotatedPagePointsUpdate(
|
|
670
|
+
editor: Editor,
|
|
671
|
+
shape: SelectionRotatePointShapeSnapshot,
|
|
672
|
+
center: Vec,
|
|
673
|
+
delta: number,
|
|
674
|
+
update: ShapeUpdate,
|
|
675
|
+
): void {
|
|
676
|
+
const nextShapeUpdate = editor
|
|
677
|
+
.getShapeUtil(shape.shape)
|
|
678
|
+
.updateSelectionPagePoints(shape.shape, {
|
|
679
|
+
pagePoints: [
|
|
680
|
+
rotateSelectionPagePoint(shape.startPagePoint, {
|
|
681
|
+
rotation: delta,
|
|
682
|
+
rotationCenter: center,
|
|
683
|
+
}),
|
|
684
|
+
rotateSelectionPagePoint(shape.endPagePoint, {
|
|
685
|
+
rotation: delta,
|
|
686
|
+
rotationCenter: center,
|
|
687
|
+
}),
|
|
688
|
+
],
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
update.id = shape.shape.id;
|
|
692
|
+
update.x = nextShapeUpdate.x;
|
|
693
|
+
update.y = nextShapeUpdate.y;
|
|
694
|
+
update.rotation = nextShapeUpdate.rotation;
|
|
695
|
+
update.scaleX = nextShapeUpdate.scaleX;
|
|
696
|
+
update.scaleY = nextShapeUpdate.scaleY;
|
|
697
|
+
update.props = nextShapeUpdate.props;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
export function createTranslatingUpdates(
|
|
701
|
+
shapes: TranslatingShapeSnapshot[],
|
|
702
|
+
): ShapeUpdate[] {
|
|
703
|
+
return shapes.map((shape) => ({
|
|
704
|
+
id: shape.id,
|
|
705
|
+
x: shape.x,
|
|
706
|
+
y: shape.y,
|
|
707
|
+
}));
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
export function getTranslateShapeSnapshots(
|
|
711
|
+
editor: Editor,
|
|
712
|
+
selectedShapeIds: ShapeId[],
|
|
713
|
+
): TranslatingShapeSnapshot[] {
|
|
714
|
+
const movableRootIds = selectedShapeIds.filter((shapeId) => {
|
|
715
|
+
const shape = editor.getShape(shapeId);
|
|
716
|
+
return !!shape && !shape.isLocked && !editor.hasLockedDescendant(shape.id);
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
return editor
|
|
720
|
+
.getShapeIdsIncludingDescendants(movableRootIds)
|
|
721
|
+
.map((shapeId) => editor.getShape(shapeId))
|
|
722
|
+
.filter((shape): shape is ShapeRecord => !!shape && !shape.isLocked)
|
|
723
|
+
.map((shape) => ({
|
|
724
|
+
id: shape.id,
|
|
725
|
+
x: shape.x,
|
|
726
|
+
y: shape.y,
|
|
727
|
+
}));
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
export function isShapeWrappedByBrush(
|
|
731
|
+
editor: Editor,
|
|
732
|
+
brushBounds: Box,
|
|
733
|
+
shapeId: ShapeId,
|
|
734
|
+
): boolean {
|
|
735
|
+
const shape = editor.getShape(shapeId);
|
|
736
|
+
if (!shape) {
|
|
737
|
+
return false;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
return editor.getShapeUtil(shape).isWrappedByBrush(shape, {
|
|
741
|
+
brushBounds,
|
|
742
|
+
pageOutlineVertices: editor.getShapePageOutlineVertices(shapeId),
|
|
743
|
+
pageBounds: editor.getShapePageBounds(shapeId),
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
export function shouldSelectShapeWithBrush(
|
|
748
|
+
editor: Editor,
|
|
749
|
+
brushBounds: Box,
|
|
750
|
+
shapeId: ShapeId,
|
|
751
|
+
isWrapping: boolean,
|
|
752
|
+
): boolean {
|
|
753
|
+
const shape = editor.getShape(shapeId);
|
|
754
|
+
if (!shape || !isBrushSelectableShapeId(editor, shape.id)) {
|
|
755
|
+
return false;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
return editor.getShapeUtil(shape).canSelectByBrush(shape, {
|
|
759
|
+
brushBounds,
|
|
760
|
+
isWrapping,
|
|
761
|
+
pageOutlineVertices: editor.getShapePageOutlineVertices(shape.id),
|
|
762
|
+
pageBounds: editor.getShapePageBounds(shape.id),
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
export function isBrushSelectableShapeId(editor: Editor, shapeId: ShapeId): boolean {
|
|
767
|
+
const shape = editor.getShape(shapeId);
|
|
768
|
+
if (!shape) {
|
|
769
|
+
return false;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
return !editor.getShapeUtil(shape).shouldTransformDescendants(shape);
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
export function createResizingUpdates(
|
|
776
|
+
shapes: SelectionResizeShapeSnapshot[],
|
|
777
|
+
pointShapes: SelectionResizePointShapeSnapshot[],
|
|
778
|
+
): ShapeUpdate[] {
|
|
779
|
+
return [
|
|
780
|
+
...shapes.map((shape) => ({
|
|
781
|
+
id: shape.shape.id,
|
|
782
|
+
rotation: shape.rotation,
|
|
783
|
+
})),
|
|
784
|
+
...pointShapes.map((shape) => ({ id: shape.shape.id })),
|
|
785
|
+
];
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
export function createRotatingUpdates(
|
|
789
|
+
shapes: SelectionRotateShapeSnapshot[],
|
|
790
|
+
pointShapes: SelectionRotatePointShapeSnapshot[],
|
|
791
|
+
): ShapeUpdate[] {
|
|
792
|
+
return [
|
|
793
|
+
...shapes.map((shape) => ({
|
|
794
|
+
id: shape.id,
|
|
795
|
+
x: shape.x,
|
|
796
|
+
y: shape.y,
|
|
797
|
+
rotation: shape.rotation,
|
|
798
|
+
})),
|
|
799
|
+
...pointShapes.map((shape) => ({ id: shape.shape.id })),
|
|
800
|
+
];
|
|
801
|
+
}
|