@myoc/excalidraw 0.19.512 → 0.19.513
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/CHANGELOG.md +53 -0
- package/dist/dev/{chunk-OBLRXIUK.js → chunk-BI6BDZVY.js} +3 -3
- package/dist/dev/{chunk-QHLG4OQL.js → chunk-FW62QUKV.js} +2 -2
- package/dist/dev/data/{image-R7FQP7SA.js → image-WGZL7YPK.js} +3 -3
- package/dist/dev/index.js +1768 -1758
- package/dist/dev/index.js.map +4 -4
- package/dist/dev/subset-shared.chunk.js +1 -1
- package/dist/dev/subset-worker.chunk.js +1 -1
- package/dist/prod/{chunk-5JM5RIGS.js → chunk-56AUOKVR.js} +2 -2
- package/dist/prod/{chunk-KVNPEVSY.js → chunk-NVT4BTJO.js} +1 -1
- package/dist/prod/data/image-ZQZIDAZL.js +1 -0
- package/dist/prod/index.js +22 -22
- package/dist/prod/subset-shared.chunk.js +1 -1
- package/dist/prod/subset-worker.chunk.js +1 -1
- package/dist/types/excalidraw/components/App.d.ts +6 -6
- package/dist/types/excalidraw/types.d.ts +4 -1
- package/package.json +4 -4
- package/dist/prod/data/image-HP6HSTQ2.js +0 -1
- /package/dist/dev/{chunk-OBLRXIUK.js.map → chunk-BI6BDZVY.js.map} +0 -0
- /package/dist/dev/{chunk-QHLG4OQL.js.map → chunk-FW62QUKV.js.map} +0 -0
- /package/dist/dev/data/{image-R7FQP7SA.js.map → image-WGZL7YPK.js.map} +0 -0
package/dist/dev/index.js
CHANGED
|
@@ -57,10 +57,10 @@ import {
|
|
|
57
57
|
saveAsJSON,
|
|
58
58
|
serializeAsJSON,
|
|
59
59
|
strokeRectWithRotation_simple
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-BI6BDZVY.js";
|
|
61
61
|
import {
|
|
62
62
|
define_import_meta_env_default
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-FW62QUKV.js";
|
|
64
64
|
import {
|
|
65
65
|
en_default
|
|
66
66
|
} from "./chunk-ZGRXNVW4.js";
|
|
@@ -90,257 +90,257 @@ import {
|
|
|
90
90
|
// components/App.tsx
|
|
91
91
|
import clsx57 from "clsx";
|
|
92
92
|
import throttle2 from "lodash.throttle";
|
|
93
|
+
import { nanoid } from "nanoid";
|
|
93
94
|
import React40, { useContext as useContext3 } from "react";
|
|
94
95
|
import { flushSync as flushSync2 } from "react-dom";
|
|
95
96
|
import rough3 from "roughjs/bin/rough";
|
|
96
|
-
import { nanoid } from "nanoid";
|
|
97
97
|
import {
|
|
98
98
|
clamp as clamp8,
|
|
99
|
-
pointFrom as pointFrom34,
|
|
100
99
|
pointDistance as pointDistance9,
|
|
101
|
-
|
|
100
|
+
pointFrom as pointFrom34,
|
|
102
101
|
pointRotateRads as pointRotateRads23,
|
|
103
|
-
|
|
104
|
-
vectorSubtract as vectorSubtract2,
|
|
102
|
+
vector as vector3,
|
|
105
103
|
vectorDot,
|
|
106
|
-
|
|
104
|
+
vectorFromPoint as vectorFromPoint10,
|
|
105
|
+
vectorNormalize as vectorNormalize5,
|
|
106
|
+
vectorSubtract as vectorSubtract2
|
|
107
107
|
} from "@excalidraw/math";
|
|
108
108
|
import {
|
|
109
|
-
|
|
110
|
-
CODES as CODES11,
|
|
111
|
-
shouldResizeFromCenter,
|
|
112
|
-
shouldMaintainAspectRatio,
|
|
113
|
-
shouldRotateWithDiscreteAngle as shouldRotateWithDiscreteAngle3,
|
|
114
|
-
isArrowKey as isArrowKey2,
|
|
115
|
-
KEYS as KEYS50,
|
|
109
|
+
addEventListener as addEventListener2,
|
|
116
110
|
APP_NAME,
|
|
111
|
+
AppEventBus,
|
|
112
|
+
applyDarkModeFilter as applyDarkModeFilter4,
|
|
113
|
+
arrayToMap as arrayToMap30,
|
|
114
|
+
ARROW_TYPE as ARROW_TYPE2,
|
|
115
|
+
BIND_MODE_TIMEOUT as BIND_MODE_TIMEOUT2,
|
|
116
|
+
CLASSES as CLASSES10,
|
|
117
|
+
CODES as CODES11,
|
|
118
|
+
COLOR_PALETTE as COLOR_PALETTE6,
|
|
119
|
+
createUserAgentDescriptor,
|
|
117
120
|
CURSOR_TYPE as CURSOR_TYPE4,
|
|
121
|
+
debounce as debounce3,
|
|
122
|
+
DEFAULT_COLLISION_THRESHOLD,
|
|
123
|
+
DEFAULT_REDUCED_GLOBAL_ALPHA as DEFAULT_REDUCED_GLOBAL_ALPHA2,
|
|
124
|
+
DEFAULT_TEXT_ALIGN as DEFAULT_TEXT_ALIGN2,
|
|
118
125
|
DEFAULT_TRANSFORM_HANDLE_SPACING as DEFAULT_TRANSFORM_HANDLE_SPACING3,
|
|
119
126
|
DEFAULT_VERTICAL_ALIGN,
|
|
127
|
+
deriveStylesPanelMode as deriveStylesPanelMode2,
|
|
128
|
+
distance as distance2,
|
|
129
|
+
DOUBLE_TAP_POSITION_THRESHOLD,
|
|
120
130
|
DRAGGING_THRESHOLD as DRAGGING_THRESHOLD3,
|
|
131
|
+
easeOut as easeOut4,
|
|
132
|
+
easeToValuesRAF,
|
|
121
133
|
ELEMENT_SHIFT_TRANSLATE_AMOUNT,
|
|
122
134
|
ELEMENT_TRANSLATE_AMOUNT,
|
|
135
|
+
Emitter as Emitter2,
|
|
123
136
|
EVENT as EVENT10,
|
|
124
137
|
FRAME_STYLE as FRAME_STYLE4,
|
|
138
|
+
getDateTime,
|
|
139
|
+
getFeatureFlag as getFeatureFlag4,
|
|
140
|
+
getFontString as getFontString11,
|
|
141
|
+
getFormFactor,
|
|
142
|
+
getGridPoint as getGridPoint2,
|
|
143
|
+
getLineHeight as getLineHeight6,
|
|
144
|
+
getNearestScrollableContainer,
|
|
125
145
|
IMAGE_MIME_TYPES as IMAGE_MIME_TYPES2,
|
|
126
146
|
IMAGE_RENDER_TIMEOUT,
|
|
147
|
+
invariant as invariant16,
|
|
148
|
+
isArrowKey as isArrowKey2,
|
|
149
|
+
isBrave,
|
|
150
|
+
isDevEnv as isDevEnv9,
|
|
151
|
+
isInputLike,
|
|
152
|
+
isIOS,
|
|
153
|
+
isLocalLink as isLocalLink2,
|
|
154
|
+
isSafari as isSafari2,
|
|
155
|
+
isSelectionLikeTool,
|
|
156
|
+
isShallowEqual as isShallowEqual8,
|
|
157
|
+
isTestEnv as isTestEnv5,
|
|
158
|
+
isToolIcon,
|
|
159
|
+
isTransparent as isTransparent6,
|
|
160
|
+
isWritableElement as isWritableElement4,
|
|
161
|
+
KEYS as KEYS50,
|
|
127
162
|
LINE_CONFIRM_THRESHOLD as LINE_CONFIRM_THRESHOLD2,
|
|
163
|
+
loadDesktopUIModePreference,
|
|
164
|
+
matchKey as matchKey3,
|
|
128
165
|
MIME_TYPES as MIME_TYPES7,
|
|
166
|
+
MINIMUM_ARROW_SIZE,
|
|
129
167
|
MQ_RIGHT_SIDEBAR_MIN_WIDTH,
|
|
168
|
+
muteFSAbortError,
|
|
169
|
+
normalizeEOL as normalizeEOL2,
|
|
170
|
+
normalizeLink as normalizeLink3,
|
|
171
|
+
oneOf,
|
|
130
172
|
POINTER_BUTTON as POINTER_BUTTON2,
|
|
173
|
+
POINTER_EVENTS,
|
|
174
|
+
randomInteger as randomInteger4,
|
|
131
175
|
ROUNDNESS as ROUNDNESS7,
|
|
176
|
+
sceneCoordsToViewportCoords as sceneCoordsToViewportCoords7,
|
|
132
177
|
SCROLL_TIMEOUT,
|
|
178
|
+
setDesktopUIMode,
|
|
179
|
+
shouldMaintainAspectRatio,
|
|
180
|
+
shouldResizeFromCenter,
|
|
181
|
+
shouldRotateWithDiscreteAngle as shouldRotateWithDiscreteAngle3,
|
|
182
|
+
supportsResizeObserver as supportsResizeObserver2,
|
|
133
183
|
TAP_TWICE_TIMEOUT,
|
|
134
184
|
TEXT_TO_CENTER_SNAP_THRESHOLD,
|
|
135
185
|
THEME as THEME17,
|
|
136
|
-
TOUCH_CTX_MENU_TIMEOUT,
|
|
137
|
-
VERTICAL_ALIGN as VERTICAL_ALIGN5,
|
|
138
|
-
YOUTUBE_STATES,
|
|
139
|
-
ZOOM_STEP as ZOOM_STEP2,
|
|
140
|
-
POINTER_EVENTS,
|
|
141
186
|
TOOL_TYPE as TOOL_TYPE3,
|
|
142
|
-
|
|
143
|
-
DEFAULT_COLLISION_THRESHOLD,
|
|
144
|
-
DEFAULT_TEXT_ALIGN as DEFAULT_TEXT_ALIGN2,
|
|
145
|
-
ARROW_TYPE as ARROW_TYPE2,
|
|
146
|
-
DEFAULT_REDUCED_GLOBAL_ALPHA as DEFAULT_REDUCED_GLOBAL_ALPHA2,
|
|
147
|
-
isLocalLink as isLocalLink2,
|
|
148
|
-
normalizeLink as normalizeLink3,
|
|
187
|
+
TOUCH_CTX_MENU_TIMEOUT,
|
|
149
188
|
toValidURL,
|
|
150
|
-
getGridPoint as getGridPoint2,
|
|
151
|
-
getLineHeight as getLineHeight6,
|
|
152
|
-
debounce as debounce3,
|
|
153
|
-
distance as distance2,
|
|
154
|
-
getFontString as getFontString11,
|
|
155
|
-
getNearestScrollableContainer,
|
|
156
|
-
isInputLike,
|
|
157
|
-
isToolIcon,
|
|
158
|
-
isWritableElement as isWritableElement4,
|
|
159
|
-
sceneCoordsToViewportCoords as sceneCoordsToViewportCoords7,
|
|
160
189
|
tupleToCoors,
|
|
161
|
-
viewportCoordsToSceneCoords as viewportCoordsToSceneCoords3,
|
|
162
|
-
wrapEvent as wrapEvent2,
|
|
163
|
-
updateObject as updateObject2,
|
|
164
190
|
updateActiveTool as updateActiveTool8,
|
|
165
|
-
|
|
166
|
-
easeToValuesRAF,
|
|
167
|
-
muteFSAbortError,
|
|
168
|
-
isTestEnv as isTestEnv5,
|
|
169
|
-
isDevEnv as isDevEnv9,
|
|
170
|
-
easeOut as easeOut4,
|
|
191
|
+
updateObject as updateObject2,
|
|
171
192
|
updateStable,
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
applyDarkModeFilter as applyDarkModeFilter4,
|
|
178
|
-
AppEventBus,
|
|
179
|
-
randomInteger as randomInteger4,
|
|
180
|
-
CLASSES as CLASSES10,
|
|
181
|
-
Emitter as Emitter2,
|
|
182
|
-
MINIMUM_ARROW_SIZE,
|
|
183
|
-
DOUBLE_TAP_POSITION_THRESHOLD,
|
|
184
|
-
BIND_MODE_TIMEOUT as BIND_MODE_TIMEOUT2,
|
|
185
|
-
invariant as invariant16,
|
|
186
|
-
getFeatureFlag as getFeatureFlag4,
|
|
187
|
-
createUserAgentDescriptor,
|
|
188
|
-
getFormFactor,
|
|
189
|
-
deriveStylesPanelMode as deriveStylesPanelMode2,
|
|
190
|
-
isIOS,
|
|
191
|
-
isBrave,
|
|
192
|
-
isSafari as isSafari2,
|
|
193
|
-
loadDesktopUIModePreference,
|
|
194
|
-
setDesktopUIMode,
|
|
195
|
-
isSelectionLikeTool,
|
|
196
|
-
oneOf,
|
|
197
|
-
matchKey as matchKey3
|
|
193
|
+
VERTICAL_ALIGN as VERTICAL_ALIGN5,
|
|
194
|
+
viewportCoordsToSceneCoords as viewportCoordsToSceneCoords3,
|
|
195
|
+
wrapEvent as wrapEvent2,
|
|
196
|
+
YOUTUBE_STATES,
|
|
197
|
+
ZOOM_STEP as ZOOM_STEP2
|
|
198
198
|
} from "@excalidraw/common";
|
|
199
199
|
import {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
updateImageCache as _updateImageCache,
|
|
201
|
+
addElementsToFrame as addElementsToFrame2,
|
|
202
|
+
bindOrUnbindBindingElement as bindOrUnbindBindingElement2,
|
|
203
203
|
bindOrUnbindBindingElements as bindOrUnbindBindingElements2,
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
newFrameElement as newFrameElement2,
|
|
210
|
-
newFreeDrawElement,
|
|
211
|
-
newEmbeddableElement,
|
|
212
|
-
newMagicFrameElement,
|
|
213
|
-
newIframeElement,
|
|
214
|
-
newArrowElement as newArrowElement2,
|
|
215
|
-
newElement as newElement6,
|
|
216
|
-
newImageElement,
|
|
217
|
-
newLinearElement as newLinearElement5,
|
|
218
|
-
newTextElement as newTextElement5,
|
|
219
|
-
refreshTextDimensions,
|
|
204
|
+
calculateFixedPointForNonElbowArrowBinding as calculateFixedPointForNonElbowArrowBinding2,
|
|
205
|
+
CaptureUpdateAction as CaptureUpdateAction41,
|
|
206
|
+
convertToExcalidrawElements,
|
|
207
|
+
createSrcDoc,
|
|
208
|
+
cropElement,
|
|
220
209
|
deepCopyElement as deepCopyElement4,
|
|
210
|
+
doBoundsIntersect as doBoundsIntersect4,
|
|
211
|
+
dragNewElement,
|
|
212
|
+
dragSelectedElements,
|
|
221
213
|
duplicateElements as duplicateElements2,
|
|
214
|
+
editGroupForSelectedElement,
|
|
215
|
+
elementOverlapsWithFrame as elementOverlapsWithFrame2,
|
|
216
|
+
embeddableURLValidator as embeddableURLValidator2,
|
|
217
|
+
excludeElementsInFramesFromSelection,
|
|
218
|
+
filterElementsEligibleAsFrameChildren,
|
|
219
|
+
fixBindingsAfterDeletion as fixBindingsAfterDeletion2,
|
|
220
|
+
FlowChartCreator,
|
|
221
|
+
FlowChartNavigator,
|
|
222
|
+
getActiveTextElement as getActiveTextElement2,
|
|
223
|
+
getApproxMinLineHeight,
|
|
224
|
+
getApproxMinLineWidth as getApproxMinLineWidth2,
|
|
225
|
+
getBoundTextElement as getBoundTextElement15,
|
|
226
|
+
getCommonBounds as getCommonBounds11,
|
|
227
|
+
getCommonFrameId as getCommonFrameId2,
|
|
228
|
+
getContainerCenter,
|
|
229
|
+
getContainerElement as getContainerElement5,
|
|
230
|
+
getContainingFrame as getContainingFrame3,
|
|
231
|
+
getCornerRadius as getCornerRadius2,
|
|
232
|
+
getCursorForResizingElement,
|
|
233
|
+
getDragOffsetXY,
|
|
234
|
+
getElementAbsoluteCoords as getElementAbsoluteCoords8,
|
|
235
|
+
getElementBounds as getElementBounds5,
|
|
236
|
+
getElementsInGroup as getElementsInGroup10,
|
|
237
|
+
getElementsInNewFrame,
|
|
238
|
+
getElementsInResizingFrame as getElementsInResizingFrame4,
|
|
239
|
+
getElementsOverlappingFrame as getElementsOverlappingFrame2,
|
|
240
|
+
getElementWithTransformHandleType,
|
|
241
|
+
getEmbedLink as getEmbedLink2,
|
|
242
|
+
getFrameChildren as getFrameChildren6,
|
|
243
|
+
getFrameChildrenInsertionIndex as getFrameChildrenInsertionIndex2,
|
|
244
|
+
getFrameLikeTitle,
|
|
245
|
+
getHoveredElementForBinding as getHoveredElementForBinding2,
|
|
246
|
+
getInitializedImageElements,
|
|
247
|
+
getLineHeightInPx as getLineHeightInPx3,
|
|
248
|
+
getLinkDirectionFromKey,
|
|
249
|
+
getMinTextElementWidth,
|
|
250
|
+
getNormalizedDimensions,
|
|
251
|
+
getObservedAppState,
|
|
252
|
+
getRenderOpacity,
|
|
253
|
+
getResizeArrowDirection,
|
|
254
|
+
getResizeOffsetXY,
|
|
255
|
+
getSelectedGroupIdForElement,
|
|
256
|
+
getSelectedGroupIds as getSelectedGroupIds4,
|
|
257
|
+
getSelectionStateForElements as getSelectionStateForElements2,
|
|
258
|
+
getSnapOutlineMidPoint as getSnapOutlineMidPoint2,
|
|
259
|
+
getTransformHandleTypeFromCoords,
|
|
260
|
+
getUncroppedWidthAndHeight as getUncroppedWidthAndHeight4,
|
|
261
|
+
getVisibleSceneBounds,
|
|
262
|
+
handleFocusPointDrag,
|
|
263
|
+
handleFocusPointHover,
|
|
264
|
+
handleFocusPointPointerDown,
|
|
265
|
+
handleFocusPointPointerUp,
|
|
266
|
+
hasBoundingBox as hasBoundingBox2,
|
|
222
267
|
hasBoundTextElement as hasBoundTextElement9,
|
|
268
|
+
hitElementBoundingBox as hitElementBoundingBox2,
|
|
269
|
+
hitElementBoundingBoxOnly,
|
|
270
|
+
hitElementBoundText,
|
|
271
|
+
hitElementItself as hitElementItself3,
|
|
223
272
|
isArrowElement as isArrowElement14,
|
|
273
|
+
isBindableElement as isBindableElement3,
|
|
224
274
|
isBindingElement as isBindingElement4,
|
|
225
275
|
isBindingElementType,
|
|
276
|
+
isBindingEnabled as isBindingEnabled2,
|
|
226
277
|
isBoundToContainer as isBoundToContainer9,
|
|
278
|
+
isCursorInFrame,
|
|
279
|
+
isElbowArrow as isElbowArrow10,
|
|
280
|
+
isElementCompletelyInViewport as isElementCompletelyInViewport2,
|
|
281
|
+
isElementInFrame,
|
|
282
|
+
isElementInGroup as isElementInGroup2,
|
|
283
|
+
isElementInViewport as isElementInViewport3,
|
|
284
|
+
isElementLink as isElementLink2,
|
|
285
|
+
isEligibleFrameChildType,
|
|
286
|
+
isEmbeddableElement as isEmbeddableElement4,
|
|
287
|
+
isFlowchartNodeElement as isFlowchartNodeElement2,
|
|
227
288
|
isFrameLikeElement as isFrameLikeElement15,
|
|
289
|
+
isIframeElement as isIframeElement2,
|
|
290
|
+
isIframeLikeElement as isIframeLikeElement2,
|
|
228
291
|
isImageElement as isImageElement9,
|
|
229
|
-
isEmbeddableElement as isEmbeddableElement4,
|
|
230
292
|
isInitializedImageElement as isInitializedImageElement3,
|
|
293
|
+
isInvisiblySmallElement as isInvisiblySmallElement3,
|
|
231
294
|
isLinearElement as isLinearElement12,
|
|
232
295
|
isLinearElementType as isLinearElementType2,
|
|
233
|
-
|
|
234
|
-
isIframeElement as isIframeElement2,
|
|
235
|
-
isIframeLikeElement as isIframeLikeElement2,
|
|
296
|
+
isLineElement as isLineElement8,
|
|
236
297
|
isMagicFrameElement as isMagicFrameElement2,
|
|
298
|
+
isMeasureTextSupported,
|
|
299
|
+
isNonDeletedElement,
|
|
300
|
+
isPathALoop as isPathALoop3,
|
|
301
|
+
isPointInElement as isPointInElement3,
|
|
302
|
+
isSelectedViaGroup as isSelectedViaGroup2,
|
|
303
|
+
isSimpleArrow,
|
|
237
304
|
isTextBindableContainer as isTextBindableContainer3,
|
|
238
|
-
isElbowArrow as isElbowArrow10,
|
|
239
|
-
isFlowchartNodeElement as isFlowchartNodeElement2,
|
|
240
|
-
isBindableElement as isBindableElement3,
|
|
241
305
|
isTextElement as isTextElement19,
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
isPathALoop as isPathALoop3,
|
|
248
|
-
createSrcDoc,
|
|
249
|
-
embeddableURLValidator as embeddableURLValidator2,
|
|
306
|
+
isUsingAdaptiveRadius as isUsingAdaptiveRadius4,
|
|
307
|
+
isValidTextContainer,
|
|
308
|
+
makeNextSelectedElementIds as makeNextSelectedElementIds3,
|
|
309
|
+
maxBindingDistance_simple as maxBindingDistance_simple3,
|
|
310
|
+
maybeHandleArrowPointlikeDrag,
|
|
250
311
|
maybeParseEmbedSrc,
|
|
251
|
-
|
|
252
|
-
|
|
312
|
+
measureText as measureText8,
|
|
313
|
+
mutateElement as mutateElement6,
|
|
314
|
+
newArrowElement as newArrowElement2,
|
|
315
|
+
newElement as newElement6,
|
|
316
|
+
newElementWith as newElementWith10,
|
|
317
|
+
newEmbeddableElement,
|
|
318
|
+
newFrameElement as newFrameElement2,
|
|
319
|
+
newFreeDrawElement,
|
|
320
|
+
newIframeElement,
|
|
321
|
+
newImageElement,
|
|
322
|
+
newLinearElement as newLinearElement5,
|
|
323
|
+
newMagicFrameElement,
|
|
324
|
+
newTextElement as newTextElement5,
|
|
253
325
|
normalizeSVG,
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
getContainerElement as getContainerElement5,
|
|
258
|
-
isValidTextContainer,
|
|
326
|
+
normalizeText as normalizeText2,
|
|
327
|
+
parseElementLinkFromURL,
|
|
328
|
+
positionElementsOnGrid,
|
|
259
329
|
redrawTextBoundingBox as redrawTextBoundingBox8,
|
|
260
|
-
|
|
261
|
-
getCommonFrameId as getCommonFrameId2,
|
|
262
|
-
getFrameChildren as getFrameChildren6,
|
|
263
|
-
getFrameChildrenInsertionIndex as getFrameChildrenInsertionIndex2,
|
|
264
|
-
isCursorInFrame,
|
|
265
|
-
addElementsToFrame as addElementsToFrame2,
|
|
266
|
-
replaceAllElementsInFrame as replaceAllElementsInFrame4,
|
|
330
|
+
refreshTextDimensions,
|
|
267
331
|
removeElementsFromFrame as removeElementsFromFrame2,
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
getContainingFrame as getContainingFrame3,
|
|
271
|
-
elementOverlapsWithFrame as elementOverlapsWithFrame2,
|
|
272
|
-
updateFrameMembershipOfSelectedElements as updateFrameMembershipOfSelectedElements6,
|
|
273
|
-
isElementInFrame,
|
|
274
|
-
getFrameLikeTitle,
|
|
275
|
-
getElementsOverlappingFrame as getElementsOverlappingFrame2,
|
|
276
|
-
filterElementsEligibleAsFrameChildren,
|
|
277
|
-
hitElementBoundText,
|
|
278
|
-
hitElementBoundingBoxOnly,
|
|
279
|
-
hitElementItself as hitElementItself3,
|
|
280
|
-
getVisibleSceneBounds,
|
|
281
|
-
FlowChartCreator,
|
|
282
|
-
FlowChartNavigator,
|
|
283
|
-
getLinkDirectionFromKey,
|
|
284
|
-
cropElement,
|
|
285
|
-
wrapText as wrapText5,
|
|
286
|
-
isElementLink as isElementLink2,
|
|
287
|
-
parseElementLinkFromURL,
|
|
288
|
-
isMeasureTextSupported,
|
|
289
|
-
normalizeText as normalizeText2,
|
|
290
|
-
measureText as measureText8,
|
|
291
|
-
getLineHeightInPx as getLineHeightInPx3,
|
|
292
|
-
getApproxMinLineWidth as getApproxMinLineWidth2,
|
|
293
|
-
getApproxMinLineHeight,
|
|
294
|
-
getMinTextElementWidth,
|
|
295
|
-
ShapeCache as ShapeCache4,
|
|
296
|
-
getRenderOpacity,
|
|
297
|
-
editGroupForSelectedElement,
|
|
298
|
-
getElementsInGroup as getElementsInGroup10,
|
|
299
|
-
getSelectedGroupIdForElement,
|
|
300
|
-
getSelectedGroupIds as getSelectedGroupIds4,
|
|
301
|
-
isElementInGroup as isElementInGroup2,
|
|
302
|
-
isSelectedViaGroup as isSelectedViaGroup2,
|
|
332
|
+
replaceAllElementsInFrame as replaceAllElementsInFrame4,
|
|
333
|
+
Scene,
|
|
303
334
|
selectGroupsForSelectedElements as selectGroupsForSelectedElements7,
|
|
335
|
+
ShapeCache as ShapeCache4,
|
|
336
|
+
Store,
|
|
337
|
+
StoreDelta as StoreDelta2,
|
|
304
338
|
syncInvalidIndices,
|
|
305
339
|
syncMovedIndices as syncMovedIndices5,
|
|
306
|
-
excludeElementsInFramesFromSelection,
|
|
307
|
-
getSelectionStateForElements as getSelectionStateForElements2,
|
|
308
|
-
makeNextSelectedElementIds as makeNextSelectedElementIds3,
|
|
309
|
-
getResizeOffsetXY,
|
|
310
|
-
getResizeArrowDirection,
|
|
311
340
|
transformElements,
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
dragNewElement,
|
|
316
|
-
dragSelectedElements,
|
|
317
|
-
getDragOffsetXY,
|
|
318
|
-
isNonDeletedElement,
|
|
319
|
-
Scene,
|
|
320
|
-
Store,
|
|
321
|
-
CaptureUpdateAction as CaptureUpdateAction41,
|
|
322
|
-
hitElementBoundingBox as hitElementBoundingBox2,
|
|
323
|
-
isLineElement as isLineElement8,
|
|
324
|
-
isSimpleArrow,
|
|
325
|
-
StoreDelta as StoreDelta2,
|
|
326
|
-
positionElementsOnGrid,
|
|
327
|
-
calculateFixedPointForNonElbowArrowBinding as calculateFixedPointForNonElbowArrowBinding2,
|
|
328
|
-
bindOrUnbindBindingElement as bindOrUnbindBindingElement2,
|
|
329
|
-
mutateElement as mutateElement6,
|
|
330
|
-
getElementBounds as getElementBounds5,
|
|
331
|
-
doBoundsIntersect as doBoundsIntersect4,
|
|
332
|
-
isPointInElement as isPointInElement3,
|
|
333
|
-
maxBindingDistance_simple as maxBindingDistance_simple3,
|
|
334
|
-
convertToExcalidrawElements,
|
|
335
|
-
getSnapOutlineMidPoint as getSnapOutlineMidPoint2,
|
|
336
|
-
handleFocusPointDrag,
|
|
337
|
-
handleFocusPointHover,
|
|
338
|
-
handleFocusPointPointerDown,
|
|
339
|
-
handleFocusPointPointerUp,
|
|
340
|
-
maybeHandleArrowPointlikeDrag,
|
|
341
|
-
getUncroppedWidthAndHeight as getUncroppedWidthAndHeight4,
|
|
342
|
-
getActiveTextElement as getActiveTextElement2,
|
|
343
|
-
isEligibleFrameChildType
|
|
341
|
+
updateBoundElements as updateBoundElements4,
|
|
342
|
+
updateFrameMembershipOfSelectedElements as updateFrameMembershipOfSelectedElements6,
|
|
343
|
+
wrapText as wrapText5
|
|
344
344
|
} from "@excalidraw/element";
|
|
345
345
|
import { LinearElementEditor as LinearElementEditor11 } from "@excalidraw/element/linearElementEditor";
|
|
346
346
|
import { findShapeByKey } from "@excalidraw/element/shapes";
|
|
@@ -9611,7 +9611,7 @@ var exportCanvas = async (type, elements, appState, files, {
|
|
|
9611
9611
|
let blob = canvasToBlob(tempCanvas);
|
|
9612
9612
|
if (appState.exportEmbedScene) {
|
|
9613
9613
|
blob = blob.then(
|
|
9614
|
-
(blob2) => import("./data/image-
|
|
9614
|
+
(blob2) => import("./data/image-WGZL7YPK.js").then(
|
|
9615
9615
|
({ encodePngMetadata: encodePngMetadata2 }) => encodePngMetadata2({
|
|
9616
9616
|
blob: blob2,
|
|
9617
9617
|
metadata: serializeAsJSON(elements, appState, files, "local")
|
|
@@ -15025,980 +15025,428 @@ var getCenter = (pointers) => {
|
|
|
15025
15025
|
var getDistance = ([a, b]) => Math.hypot(a.x - b.x, a.y - b.y);
|
|
15026
15026
|
var sum = (array, mapper) => array.reduce((acc, item) => acc + mapper(item), 0);
|
|
15027
15027
|
|
|
15028
|
-
//
|
|
15029
|
-
import {
|
|
15030
|
-
|
|
15031
|
-
|
|
15032
|
-
|
|
15033
|
-
|
|
15034
|
-
|
|
15035
|
-
}
|
|
15036
|
-
|
|
15037
|
-
|
|
15038
|
-
getCommonBounds as getCommonBounds4,
|
|
15039
|
-
getDraggedElementsBounds,
|
|
15040
|
-
getElementAbsoluteCoords as getElementAbsoluteCoords4
|
|
15041
|
-
} from "@excalidraw/element";
|
|
15042
|
-
import { isBoundToContainer as isBoundToContainer6 } from "@excalidraw/element";
|
|
15043
|
-
import { getMaximumGroups } from "@excalidraw/element";
|
|
15044
|
-
import {
|
|
15045
|
-
getSelectedElements as getSelectedElements4,
|
|
15046
|
-
getVisibleAndNonSelectedElements
|
|
15047
|
-
} from "@excalidraw/element";
|
|
15048
|
-
var SNAP_DISTANCE = 8;
|
|
15049
|
-
var VISIBLE_GAPS_LIMIT_PER_AXIS = 99999;
|
|
15050
|
-
var getSnapDistance = (zoomValue) => {
|
|
15051
|
-
return SNAP_DISTANCE / zoomValue;
|
|
15052
|
-
};
|
|
15053
|
-
var _SnapCache = class _SnapCache {
|
|
15054
|
-
};
|
|
15055
|
-
__publicField(_SnapCache, "referenceSnapPoints", null);
|
|
15056
|
-
__publicField(_SnapCache, "visibleGaps", null);
|
|
15057
|
-
__publicField(_SnapCache, "setReferenceSnapPoints", (snapPoints) => {
|
|
15058
|
-
_SnapCache.referenceSnapPoints = snapPoints;
|
|
15059
|
-
});
|
|
15060
|
-
__publicField(_SnapCache, "getReferenceSnapPoints", () => {
|
|
15061
|
-
return _SnapCache.referenceSnapPoints;
|
|
15062
|
-
});
|
|
15063
|
-
__publicField(_SnapCache, "setVisibleGaps", (gaps) => {
|
|
15064
|
-
_SnapCache.visibleGaps = gaps;
|
|
15065
|
-
});
|
|
15066
|
-
__publicField(_SnapCache, "getVisibleGaps", () => {
|
|
15067
|
-
return _SnapCache.visibleGaps;
|
|
15068
|
-
});
|
|
15069
|
-
__publicField(_SnapCache, "destroy", () => {
|
|
15070
|
-
_SnapCache.referenceSnapPoints = null;
|
|
15071
|
-
_SnapCache.visibleGaps = null;
|
|
15072
|
-
});
|
|
15073
|
-
var SnapCache = _SnapCache;
|
|
15074
|
-
var isGridModeEnabled = (app) => app.props.gridModeEnabled ?? app.state.gridModeEnabled;
|
|
15075
|
-
var isSnappingEnabled = ({
|
|
15076
|
-
event,
|
|
15077
|
-
app,
|
|
15078
|
-
selectedElements
|
|
15079
|
-
}) => {
|
|
15080
|
-
if (event) {
|
|
15081
|
-
const isLassoDragging = app.state.activeTool.type === "lasso" && app.state.selectedElementsAreBeingDragged;
|
|
15082
|
-
return (app.state.activeTool.type !== "lasso" || isLassoDragging) && (app.state.objectsSnapModeEnabled && !event[KEYS34.CTRL_OR_CMD] || !app.state.objectsSnapModeEnabled && event[KEYS34.CTRL_OR_CMD] && !isGridModeEnabled(app));
|
|
15083
|
-
}
|
|
15084
|
-
if (selectedElements.length === 1 && selectedElements[0].type === "arrow") {
|
|
15085
|
-
return false;
|
|
15086
|
-
}
|
|
15087
|
-
return app.state.objectsSnapModeEnabled;
|
|
15088
|
-
};
|
|
15089
|
-
var areRoughlyEqual = (a, b, precision = 0.01) => {
|
|
15090
|
-
return Math.abs(a - b) <= precision;
|
|
15091
|
-
};
|
|
15092
|
-
var getElementsCorners = (elements, elementsMap, {
|
|
15093
|
-
omitCenter,
|
|
15094
|
-
boundingBoxCorners,
|
|
15095
|
-
dragOffset
|
|
15096
|
-
} = {
|
|
15097
|
-
omitCenter: false,
|
|
15098
|
-
boundingBoxCorners: false
|
|
15099
|
-
}) => {
|
|
15100
|
-
let result = [];
|
|
15101
|
-
if (elements.length === 1) {
|
|
15102
|
-
const element = elements[0];
|
|
15103
|
-
let [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords4(
|
|
15104
|
-
element,
|
|
15105
|
-
elementsMap
|
|
15106
|
-
);
|
|
15107
|
-
if (dragOffset) {
|
|
15108
|
-
x1 += dragOffset.x;
|
|
15109
|
-
x2 += dragOffset.x;
|
|
15110
|
-
cx += dragOffset.x;
|
|
15111
|
-
y1 += dragOffset.y;
|
|
15112
|
-
y2 += dragOffset.y;
|
|
15113
|
-
cy += dragOffset.y;
|
|
15114
|
-
}
|
|
15115
|
-
const halfWidth = (x2 - x1) / 2;
|
|
15116
|
-
const halfHeight = (y2 - y1) / 2;
|
|
15117
|
-
if ((element.type === "diamond" || element.type === "ellipse") && !boundingBoxCorners) {
|
|
15118
|
-
const leftMid = pointRotateRads14(
|
|
15119
|
-
pointFrom18(x1, y1 + halfHeight),
|
|
15120
|
-
pointFrom18(cx, cy),
|
|
15121
|
-
element.angle
|
|
15122
|
-
);
|
|
15123
|
-
const topMid = pointRotateRads14(
|
|
15124
|
-
pointFrom18(x1 + halfWidth, y1),
|
|
15125
|
-
pointFrom18(cx, cy),
|
|
15126
|
-
element.angle
|
|
15127
|
-
);
|
|
15128
|
-
const rightMid = pointRotateRads14(
|
|
15129
|
-
pointFrom18(x2, y1 + halfHeight),
|
|
15130
|
-
pointFrom18(cx, cy),
|
|
15131
|
-
element.angle
|
|
15132
|
-
);
|
|
15133
|
-
const bottomMid = pointRotateRads14(
|
|
15134
|
-
pointFrom18(x1 + halfWidth, y2),
|
|
15135
|
-
pointFrom18(cx, cy),
|
|
15136
|
-
element.angle
|
|
15137
|
-
);
|
|
15138
|
-
const center = pointFrom18(cx, cy);
|
|
15139
|
-
result = omitCenter ? [leftMid, topMid, rightMid, bottomMid] : [leftMid, topMid, rightMid, bottomMid, center];
|
|
15140
|
-
} else {
|
|
15141
|
-
const topLeft = pointRotateRads14(
|
|
15142
|
-
pointFrom18(x1, y1),
|
|
15143
|
-
pointFrom18(cx, cy),
|
|
15144
|
-
element.angle
|
|
15145
|
-
);
|
|
15146
|
-
const topRight = pointRotateRads14(
|
|
15147
|
-
pointFrom18(x2, y1),
|
|
15148
|
-
pointFrom18(cx, cy),
|
|
15149
|
-
element.angle
|
|
15150
|
-
);
|
|
15151
|
-
const bottomLeft = pointRotateRads14(
|
|
15152
|
-
pointFrom18(x1, y2),
|
|
15153
|
-
pointFrom18(cx, cy),
|
|
15154
|
-
element.angle
|
|
15155
|
-
);
|
|
15156
|
-
const bottomRight = pointRotateRads14(
|
|
15157
|
-
pointFrom18(x2, y2),
|
|
15158
|
-
pointFrom18(cx, cy),
|
|
15159
|
-
element.angle
|
|
15160
|
-
);
|
|
15161
|
-
const center = pointFrom18(cx, cy);
|
|
15162
|
-
result = omitCenter ? [topLeft, topRight, bottomLeft, bottomRight] : [topLeft, topRight, bottomLeft, bottomRight, center];
|
|
15163
|
-
}
|
|
15164
|
-
} else if (elements.length > 1) {
|
|
15165
|
-
const [minX, minY, maxX, maxY] = getDraggedElementsBounds(
|
|
15166
|
-
elements,
|
|
15167
|
-
dragOffset ?? { x: 0, y: 0 }
|
|
15168
|
-
);
|
|
15169
|
-
const width = maxX - minX;
|
|
15170
|
-
const height = maxY - minY;
|
|
15171
|
-
const topLeft = pointFrom18(minX, minY);
|
|
15172
|
-
const topRight = pointFrom18(maxX, minY);
|
|
15173
|
-
const bottomLeft = pointFrom18(minX, maxY);
|
|
15174
|
-
const bottomRight = pointFrom18(maxX, maxY);
|
|
15175
|
-
const center = pointFrom18(minX + width / 2, minY + height / 2);
|
|
15176
|
-
result = omitCenter ? [topLeft, topRight, bottomLeft, bottomRight] : [topLeft, topRight, bottomLeft, bottomRight, center];
|
|
15177
|
-
}
|
|
15178
|
-
return result.map((p) => pointFrom18(round(p[0]), round(p[1])));
|
|
15179
|
-
};
|
|
15180
|
-
var getReferenceElements = (elements, selectedElements, appState, elementsMap) => getVisibleAndNonSelectedElements(
|
|
15181
|
-
elements,
|
|
15182
|
-
selectedElements,
|
|
15183
|
-
appState,
|
|
15184
|
-
elementsMap
|
|
15185
|
-
);
|
|
15186
|
-
var getVisibleGaps = (elements, selectedElements, appState, elementsMap) => {
|
|
15187
|
-
const referenceElements = getReferenceElements(
|
|
15188
|
-
elements,
|
|
15189
|
-
selectedElements,
|
|
15190
|
-
appState,
|
|
15191
|
-
elementsMap
|
|
15192
|
-
);
|
|
15193
|
-
const referenceBounds = getMaximumGroups(referenceElements, elementsMap).filter(
|
|
15194
|
-
(elementsGroup) => !(elementsGroup.length === 1 && isBoundToContainer6(elementsGroup[0]))
|
|
15195
|
-
).map(
|
|
15196
|
-
(group) => getCommonBounds4(group).map(
|
|
15197
|
-
(bound) => round(bound)
|
|
15198
|
-
)
|
|
15199
|
-
);
|
|
15200
|
-
const horizontallySorted = referenceBounds.sort((a, b) => a[0] - b[0]);
|
|
15201
|
-
const horizontalGaps = [];
|
|
15202
|
-
let c = 0;
|
|
15203
|
-
horizontal:
|
|
15204
|
-
for (let i = 0; i < horizontallySorted.length; i++) {
|
|
15205
|
-
const startBounds = horizontallySorted[i];
|
|
15206
|
-
for (let j = i + 1; j < horizontallySorted.length; j++) {
|
|
15207
|
-
if (++c > VISIBLE_GAPS_LIMIT_PER_AXIS) {
|
|
15208
|
-
break horizontal;
|
|
15209
|
-
}
|
|
15210
|
-
const endBounds = horizontallySorted[j];
|
|
15211
|
-
const [, startMinY, startMaxX, startMaxY] = startBounds;
|
|
15212
|
-
const [endMinX, endMinY, , endMaxY] = endBounds;
|
|
15213
|
-
if (startMaxX < endMinX && rangesOverlap(
|
|
15214
|
-
rangeInclusive(startMinY, startMaxY),
|
|
15215
|
-
rangeInclusive(endMinY, endMaxY)
|
|
15216
|
-
)) {
|
|
15217
|
-
horizontalGaps.push({
|
|
15218
|
-
startBounds,
|
|
15219
|
-
endBounds,
|
|
15220
|
-
startSide: [
|
|
15221
|
-
pointFrom18(startMaxX, startMinY),
|
|
15222
|
-
pointFrom18(startMaxX, startMaxY)
|
|
15223
|
-
],
|
|
15224
|
-
endSide: [pointFrom18(endMinX, endMinY), pointFrom18(endMinX, endMaxY)],
|
|
15225
|
-
length: endMinX - startMaxX,
|
|
15226
|
-
overlap: rangeIntersection(
|
|
15227
|
-
rangeInclusive(startMinY, startMaxY),
|
|
15228
|
-
rangeInclusive(endMinY, endMaxY)
|
|
15229
|
-
)
|
|
15230
|
-
});
|
|
15231
|
-
}
|
|
15232
|
-
}
|
|
15233
|
-
}
|
|
15234
|
-
const verticallySorted = referenceBounds.sort((a, b) => a[1] - b[1]);
|
|
15235
|
-
const verticalGaps = [];
|
|
15236
|
-
c = 0;
|
|
15237
|
-
vertical:
|
|
15238
|
-
for (let i = 0; i < verticallySorted.length; i++) {
|
|
15239
|
-
const startBounds = verticallySorted[i];
|
|
15240
|
-
for (let j = i + 1; j < verticallySorted.length; j++) {
|
|
15241
|
-
if (++c > VISIBLE_GAPS_LIMIT_PER_AXIS) {
|
|
15242
|
-
break vertical;
|
|
15243
|
-
}
|
|
15244
|
-
const endBounds = verticallySorted[j];
|
|
15245
|
-
const [startMinX, , startMaxX, startMaxY] = startBounds;
|
|
15246
|
-
const [endMinX, endMinY, endMaxX] = endBounds;
|
|
15247
|
-
if (startMaxY < endMinY && rangesOverlap(
|
|
15248
|
-
rangeInclusive(startMinX, startMaxX),
|
|
15249
|
-
rangeInclusive(endMinX, endMaxX)
|
|
15250
|
-
)) {
|
|
15251
|
-
verticalGaps.push({
|
|
15252
|
-
startBounds,
|
|
15253
|
-
endBounds,
|
|
15254
|
-
startSide: [
|
|
15255
|
-
pointFrom18(startMinX, startMaxY),
|
|
15256
|
-
pointFrom18(startMaxX, startMaxY)
|
|
15257
|
-
],
|
|
15258
|
-
endSide: [pointFrom18(endMinX, endMinY), pointFrom18(endMaxX, endMinY)],
|
|
15259
|
-
length: endMinY - startMaxY,
|
|
15260
|
-
overlap: rangeIntersection(
|
|
15261
|
-
rangeInclusive(startMinX, startMaxX),
|
|
15262
|
-
rangeInclusive(endMinX, endMaxX)
|
|
15263
|
-
)
|
|
15264
|
-
});
|
|
15265
|
-
}
|
|
15266
|
-
}
|
|
15267
|
-
}
|
|
15268
|
-
return {
|
|
15269
|
-
horizontalGaps,
|
|
15270
|
-
verticalGaps
|
|
15271
|
-
};
|
|
15272
|
-
};
|
|
15273
|
-
var getGapSnaps = (selectedElements, dragOffset, app, event, nearestSnapsX, nearestSnapsY, minOffset) => {
|
|
15274
|
-
if (!isSnappingEnabled({ app, event, selectedElements })) {
|
|
15275
|
-
return [];
|
|
15276
|
-
}
|
|
15277
|
-
if (selectedElements.length === 0) {
|
|
15278
|
-
return [];
|
|
15279
|
-
}
|
|
15280
|
-
const visibleGaps = SnapCache.getVisibleGaps();
|
|
15281
|
-
if (visibleGaps) {
|
|
15282
|
-
const { horizontalGaps, verticalGaps } = visibleGaps;
|
|
15283
|
-
const [minX, minY, maxX, maxY] = getDraggedElementsBounds(
|
|
15284
|
-
selectedElements,
|
|
15285
|
-
dragOffset
|
|
15286
|
-
).map((bound) => round(bound));
|
|
15287
|
-
const centerX = (minX + maxX) / 2;
|
|
15288
|
-
const centerY = (minY + maxY) / 2;
|
|
15289
|
-
for (const gap of horizontalGaps) {
|
|
15290
|
-
if (!rangesOverlap(rangeInclusive(minY, maxY), gap.overlap)) {
|
|
15291
|
-
continue;
|
|
15292
|
-
}
|
|
15293
|
-
const gapMidX = gap.startSide[0][0] + gap.length / 2;
|
|
15294
|
-
const centerOffset = round(gapMidX - centerX);
|
|
15295
|
-
const gapIsLargerThanSelection = gap.length > maxX - minX;
|
|
15296
|
-
if (gapIsLargerThanSelection && Math.abs(centerOffset) <= minOffset.x) {
|
|
15297
|
-
if (Math.abs(centerOffset) < minOffset.x) {
|
|
15298
|
-
nearestSnapsX.length = 0;
|
|
15299
|
-
}
|
|
15300
|
-
minOffset.x = Math.abs(centerOffset);
|
|
15301
|
-
const snap = {
|
|
15302
|
-
type: "gap",
|
|
15303
|
-
direction: "center_horizontal",
|
|
15304
|
-
gap,
|
|
15305
|
-
offset: centerOffset
|
|
15306
|
-
};
|
|
15307
|
-
nearestSnapsX.push(snap);
|
|
15308
|
-
continue;
|
|
15309
|
-
}
|
|
15310
|
-
const [, , endMaxX] = gap.endBounds;
|
|
15311
|
-
const distanceToEndElementX = minX - endMaxX;
|
|
15312
|
-
const sideOffsetRight = round(gap.length - distanceToEndElementX);
|
|
15313
|
-
if (Math.abs(sideOffsetRight) <= minOffset.x) {
|
|
15314
|
-
if (Math.abs(sideOffsetRight) < minOffset.x) {
|
|
15315
|
-
nearestSnapsX.length = 0;
|
|
15316
|
-
}
|
|
15317
|
-
minOffset.x = Math.abs(sideOffsetRight);
|
|
15318
|
-
const snap = {
|
|
15319
|
-
type: "gap",
|
|
15320
|
-
direction: "side_right",
|
|
15321
|
-
gap,
|
|
15322
|
-
offset: sideOffsetRight
|
|
15323
|
-
};
|
|
15324
|
-
nearestSnapsX.push(snap);
|
|
15325
|
-
continue;
|
|
15326
|
-
}
|
|
15327
|
-
const [startMinX, , ,] = gap.startBounds;
|
|
15328
|
-
const distanceToStartElementX = startMinX - maxX;
|
|
15329
|
-
const sideOffsetLeft = round(distanceToStartElementX - gap.length);
|
|
15330
|
-
if (Math.abs(sideOffsetLeft) <= minOffset.x) {
|
|
15331
|
-
if (Math.abs(sideOffsetLeft) < minOffset.x) {
|
|
15332
|
-
nearestSnapsX.length = 0;
|
|
15333
|
-
}
|
|
15334
|
-
minOffset.x = Math.abs(sideOffsetLeft);
|
|
15335
|
-
const snap = {
|
|
15336
|
-
type: "gap",
|
|
15337
|
-
direction: "side_left",
|
|
15338
|
-
gap,
|
|
15339
|
-
offset: sideOffsetLeft
|
|
15340
|
-
};
|
|
15341
|
-
nearestSnapsX.push(snap);
|
|
15342
|
-
continue;
|
|
15343
|
-
}
|
|
15344
|
-
}
|
|
15345
|
-
for (const gap of verticalGaps) {
|
|
15346
|
-
if (!rangesOverlap(rangeInclusive(minX, maxX), gap.overlap)) {
|
|
15347
|
-
continue;
|
|
15348
|
-
}
|
|
15349
|
-
const gapMidY = gap.startSide[0][1] + gap.length / 2;
|
|
15350
|
-
const centerOffset = round(gapMidY - centerY);
|
|
15351
|
-
const gapIsLargerThanSelection = gap.length > maxY - minY;
|
|
15352
|
-
if (gapIsLargerThanSelection && Math.abs(centerOffset) <= minOffset.y) {
|
|
15353
|
-
if (Math.abs(centerOffset) < minOffset.y) {
|
|
15354
|
-
nearestSnapsY.length = 0;
|
|
15355
|
-
}
|
|
15356
|
-
minOffset.y = Math.abs(centerOffset);
|
|
15357
|
-
const snap = {
|
|
15358
|
-
type: "gap",
|
|
15359
|
-
direction: "center_vertical",
|
|
15360
|
-
gap,
|
|
15361
|
-
offset: centerOffset
|
|
15362
|
-
};
|
|
15363
|
-
nearestSnapsY.push(snap);
|
|
15364
|
-
continue;
|
|
15365
|
-
}
|
|
15366
|
-
const [, startMinY, ,] = gap.startBounds;
|
|
15367
|
-
const distanceToStartElementY = startMinY - maxY;
|
|
15368
|
-
const sideOffsetTop = round(distanceToStartElementY - gap.length);
|
|
15369
|
-
if (Math.abs(sideOffsetTop) <= minOffset.y) {
|
|
15370
|
-
if (Math.abs(sideOffsetTop) < minOffset.y) {
|
|
15371
|
-
nearestSnapsY.length = 0;
|
|
15372
|
-
}
|
|
15373
|
-
minOffset.y = Math.abs(sideOffsetTop);
|
|
15374
|
-
const snap = {
|
|
15375
|
-
type: "gap",
|
|
15376
|
-
direction: "side_top",
|
|
15377
|
-
gap,
|
|
15378
|
-
offset: sideOffsetTop
|
|
15379
|
-
};
|
|
15380
|
-
nearestSnapsY.push(snap);
|
|
15381
|
-
continue;
|
|
15382
|
-
}
|
|
15383
|
-
const [, , , endMaxY] = gap.endBounds;
|
|
15384
|
-
const distanceToEndElementY = round(minY - endMaxY);
|
|
15385
|
-
const sideOffsetBottom = gap.length - distanceToEndElementY;
|
|
15386
|
-
if (Math.abs(sideOffsetBottom) <= minOffset.y) {
|
|
15387
|
-
if (Math.abs(sideOffsetBottom) < minOffset.y) {
|
|
15388
|
-
nearestSnapsY.length = 0;
|
|
15389
|
-
}
|
|
15390
|
-
minOffset.y = Math.abs(sideOffsetBottom);
|
|
15391
|
-
const snap = {
|
|
15392
|
-
type: "gap",
|
|
15393
|
-
direction: "side_bottom",
|
|
15394
|
-
gap,
|
|
15395
|
-
offset: sideOffsetBottom
|
|
15396
|
-
};
|
|
15397
|
-
nearestSnapsY.push(snap);
|
|
15398
|
-
continue;
|
|
15399
|
-
}
|
|
15400
|
-
}
|
|
15401
|
-
}
|
|
15402
|
-
};
|
|
15403
|
-
var getReferenceSnapPoints = (elements, selectedElements, appState, elementsMap) => {
|
|
15404
|
-
const referenceElements = getReferenceElements(
|
|
15405
|
-
elements,
|
|
15406
|
-
selectedElements,
|
|
15407
|
-
appState,
|
|
15408
|
-
elementsMap
|
|
15409
|
-
);
|
|
15410
|
-
return getMaximumGroups(referenceElements, elementsMap).filter(
|
|
15411
|
-
(elementsGroup) => !(elementsGroup.length === 1 && isBoundToContainer6(elementsGroup[0]))
|
|
15412
|
-
).flatMap((elementGroup) => getElementsCorners(elementGroup, elementsMap));
|
|
15413
|
-
};
|
|
15414
|
-
var getPointSnaps = (selectedElements, selectionSnapPoints, app, event, nearestSnapsX, nearestSnapsY, minOffset) => {
|
|
15415
|
-
if (!isSnappingEnabled({ app, event, selectedElements }) || selectedElements.length === 0 && selectionSnapPoints.length === 0) {
|
|
15416
|
-
return [];
|
|
15417
|
-
}
|
|
15418
|
-
const referenceSnapPoints = SnapCache.getReferenceSnapPoints();
|
|
15419
|
-
if (referenceSnapPoints) {
|
|
15420
|
-
for (const thisSnapPoint of selectionSnapPoints) {
|
|
15421
|
-
for (const otherSnapPoint of referenceSnapPoints) {
|
|
15422
|
-
const offsetX = otherSnapPoint[0] - thisSnapPoint[0];
|
|
15423
|
-
const offsetY = otherSnapPoint[1] - thisSnapPoint[1];
|
|
15424
|
-
if (Math.abs(offsetX) <= minOffset.x) {
|
|
15425
|
-
if (Math.abs(offsetX) < minOffset.x) {
|
|
15426
|
-
nearestSnapsX.length = 0;
|
|
15427
|
-
}
|
|
15428
|
-
nearestSnapsX.push({
|
|
15429
|
-
type: "point",
|
|
15430
|
-
points: [thisSnapPoint, otherSnapPoint],
|
|
15431
|
-
offset: offsetX
|
|
15432
|
-
});
|
|
15433
|
-
minOffset.x = Math.abs(offsetX);
|
|
15434
|
-
}
|
|
15435
|
-
if (Math.abs(offsetY) <= minOffset.y) {
|
|
15436
|
-
if (Math.abs(offsetY) < minOffset.y) {
|
|
15437
|
-
nearestSnapsY.length = 0;
|
|
15438
|
-
}
|
|
15439
|
-
nearestSnapsY.push({
|
|
15440
|
-
type: "point",
|
|
15441
|
-
points: [thisSnapPoint, otherSnapPoint],
|
|
15442
|
-
offset: offsetY
|
|
15443
|
-
});
|
|
15444
|
-
minOffset.y = Math.abs(offsetY);
|
|
15445
|
-
}
|
|
15446
|
-
}
|
|
15447
|
-
}
|
|
15448
|
-
}
|
|
15449
|
-
};
|
|
15450
|
-
var snapDraggedElements = (elements, dragOffset, app, event, elementsMap) => {
|
|
15451
|
-
const appState = app.state;
|
|
15452
|
-
const selectedElements = getSelectedElements4(elements, appState);
|
|
15453
|
-
if (!isSnappingEnabled({ app, event, selectedElements }) || selectedElements.length === 0) {
|
|
15454
|
-
return {
|
|
15455
|
-
snapOffset: {
|
|
15456
|
-
x: 0,
|
|
15457
|
-
y: 0
|
|
15458
|
-
},
|
|
15459
|
-
snapLines: []
|
|
15460
|
-
};
|
|
15461
|
-
}
|
|
15462
|
-
dragOffset.x = round(dragOffset.x);
|
|
15463
|
-
dragOffset.y = round(dragOffset.y);
|
|
15464
|
-
const nearestSnapsX = [];
|
|
15465
|
-
const nearestSnapsY = [];
|
|
15466
|
-
const snapDistance = getSnapDistance(appState.zoom.value);
|
|
15467
|
-
const minOffset = {
|
|
15468
|
-
x: snapDistance,
|
|
15469
|
-
y: snapDistance
|
|
15470
|
-
};
|
|
15471
|
-
const selectionPoints = getElementsCorners(selectedElements, elementsMap, {
|
|
15472
|
-
dragOffset
|
|
15473
|
-
});
|
|
15474
|
-
getPointSnaps(
|
|
15475
|
-
selectedElements,
|
|
15476
|
-
selectionPoints,
|
|
15477
|
-
app,
|
|
15478
|
-
event,
|
|
15479
|
-
nearestSnapsX,
|
|
15480
|
-
nearestSnapsY,
|
|
15481
|
-
minOffset
|
|
15482
|
-
);
|
|
15483
|
-
getGapSnaps(
|
|
15484
|
-
selectedElements,
|
|
15485
|
-
dragOffset,
|
|
15486
|
-
app,
|
|
15487
|
-
event,
|
|
15488
|
-
nearestSnapsX,
|
|
15489
|
-
nearestSnapsY,
|
|
15490
|
-
minOffset
|
|
15491
|
-
);
|
|
15492
|
-
const snapOffset = {
|
|
15493
|
-
x: nearestSnapsX[0]?.offset ?? 0,
|
|
15494
|
-
y: nearestSnapsY[0]?.offset ?? 0
|
|
15495
|
-
};
|
|
15496
|
-
minOffset.x = 0;
|
|
15497
|
-
minOffset.y = 0;
|
|
15498
|
-
nearestSnapsX.length = 0;
|
|
15499
|
-
nearestSnapsY.length = 0;
|
|
15500
|
-
const newDragOffset = {
|
|
15501
|
-
x: round(dragOffset.x + snapOffset.x),
|
|
15502
|
-
y: round(dragOffset.y + snapOffset.y)
|
|
15503
|
-
};
|
|
15504
|
-
getPointSnaps(
|
|
15505
|
-
selectedElements,
|
|
15506
|
-
getElementsCorners(selectedElements, elementsMap, {
|
|
15507
|
-
dragOffset: newDragOffset
|
|
15508
|
-
}),
|
|
15509
|
-
app,
|
|
15510
|
-
event,
|
|
15511
|
-
nearestSnapsX,
|
|
15512
|
-
nearestSnapsY,
|
|
15513
|
-
minOffset
|
|
15514
|
-
);
|
|
15515
|
-
getGapSnaps(
|
|
15516
|
-
selectedElements,
|
|
15517
|
-
newDragOffset,
|
|
15518
|
-
app,
|
|
15519
|
-
event,
|
|
15520
|
-
nearestSnapsX,
|
|
15521
|
-
nearestSnapsY,
|
|
15522
|
-
minOffset
|
|
15523
|
-
);
|
|
15524
|
-
const pointSnapLines = createPointSnapLines(nearestSnapsX, nearestSnapsY);
|
|
15525
|
-
const gapSnapLines = createGapSnapLines(
|
|
15526
|
-
selectedElements,
|
|
15527
|
-
newDragOffset,
|
|
15528
|
-
[...nearestSnapsX, ...nearestSnapsY].filter(
|
|
15529
|
-
(snap) => snap.type === "gap"
|
|
15530
|
-
)
|
|
15531
|
-
);
|
|
15532
|
-
return {
|
|
15533
|
-
snapOffset,
|
|
15534
|
-
snapLines: [...pointSnapLines, ...gapSnapLines]
|
|
15535
|
-
};
|
|
15536
|
-
};
|
|
15537
|
-
var round = (x) => {
|
|
15538
|
-
const decimalPlaces = 6;
|
|
15539
|
-
return Math.round(x * 10 ** decimalPlaces) / 10 ** decimalPlaces;
|
|
15540
|
-
};
|
|
15541
|
-
var dedupePoints = (points) => {
|
|
15542
|
-
const map = /* @__PURE__ */ new Map();
|
|
15543
|
-
for (const point of points) {
|
|
15544
|
-
const key = point.join(",");
|
|
15545
|
-
if (!map.has(key)) {
|
|
15546
|
-
map.set(key, point);
|
|
15547
|
-
}
|
|
15548
|
-
}
|
|
15549
|
-
return Array.from(map.values());
|
|
15550
|
-
};
|
|
15551
|
-
var createPointSnapLines = (nearestSnapsX, nearestSnapsY) => {
|
|
15552
|
-
const snapsX = {};
|
|
15553
|
-
const snapsY = {};
|
|
15554
|
-
if (nearestSnapsX.length > 0) {
|
|
15555
|
-
for (const snap of nearestSnapsX) {
|
|
15556
|
-
if (snap.type === "point") {
|
|
15557
|
-
const key = round(snap.points[0][0]);
|
|
15558
|
-
if (!snapsX[key]) {
|
|
15559
|
-
snapsX[key] = [];
|
|
15560
|
-
}
|
|
15561
|
-
snapsX[key].push(
|
|
15562
|
-
...snap.points.map(
|
|
15563
|
-
(p) => pointFrom18(round(p[0]), round(p[1]))
|
|
15564
|
-
)
|
|
15565
|
-
);
|
|
15566
|
-
}
|
|
15567
|
-
}
|
|
15568
|
-
}
|
|
15569
|
-
if (nearestSnapsY.length > 0) {
|
|
15570
|
-
for (const snap of nearestSnapsY) {
|
|
15571
|
-
if (snap.type === "point") {
|
|
15572
|
-
const key = round(snap.points[0][1]);
|
|
15573
|
-
if (!snapsY[key]) {
|
|
15574
|
-
snapsY[key] = [];
|
|
15575
|
-
}
|
|
15576
|
-
snapsY[key].push(
|
|
15577
|
-
...snap.points.map(
|
|
15578
|
-
(p) => pointFrom18(round(p[0]), round(p[1]))
|
|
15579
|
-
)
|
|
15580
|
-
);
|
|
15581
|
-
}
|
|
15582
|
-
}
|
|
15583
|
-
}
|
|
15584
|
-
return Object.entries(snapsX).map(([key, points]) => {
|
|
15585
|
-
return {
|
|
15586
|
-
type: "points",
|
|
15587
|
-
points: dedupePoints(
|
|
15588
|
-
points.map((p) => {
|
|
15589
|
-
return pointFrom18(Number(key), p[1]);
|
|
15590
|
-
}).sort((a, b) => a[1] - b[1])
|
|
15591
|
-
)
|
|
15592
|
-
};
|
|
15593
|
-
}).concat(
|
|
15594
|
-
Object.entries(snapsY).map(([key, points]) => {
|
|
15595
|
-
return {
|
|
15596
|
-
type: "points",
|
|
15597
|
-
points: dedupePoints(
|
|
15598
|
-
points.map((p) => {
|
|
15599
|
-
return pointFrom18(p[0], Number(key));
|
|
15600
|
-
}).sort((a, b) => a[0] - b[0])
|
|
15601
|
-
)
|
|
15602
|
-
};
|
|
15603
|
-
})
|
|
15028
|
+
// components/ElementCanvasButtons.tsx
|
|
15029
|
+
import { sceneCoordsToViewportCoords as sceneCoordsToViewportCoords2 } from "@excalidraw/common";
|
|
15030
|
+
import { getElementAbsoluteCoords as getElementAbsoluteCoords4 } from "@excalidraw/element";
|
|
15031
|
+
import { jsx as jsx57 } from "react/jsx-runtime";
|
|
15032
|
+
var CONTAINER_PADDING = 5;
|
|
15033
|
+
var getContainerCoords2 = (element, appState, elementsMap) => {
|
|
15034
|
+
const [x1, y1] = getElementAbsoluteCoords4(element, elementsMap);
|
|
15035
|
+
const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords2(
|
|
15036
|
+
{ sceneX: x1 + element.width, sceneY: y1 },
|
|
15037
|
+
appState
|
|
15604
15038
|
);
|
|
15039
|
+
const x = viewportX - appState.offsetLeft + 10;
|
|
15040
|
+
const y = viewportY - appState.offsetTop;
|
|
15041
|
+
return { x, y };
|
|
15605
15042
|
};
|
|
15606
|
-
var
|
|
15607
|
-
|
|
15608
|
-
|
|
15609
|
-
|
|
15610
|
-
|
|
15611
|
-
|
|
15612
|
-
|
|
15043
|
+
var ElementCanvasButtons = ({
|
|
15044
|
+
children,
|
|
15045
|
+
element,
|
|
15046
|
+
elementsMap
|
|
15047
|
+
}) => {
|
|
15048
|
+
const appState = useExcalidrawAppState();
|
|
15049
|
+
if (appState.contextMenu || appState.newElement || appState.resizingElement || appState.isRotating || appState.openMenu || appState.viewModeEnabled) {
|
|
15050
|
+
return null;
|
|
15613
15051
|
}
|
|
15614
|
-
|
|
15615
|
-
|
|
15616
|
-
|
|
15617
|
-
|
|
15618
|
-
|
|
15619
|
-
|
|
15620
|
-
|
|
15621
|
-
|
|
15622
|
-
|
|
15623
|
-
|
|
15624
|
-
|
|
15625
|
-
|
|
15626
|
-
|
|
15627
|
-
|
|
15628
|
-
|
|
15629
|
-
|
|
15630
|
-
|
|
15631
|
-
|
|
15632
|
-
|
|
15633
|
-
|
|
15634
|
-
|
|
15635
|
-
|
|
15636
|
-
|
|
15637
|
-
|
|
15638
|
-
|
|
15639
|
-
|
|
15640
|
-
|
|
15641
|
-
|
|
15642
|
-
|
|
15643
|
-
|
|
15644
|
-
|
|
15645
|
-
|
|
15646
|
-
|
|
15647
|
-
|
|
15648
|
-
|
|
15649
|
-
|
|
15650
|
-
|
|
15651
|
-
|
|
15652
|
-
|
|
15653
|
-
|
|
15654
|
-
|
|
15655
|
-
|
|
15656
|
-
|
|
15657
|
-
|
|
15658
|
-
|
|
15659
|
-
|
|
15660
|
-
|
|
15661
|
-
|
|
15662
|
-
|
|
15663
|
-
|
|
15664
|
-
|
|
15665
|
-
|
|
15666
|
-
|
|
15667
|
-
|
|
15668
|
-
|
|
15669
|
-
},
|
|
15670
|
-
{
|
|
15671
|
-
type: "gap",
|
|
15672
|
-
direction: "vertical",
|
|
15673
|
-
points: [
|
|
15674
|
-
pointFrom18(gapLineX, maxY),
|
|
15675
|
-
pointFrom18(gapLineX, gapSnap.gap.endSide[0][1])
|
|
15676
|
-
]
|
|
15677
|
-
}
|
|
15678
|
-
);
|
|
15679
|
-
}
|
|
15680
|
-
break;
|
|
15681
|
-
}
|
|
15682
|
-
case "side_right": {
|
|
15683
|
-
if (verticalIntersection) {
|
|
15684
|
-
const gapLineY = (verticalIntersection[0] + verticalIntersection[1]) / 2;
|
|
15685
|
-
gapSnapLines.push(
|
|
15686
|
-
{
|
|
15687
|
-
type: "gap",
|
|
15688
|
-
direction: "horizontal",
|
|
15689
|
-
points: [
|
|
15690
|
-
pointFrom18(startMaxX, gapLineY),
|
|
15691
|
-
pointFrom18(endMinX, gapLineY)
|
|
15692
|
-
]
|
|
15693
|
-
},
|
|
15694
|
-
{
|
|
15695
|
-
type: "gap",
|
|
15696
|
-
direction: "horizontal",
|
|
15697
|
-
points: [pointFrom18(endMaxX, gapLineY), pointFrom18(minX, gapLineY)]
|
|
15698
|
-
}
|
|
15699
|
-
);
|
|
15700
|
-
}
|
|
15701
|
-
break;
|
|
15702
|
-
}
|
|
15703
|
-
case "side_left": {
|
|
15704
|
-
if (verticalIntersection) {
|
|
15705
|
-
const gapLineY = (verticalIntersection[0] + verticalIntersection[1]) / 2;
|
|
15706
|
-
gapSnapLines.push(
|
|
15707
|
-
{
|
|
15708
|
-
type: "gap",
|
|
15709
|
-
direction: "horizontal",
|
|
15710
|
-
points: [
|
|
15711
|
-
pointFrom18(maxX, gapLineY),
|
|
15712
|
-
pointFrom18(startMinX, gapLineY)
|
|
15713
|
-
]
|
|
15714
|
-
},
|
|
15715
|
-
{
|
|
15716
|
-
type: "gap",
|
|
15717
|
-
direction: "horizontal",
|
|
15718
|
-
points: [
|
|
15719
|
-
pointFrom18(startMaxX, gapLineY),
|
|
15720
|
-
pointFrom18(endMinX, gapLineY)
|
|
15721
|
-
]
|
|
15722
|
-
}
|
|
15723
|
-
);
|
|
15724
|
-
}
|
|
15725
|
-
break;
|
|
15726
|
-
}
|
|
15727
|
-
case "side_top": {
|
|
15728
|
-
if (horizontalGapIntersection) {
|
|
15729
|
-
const gapLineX = (horizontalGapIntersection[0] + horizontalGapIntersection[1]) / 2;
|
|
15730
|
-
gapSnapLines.push(
|
|
15731
|
-
{
|
|
15732
|
-
type: "gap",
|
|
15733
|
-
direction: "vertical",
|
|
15734
|
-
points: [
|
|
15735
|
-
pointFrom18(gapLineX, maxY),
|
|
15736
|
-
pointFrom18(gapLineX, startMinY)
|
|
15737
|
-
]
|
|
15738
|
-
},
|
|
15739
|
-
{
|
|
15740
|
-
type: "gap",
|
|
15741
|
-
direction: "vertical",
|
|
15742
|
-
points: [
|
|
15743
|
-
pointFrom18(gapLineX, startMaxY),
|
|
15744
|
-
pointFrom18(gapLineX, endMinY)
|
|
15745
|
-
]
|
|
15746
|
-
}
|
|
15747
|
-
);
|
|
15748
|
-
}
|
|
15749
|
-
break;
|
|
15750
|
-
}
|
|
15751
|
-
case "side_bottom": {
|
|
15752
|
-
if (horizontalGapIntersection) {
|
|
15753
|
-
const gapLineX = (horizontalGapIntersection[0] + horizontalGapIntersection[1]) / 2;
|
|
15754
|
-
gapSnapLines.push(
|
|
15755
|
-
{
|
|
15756
|
-
type: "gap",
|
|
15757
|
-
direction: "vertical",
|
|
15758
|
-
points: [
|
|
15759
|
-
pointFrom18(gapLineX, startMaxY),
|
|
15760
|
-
pointFrom18(gapLineX, endMinY)
|
|
15761
|
-
]
|
|
15762
|
-
},
|
|
15763
|
-
{
|
|
15764
|
-
type: "gap",
|
|
15765
|
-
direction: "vertical",
|
|
15766
|
-
points: [pointFrom18(gapLineX, endMaxY), pointFrom18(gapLineX, minY)]
|
|
15767
|
-
}
|
|
15052
|
+
const { x, y } = getContainerCoords2(element, appState, elementsMap);
|
|
15053
|
+
return /* @__PURE__ */ jsx57(
|
|
15054
|
+
"div",
|
|
15055
|
+
{
|
|
15056
|
+
className: "excalidraw-canvas-buttons",
|
|
15057
|
+
style: {
|
|
15058
|
+
top: `${y}px`,
|
|
15059
|
+
left: `${x}px`,
|
|
15060
|
+
// width: CONTAINER_WIDTH,
|
|
15061
|
+
padding: CONTAINER_PADDING
|
|
15062
|
+
},
|
|
15063
|
+
children
|
|
15064
|
+
}
|
|
15065
|
+
);
|
|
15066
|
+
};
|
|
15067
|
+
|
|
15068
|
+
// laserTrails.ts
|
|
15069
|
+
import { DEFAULT_LASER_COLOR, easeOut } from "@excalidraw/common";
|
|
15070
|
+
|
|
15071
|
+
// animatedTrail.ts
|
|
15072
|
+
import { LaserPointer } from "@excalidraw/laser-pointer";
|
|
15073
|
+
import {
|
|
15074
|
+
SVG_NS,
|
|
15075
|
+
getSvgPathFromStroke as getSvgPathFromStroke2,
|
|
15076
|
+
sceneCoordsToViewportCoords as sceneCoordsToViewportCoords3
|
|
15077
|
+
} from "@excalidraw/common";
|
|
15078
|
+
|
|
15079
|
+
// reactUtils.ts
|
|
15080
|
+
import { version as ReactVersion } from "react";
|
|
15081
|
+
import { unstable_batchedUpdates } from "react-dom";
|
|
15082
|
+
import { throttleRAF } from "@excalidraw/common";
|
|
15083
|
+
var withBatchedUpdates = (func) => (event) => {
|
|
15084
|
+
unstable_batchedUpdates(func, event);
|
|
15085
|
+
};
|
|
15086
|
+
var withBatchedUpdatesThrottled = (func) => {
|
|
15087
|
+
return throttleRAF((event) => {
|
|
15088
|
+
unstable_batchedUpdates(func, event);
|
|
15089
|
+
});
|
|
15090
|
+
};
|
|
15091
|
+
var isRenderThrottlingEnabled = (() => {
|
|
15092
|
+
let IS_REACT_18_AND_UP;
|
|
15093
|
+
try {
|
|
15094
|
+
const version = ReactVersion.split(".");
|
|
15095
|
+
IS_REACT_18_AND_UP = Number(version[0]) > 17;
|
|
15096
|
+
} catch {
|
|
15097
|
+
IS_REACT_18_AND_UP = false;
|
|
15098
|
+
}
|
|
15099
|
+
let hasWarned = false;
|
|
15100
|
+
return () => {
|
|
15101
|
+
if (window.EXCALIDRAW_THROTTLE_RENDER === true) {
|
|
15102
|
+
if (!IS_REACT_18_AND_UP) {
|
|
15103
|
+
if (!hasWarned) {
|
|
15104
|
+
hasWarned = true;
|
|
15105
|
+
console.warn(
|
|
15106
|
+
"Excalidraw: render throttling is disabled on React versions < 18."
|
|
15768
15107
|
);
|
|
15769
15108
|
}
|
|
15770
|
-
|
|
15109
|
+
return false;
|
|
15771
15110
|
}
|
|
15111
|
+
return true;
|
|
15112
|
+
}
|
|
15113
|
+
return false;
|
|
15114
|
+
};
|
|
15115
|
+
})();
|
|
15116
|
+
|
|
15117
|
+
// renderer/animation.ts
|
|
15118
|
+
var _AnimationController = class _AnimationController {
|
|
15119
|
+
static start(key, animation) {
|
|
15120
|
+
if (_AnimationController.animations.has(key)) {
|
|
15121
|
+
return;
|
|
15122
|
+
}
|
|
15123
|
+
const initialState = animation({
|
|
15124
|
+
deltaTime: 0,
|
|
15125
|
+
state: void 0
|
|
15126
|
+
});
|
|
15127
|
+
if (initialState) {
|
|
15128
|
+
_AnimationController.animations.set(key, {
|
|
15129
|
+
animation,
|
|
15130
|
+
lastTime: 0,
|
|
15131
|
+
state: initialState
|
|
15132
|
+
});
|
|
15133
|
+
_AnimationController.scheduleNextFrame();
|
|
15772
15134
|
}
|
|
15773
15135
|
}
|
|
15774
|
-
|
|
15775
|
-
|
|
15776
|
-
return
|
|
15777
|
-
|
|
15778
|
-
|
|
15779
|
-
|
|
15780
|
-
)
|
|
15136
|
+
static scheduleNextFrame() {
|
|
15137
|
+
if (_AnimationController.scheduledFrame) {
|
|
15138
|
+
return;
|
|
15139
|
+
}
|
|
15140
|
+
if (isRenderThrottlingEnabled()) {
|
|
15141
|
+
_AnimationController.scheduledFrame = {
|
|
15142
|
+
id: requestAnimationFrame(_AnimationController.tick),
|
|
15143
|
+
type: "raf"
|
|
15781
15144
|
};
|
|
15782
|
-
}
|
|
15783
|
-
|
|
15784
|
-
|
|
15785
|
-
|
|
15786
|
-
|
|
15787
|
-
|
|
15788
|
-
snapOffset: { x: 0, y: 0 },
|
|
15789
|
-
snapLines: []
|
|
15790
|
-
};
|
|
15145
|
+
} else {
|
|
15146
|
+
_AnimationController.scheduledFrame = {
|
|
15147
|
+
id: setTimeout(_AnimationController.tick, 0),
|
|
15148
|
+
type: "timeout"
|
|
15149
|
+
};
|
|
15150
|
+
}
|
|
15791
15151
|
}
|
|
15792
|
-
|
|
15793
|
-
|
|
15794
|
-
|
|
15795
|
-
maxX += dragOffset.x;
|
|
15796
|
-
} else if (transformHandle.includes("w")) {
|
|
15797
|
-
minX += dragOffset.x;
|
|
15152
|
+
static cancelScheduledFrame() {
|
|
15153
|
+
if (!_AnimationController.scheduledFrame) {
|
|
15154
|
+
return;
|
|
15798
15155
|
}
|
|
15799
|
-
if (
|
|
15800
|
-
|
|
15801
|
-
} else
|
|
15802
|
-
|
|
15156
|
+
if (_AnimationController.scheduledFrame.type === "raf") {
|
|
15157
|
+
cancelAnimationFrame(_AnimationController.scheduledFrame.id);
|
|
15158
|
+
} else {
|
|
15159
|
+
clearTimeout(_AnimationController.scheduledFrame.id);
|
|
15803
15160
|
}
|
|
15161
|
+
_AnimationController.scheduledFrame = null;
|
|
15804
15162
|
}
|
|
15805
|
-
|
|
15806
|
-
|
|
15807
|
-
|
|
15808
|
-
|
|
15809
|
-
|
|
15810
|
-
|
|
15811
|
-
|
|
15812
|
-
|
|
15813
|
-
|
|
15814
|
-
|
|
15815
|
-
|
|
15816
|
-
|
|
15817
|
-
|
|
15818
|
-
|
|
15819
|
-
|
|
15820
|
-
|
|
15821
|
-
|
|
15822
|
-
|
|
15823
|
-
|
|
15824
|
-
|
|
15825
|
-
|
|
15826
|
-
|
|
15827
|
-
|
|
15828
|
-
|
|
15829
|
-
|
|
15830
|
-
|
|
15831
|
-
}
|
|
15832
|
-
case "se": {
|
|
15833
|
-
selectionSnapPoints.push(pointFrom18(maxX, maxY));
|
|
15834
|
-
break;
|
|
15163
|
+
static cancelScheduledFrameIfIdle() {
|
|
15164
|
+
if (_AnimationController.animations.size > 0) {
|
|
15165
|
+
return false;
|
|
15166
|
+
}
|
|
15167
|
+
_AnimationController.cancelScheduledFrame();
|
|
15168
|
+
return true;
|
|
15169
|
+
}
|
|
15170
|
+
static tick() {
|
|
15171
|
+
_AnimationController.scheduledFrame = null;
|
|
15172
|
+
if (_AnimationController.animations.size > 0) {
|
|
15173
|
+
for (const [key, animation] of _AnimationController.animations) {
|
|
15174
|
+
const now = performance.now();
|
|
15175
|
+
const deltaTime = animation.lastTime === 0 ? 0 : now - animation.lastTime;
|
|
15176
|
+
const state = animation.animation({
|
|
15177
|
+
deltaTime,
|
|
15178
|
+
state: animation.state
|
|
15179
|
+
});
|
|
15180
|
+
if (!state) {
|
|
15181
|
+
_AnimationController.animations.delete(key);
|
|
15182
|
+
if (_AnimationController.cancelScheduledFrameIfIdle()) {
|
|
15183
|
+
return;
|
|
15184
|
+
}
|
|
15185
|
+
} else {
|
|
15186
|
+
animation.lastTime = now;
|
|
15187
|
+
animation.state = state;
|
|
15188
|
+
}
|
|
15835
15189
|
}
|
|
15836
|
-
|
|
15837
|
-
|
|
15838
|
-
break;
|
|
15190
|
+
if (_AnimationController.cancelScheduledFrameIfIdle()) {
|
|
15191
|
+
return;
|
|
15839
15192
|
}
|
|
15193
|
+
_AnimationController.scheduleNextFrame();
|
|
15840
15194
|
}
|
|
15841
15195
|
}
|
|
15842
|
-
|
|
15843
|
-
|
|
15844
|
-
|
|
15845
|
-
|
|
15846
|
-
|
|
15847
|
-
|
|
15848
|
-
|
|
15849
|
-
getPointSnaps(
|
|
15850
|
-
selectedOriginalElements,
|
|
15851
|
-
selectionSnapPoints,
|
|
15852
|
-
app,
|
|
15853
|
-
event,
|
|
15854
|
-
nearestSnapsX,
|
|
15855
|
-
nearestSnapsY,
|
|
15856
|
-
minOffset
|
|
15857
|
-
);
|
|
15858
|
-
const snapOffset = {
|
|
15859
|
-
x: nearestSnapsX[0]?.offset ?? 0,
|
|
15860
|
-
y: nearestSnapsY[0]?.offset ?? 0
|
|
15861
|
-
};
|
|
15862
|
-
minOffset.x = 0;
|
|
15863
|
-
minOffset.y = 0;
|
|
15864
|
-
nearestSnapsX.length = 0;
|
|
15865
|
-
nearestSnapsY.length = 0;
|
|
15866
|
-
const [x1, y1, x2, y2] = getCommonBounds4(selectedElements).map(
|
|
15867
|
-
(bound) => round(bound)
|
|
15868
|
-
);
|
|
15869
|
-
const corners = [
|
|
15870
|
-
pointFrom18(x1, y1),
|
|
15871
|
-
pointFrom18(x1, y2),
|
|
15872
|
-
pointFrom18(x2, y1),
|
|
15873
|
-
pointFrom18(x2, y2)
|
|
15874
|
-
];
|
|
15875
|
-
getPointSnaps(
|
|
15876
|
-
selectedElements,
|
|
15877
|
-
corners,
|
|
15878
|
-
app,
|
|
15879
|
-
event,
|
|
15880
|
-
nearestSnapsX,
|
|
15881
|
-
nearestSnapsY,
|
|
15882
|
-
minOffset
|
|
15883
|
-
);
|
|
15884
|
-
const pointSnapLines = createPointSnapLines(nearestSnapsX, nearestSnapsY);
|
|
15885
|
-
return {
|
|
15886
|
-
snapOffset,
|
|
15887
|
-
snapLines: pointSnapLines
|
|
15888
|
-
};
|
|
15196
|
+
static running(key) {
|
|
15197
|
+
return _AnimationController.animations.has(key);
|
|
15198
|
+
}
|
|
15199
|
+
static cancel(key) {
|
|
15200
|
+
_AnimationController.animations.delete(key);
|
|
15201
|
+
_AnimationController.cancelScheduledFrameIfIdle();
|
|
15202
|
+
}
|
|
15889
15203
|
};
|
|
15890
|
-
|
|
15891
|
-
|
|
15892
|
-
|
|
15893
|
-
|
|
15894
|
-
|
|
15895
|
-
|
|
15204
|
+
__publicField(_AnimationController, "scheduledFrame", null);
|
|
15205
|
+
__publicField(_AnimationController, "animations", /* @__PURE__ */ new Map());
|
|
15206
|
+
var AnimationController = _AnimationController;
|
|
15207
|
+
|
|
15208
|
+
// animatedTrail.ts
|
|
15209
|
+
var _AnimatedTrail = class _AnimatedTrail {
|
|
15210
|
+
constructor(app, options) {
|
|
15211
|
+
this.app = app;
|
|
15212
|
+
this.options = options;
|
|
15213
|
+
__publicField(this, "currentTrail");
|
|
15214
|
+
__publicField(this, "pastTrails", []);
|
|
15215
|
+
__publicField(this, "container");
|
|
15216
|
+
__publicField(this, "trailElement");
|
|
15217
|
+
__publicField(this, "trailAnimation");
|
|
15218
|
+
__publicField(this, "key");
|
|
15219
|
+
this.key = `animated-trail-${_AnimatedTrail.counter++}`;
|
|
15220
|
+
this.trailElement = document.createElementNS(SVG_NS, "path");
|
|
15221
|
+
if (this.options.animateTrail) {
|
|
15222
|
+
this.trailAnimation = document.createElementNS(SVG_NS, "animate");
|
|
15223
|
+
this.trailAnimation.setAttribute("attributeName", "stroke-dashoffset");
|
|
15224
|
+
this.trailElement.setAttribute("stroke-dasharray", "7 7");
|
|
15225
|
+
this.trailElement.setAttribute("stroke-dashoffset", "10");
|
|
15226
|
+
this.trailAnimation.setAttribute("from", "0");
|
|
15227
|
+
this.trailAnimation.setAttribute("to", `-14`);
|
|
15228
|
+
this.trailAnimation.setAttribute("dur", "0.3s");
|
|
15229
|
+
this.trailElement.appendChild(this.trailAnimation);
|
|
15230
|
+
}
|
|
15231
|
+
}
|
|
15232
|
+
get hasCurrentTrail() {
|
|
15233
|
+
return !!this.currentTrail;
|
|
15234
|
+
}
|
|
15235
|
+
hasLastPoint(x, y) {
|
|
15236
|
+
if (this.currentTrail) {
|
|
15237
|
+
const len = this.currentTrail.originalPoints.length;
|
|
15238
|
+
return this.currentTrail.originalPoints[len - 1][0] === x && this.currentTrail.originalPoints[len - 1][1] === y;
|
|
15239
|
+
}
|
|
15240
|
+
return false;
|
|
15241
|
+
}
|
|
15242
|
+
cleanup() {
|
|
15243
|
+
this.pastTrails = [];
|
|
15244
|
+
this.currentTrail = void 0;
|
|
15245
|
+
if (this.trailElement.parentNode === this.container) {
|
|
15246
|
+
this.container?.removeChild(this.trailElement);
|
|
15247
|
+
}
|
|
15248
|
+
}
|
|
15249
|
+
start(container) {
|
|
15250
|
+
if (container) {
|
|
15251
|
+
this.container = container;
|
|
15252
|
+
}
|
|
15253
|
+
if (this.trailElement.parentNode !== this.container && this.container) {
|
|
15254
|
+
this.container.appendChild(this.trailElement);
|
|
15255
|
+
}
|
|
15256
|
+
if (!AnimationController.running(this.key)) {
|
|
15257
|
+
AnimationController.start(this.key, () => {
|
|
15258
|
+
const needsNext = this.onFrame();
|
|
15259
|
+
if (needsNext) {
|
|
15260
|
+
return { keep: true };
|
|
15261
|
+
}
|
|
15262
|
+
this.cleanup();
|
|
15263
|
+
return null;
|
|
15264
|
+
});
|
|
15265
|
+
}
|
|
15266
|
+
}
|
|
15267
|
+
stop() {
|
|
15268
|
+
AnimationController.cancel(this.key);
|
|
15269
|
+
this.cleanup();
|
|
15270
|
+
}
|
|
15271
|
+
startPath(x, y) {
|
|
15272
|
+
this.currentTrail = new LaserPointer(this.options);
|
|
15273
|
+
this.currentTrail.addPoint([x, y, performance.now()]);
|
|
15274
|
+
this.update();
|
|
15275
|
+
}
|
|
15276
|
+
addPointToPath(x, y) {
|
|
15277
|
+
if (this.currentTrail) {
|
|
15278
|
+
this.currentTrail.addPoint([x, y, performance.now()]);
|
|
15279
|
+
this.update();
|
|
15280
|
+
}
|
|
15281
|
+
}
|
|
15282
|
+
endPath() {
|
|
15283
|
+
if (this.currentTrail) {
|
|
15284
|
+
this.currentTrail.close();
|
|
15285
|
+
this.currentTrail.options.keepHead = false;
|
|
15286
|
+
this.pastTrails.push(this.currentTrail);
|
|
15287
|
+
this.currentTrail = void 0;
|
|
15288
|
+
this.update();
|
|
15289
|
+
}
|
|
15290
|
+
}
|
|
15291
|
+
getCurrentTrail() {
|
|
15292
|
+
return this.currentTrail;
|
|
15293
|
+
}
|
|
15294
|
+
clearTrails() {
|
|
15295
|
+
this.pastTrails = [];
|
|
15296
|
+
this.currentTrail = void 0;
|
|
15297
|
+
this.update();
|
|
15298
|
+
}
|
|
15299
|
+
update() {
|
|
15300
|
+
this.start();
|
|
15301
|
+
if (this.trailAnimation) {
|
|
15302
|
+
this.trailAnimation.setAttribute("begin", "indefinite");
|
|
15303
|
+
this.trailAnimation.setAttribute("repeatCount", "indefinite");
|
|
15304
|
+
}
|
|
15305
|
+
}
|
|
15306
|
+
onFrame() {
|
|
15307
|
+
const paths = [];
|
|
15308
|
+
for (const trail of this.pastTrails) {
|
|
15309
|
+
paths.push(this.drawTrail(trail, this.app.state));
|
|
15310
|
+
}
|
|
15311
|
+
if (this.currentTrail) {
|
|
15312
|
+
const currentPath = this.drawTrail(this.currentTrail, this.app.state);
|
|
15313
|
+
paths.push(currentPath);
|
|
15314
|
+
}
|
|
15315
|
+
this.pastTrails = this.pastTrails.filter(
|
|
15316
|
+
(t2) => t2.getStrokeOutline(t2.options.size / this.app.state.zoom.value).length !== 0
|
|
15317
|
+
);
|
|
15318
|
+
if (paths.length === 0) {
|
|
15319
|
+
this.trailElement.setAttribute("d", "");
|
|
15320
|
+
return false;
|
|
15321
|
+
}
|
|
15322
|
+
const svgPaths = paths.join(" ").trim();
|
|
15323
|
+
this.trailElement.setAttribute("d", svgPaths);
|
|
15324
|
+
if (this.trailAnimation) {
|
|
15325
|
+
this.trailElement.setAttribute(
|
|
15326
|
+
"fill",
|
|
15327
|
+
(this.options.fill ?? (() => "black"))(this)
|
|
15328
|
+
);
|
|
15329
|
+
this.trailElement.setAttribute(
|
|
15330
|
+
"stroke",
|
|
15331
|
+
(this.options.stroke ?? (() => "black"))(this)
|
|
15332
|
+
);
|
|
15333
|
+
} else {
|
|
15334
|
+
this.trailElement.setAttribute(
|
|
15335
|
+
"fill",
|
|
15336
|
+
(this.options.fill ?? (() => "black"))(this)
|
|
15337
|
+
);
|
|
15338
|
+
}
|
|
15339
|
+
return true;
|
|
15340
|
+
}
|
|
15341
|
+
drawTrail(trail, state) {
|
|
15342
|
+
const _stroke = trail.getStrokeOutline(trail.options.size / state.zoom.value).map(([x, y]) => {
|
|
15343
|
+
const result = sceneCoordsToViewportCoords3(
|
|
15344
|
+
{ sceneX: x, sceneY: y },
|
|
15345
|
+
state
|
|
15346
|
+
);
|
|
15347
|
+
return [result.x, result.y];
|
|
15348
|
+
});
|
|
15349
|
+
const stroke = this.trailAnimation ? _stroke.slice(0, _stroke.length / 2) : _stroke;
|
|
15350
|
+
return getSvgPathFromStroke2(stroke, true);
|
|
15896
15351
|
}
|
|
15897
|
-
const selectionSnapPoints = [
|
|
15898
|
-
pointFrom18(origin.x + dragOffset.x, origin.y + dragOffset.y)
|
|
15899
|
-
];
|
|
15900
|
-
const snapDistance = getSnapDistance(app.state.zoom.value);
|
|
15901
|
-
const minOffset = {
|
|
15902
|
-
x: snapDistance,
|
|
15903
|
-
y: snapDistance
|
|
15904
|
-
};
|
|
15905
|
-
const nearestSnapsX = [];
|
|
15906
|
-
const nearestSnapsY = [];
|
|
15907
|
-
getPointSnaps(
|
|
15908
|
-
[newElement7],
|
|
15909
|
-
selectionSnapPoints,
|
|
15910
|
-
app,
|
|
15911
|
-
event,
|
|
15912
|
-
nearestSnapsX,
|
|
15913
|
-
nearestSnapsY,
|
|
15914
|
-
minOffset
|
|
15915
|
-
);
|
|
15916
|
-
const snapOffset = {
|
|
15917
|
-
x: nearestSnapsX[0]?.offset ?? 0,
|
|
15918
|
-
y: nearestSnapsY[0]?.offset ?? 0
|
|
15919
|
-
};
|
|
15920
|
-
minOffset.x = 0;
|
|
15921
|
-
minOffset.y = 0;
|
|
15922
|
-
nearestSnapsX.length = 0;
|
|
15923
|
-
nearestSnapsY.length = 0;
|
|
15924
|
-
const corners = getElementsCorners([newElement7], elementsMap, {
|
|
15925
|
-
boundingBoxCorners: true,
|
|
15926
|
-
omitCenter: true
|
|
15927
|
-
});
|
|
15928
|
-
getPointSnaps(
|
|
15929
|
-
[newElement7],
|
|
15930
|
-
corners,
|
|
15931
|
-
app,
|
|
15932
|
-
event,
|
|
15933
|
-
nearestSnapsX,
|
|
15934
|
-
nearestSnapsY,
|
|
15935
|
-
minOffset
|
|
15936
|
-
);
|
|
15937
|
-
const pointSnapLines = createPointSnapLines(nearestSnapsX, nearestSnapsY);
|
|
15938
|
-
return {
|
|
15939
|
-
snapOffset,
|
|
15940
|
-
snapLines: pointSnapLines
|
|
15941
|
-
};
|
|
15942
15352
|
};
|
|
15943
|
-
|
|
15944
|
-
|
|
15353
|
+
__publicField(_AnimatedTrail, "counter", 0);
|
|
15354
|
+
var AnimatedTrail = _AnimatedTrail;
|
|
15355
|
+
|
|
15356
|
+
// laserTrails.ts
|
|
15357
|
+
var LaserTrails = class {
|
|
15358
|
+
constructor(app) {
|
|
15359
|
+
this.app = app;
|
|
15360
|
+
__publicField(this, "localTrail");
|
|
15361
|
+
__publicField(this, "collabTrails", /* @__PURE__ */ new Map());
|
|
15362
|
+
__publicField(this, "container");
|
|
15363
|
+
this.localTrail = new AnimatedTrail(app, {
|
|
15364
|
+
...this.getTrailOptions(),
|
|
15365
|
+
fill: () => DEFAULT_LASER_COLOR
|
|
15366
|
+
});
|
|
15367
|
+
}
|
|
15368
|
+
getTrailOptions() {
|
|
15945
15369
|
return {
|
|
15946
|
-
|
|
15947
|
-
|
|
15370
|
+
simplify: 0,
|
|
15371
|
+
streamline: 0.4,
|
|
15372
|
+
sizeMapping: (c) => {
|
|
15373
|
+
const DECAY_TIME = 1e3;
|
|
15374
|
+
const DECAY_LENGTH = 50;
|
|
15375
|
+
const t2 = Math.max(
|
|
15376
|
+
0,
|
|
15377
|
+
1 - (performance.now() - c.pressure) / DECAY_TIME
|
|
15378
|
+
);
|
|
15379
|
+
const l = (DECAY_LENGTH - Math.min(DECAY_LENGTH, c.totalLength - c.currentIndex)) / DECAY_LENGTH;
|
|
15380
|
+
return Math.min(easeOut(l), easeOut(t2));
|
|
15381
|
+
}
|
|
15948
15382
|
};
|
|
15949
15383
|
}
|
|
15950
|
-
|
|
15951
|
-
|
|
15952
|
-
|
|
15953
|
-
|
|
15954
|
-
|
|
15955
|
-
|
|
15956
|
-
|
|
15957
|
-
|
|
15958
|
-
|
|
15959
|
-
|
|
15960
|
-
|
|
15961
|
-
|
|
15962
|
-
|
|
15963
|
-
|
|
15964
|
-
|
|
15965
|
-
|
|
15966
|
-
|
|
15967
|
-
|
|
15968
|
-
|
|
15969
|
-
|
|
15970
|
-
|
|
15971
|
-
|
|
15972
|
-
|
|
15973
|
-
|
|
15974
|
-
|
|
15384
|
+
startPath(x, y) {
|
|
15385
|
+
this.localTrail.startPath(x, y);
|
|
15386
|
+
}
|
|
15387
|
+
addPointToPath(x, y) {
|
|
15388
|
+
this.localTrail.addPointToPath(x, y);
|
|
15389
|
+
}
|
|
15390
|
+
endPath() {
|
|
15391
|
+
this.localTrail.endPath();
|
|
15392
|
+
}
|
|
15393
|
+
start(container) {
|
|
15394
|
+
this.container = container;
|
|
15395
|
+
this.localTrail.start(container);
|
|
15396
|
+
}
|
|
15397
|
+
stop() {
|
|
15398
|
+
this.localTrail.stop();
|
|
15399
|
+
this.stopCollabTrails();
|
|
15400
|
+
this.container = void 0;
|
|
15401
|
+
}
|
|
15402
|
+
stopCollabTrails(collaborators) {
|
|
15403
|
+
for (const [key, trail] of this.collabTrails) {
|
|
15404
|
+
const collaborator = collaborators?.get(key);
|
|
15405
|
+
if (!collaborator) {
|
|
15406
|
+
trail.stop();
|
|
15407
|
+
this.collabTrails.delete(key);
|
|
15408
|
+
}
|
|
15409
|
+
}
|
|
15410
|
+
}
|
|
15411
|
+
updateCollabTrails(collaborators) {
|
|
15412
|
+
this.stopCollabTrails(collaborators);
|
|
15413
|
+
if (!this.container || collaborators.size === 0) {
|
|
15414
|
+
return;
|
|
15415
|
+
}
|
|
15416
|
+
for (const [key, collaborator] of collaborators.entries()) {
|
|
15417
|
+
if (collaborator.isCurrentUser) {
|
|
15418
|
+
continue;
|
|
15419
|
+
}
|
|
15420
|
+
let trail = this.collabTrails.get(key);
|
|
15421
|
+
if (!trail) {
|
|
15422
|
+
trail = new AnimatedTrail(this.app, {
|
|
15423
|
+
...this.getTrailOptions(),
|
|
15424
|
+
fill: () => collaborator.pointer?.laserColor || getClientColor(key, collaborator)
|
|
15975
15425
|
});
|
|
15976
|
-
|
|
15426
|
+
trail.start(this.container);
|
|
15427
|
+
this.collabTrails.set(key, trail);
|
|
15977
15428
|
}
|
|
15978
|
-
|
|
15979
|
-
|
|
15980
|
-
|
|
15981
|
-
|
|
15429
|
+
if (collaborator.pointer && collaborator.pointer.tool === "laser") {
|
|
15430
|
+
const buttonDown = collaborator.button === "down";
|
|
15431
|
+
const buttonUp = collaborator.button === "up";
|
|
15432
|
+
const hasTrail = trail.hasCurrentTrail;
|
|
15433
|
+
if (buttonDown && !hasTrail) {
|
|
15434
|
+
trail.startPath(collaborator.pointer.x, collaborator.pointer.y);
|
|
15435
|
+
}
|
|
15436
|
+
const lastPointOriginal = !trail.hasLastPoint(
|
|
15437
|
+
collaborator.pointer.x,
|
|
15438
|
+
collaborator.pointer.y
|
|
15439
|
+
);
|
|
15440
|
+
if (buttonDown && lastPointOriginal) {
|
|
15441
|
+
trail.addPointToPath(collaborator.pointer.x, collaborator.pointer.y);
|
|
15442
|
+
}
|
|
15443
|
+
if (buttonUp && hasTrail) {
|
|
15444
|
+
trail.addPointToPath(collaborator.pointer.x, collaborator.pointer.y);
|
|
15445
|
+
trail.endPath();
|
|
15982
15446
|
}
|
|
15983
|
-
horizontalSnapLines.push({
|
|
15984
|
-
type: "pointer",
|
|
15985
|
-
points: [corner, pointFrom18(pointer.x, corner[1])],
|
|
15986
|
-
direction: "horizontal"
|
|
15987
|
-
});
|
|
15988
|
-
minOffset.y = offsetY;
|
|
15989
15447
|
}
|
|
15990
15448
|
}
|
|
15991
15449
|
}
|
|
15992
|
-
return {
|
|
15993
|
-
originOffset: {
|
|
15994
|
-
x: verticalSnapLines.length > 0 ? verticalSnapLines[0].points[0][0] - pointer.x : 0,
|
|
15995
|
-
y: horizontalSnapLines.length > 0 ? horizontalSnapLines[0].points[0][1] - pointer.y : 0
|
|
15996
|
-
},
|
|
15997
|
-
snapLines: [...verticalSnapLines, ...horizontalSnapLines]
|
|
15998
|
-
};
|
|
15999
|
-
};
|
|
16000
|
-
var isActiveToolNonLinearSnappable = (activeToolType) => {
|
|
16001
|
-
return activeToolType === TOOL_TYPE.rectangle || activeToolType === TOOL_TYPE.ellipse || activeToolType === TOOL_TYPE.diamond || activeToolType === TOOL_TYPE.frame || activeToolType === TOOL_TYPE.magicframe || activeToolType === TOOL_TYPE.image || activeToolType === TOOL_TYPE.text;
|
|
16002
15450
|
};
|
|
16003
15451
|
|
|
16004
15452
|
// scene/Renderer.ts
|
|
@@ -16107,481 +15555,1102 @@ var Renderer = class {
|
|
|
16107
15555
|
)) {
|
|
16108
15556
|
visibleElements.push(element);
|
|
16109
15557
|
}
|
|
16110
|
-
}
|
|
16111
|
-
return visibleElements;
|
|
16112
|
-
}
|
|
16113
|
-
getRenderableElementsMap({
|
|
16114
|
-
elements,
|
|
16115
|
-
editingTextElement,
|
|
16116
|
-
newElement: newElement7
|
|
16117
|
-
}) {
|
|
16118
|
-
const elementsMap = toBrandedType(/* @__PURE__ */ new Map());
|
|
16119
|
-
const newElementCanvasElement = newElement7?.frameId ? null : newElement7;
|
|
16120
|
-
for (const element of elements) {
|
|
16121
|
-
if (newElementCanvasElement?.id === element.id) {
|
|
15558
|
+
}
|
|
15559
|
+
return visibleElements;
|
|
15560
|
+
}
|
|
15561
|
+
getRenderableElementsMap({
|
|
15562
|
+
elements,
|
|
15563
|
+
editingTextElement,
|
|
15564
|
+
newElement: newElement7
|
|
15565
|
+
}) {
|
|
15566
|
+
const elementsMap = toBrandedType(/* @__PURE__ */ new Map());
|
|
15567
|
+
const newElementCanvasElement = newElement7?.frameId ? null : newElement7;
|
|
15568
|
+
for (const element of elements) {
|
|
15569
|
+
if (newElementCanvasElement?.id === element.id) {
|
|
15570
|
+
continue;
|
|
15571
|
+
}
|
|
15572
|
+
if (!editingTextElement || editingTextElement.type !== "text" || element.id !== editingTextElement.id) {
|
|
15573
|
+
elementsMap.set(element.id, element);
|
|
15574
|
+
}
|
|
15575
|
+
}
|
|
15576
|
+
return { elementsMap, newElementCanvasElement };
|
|
15577
|
+
}
|
|
15578
|
+
sortSelectedElementsIntoHighlightedFrame({
|
|
15579
|
+
visibleElements,
|
|
15580
|
+
selectedElements,
|
|
15581
|
+
frameToHighlight
|
|
15582
|
+
}) {
|
|
15583
|
+
if (!selectedElements.length) {
|
|
15584
|
+
return visibleElements;
|
|
15585
|
+
}
|
|
15586
|
+
const selectedElementsMap = arrayToMap24(selectedElements);
|
|
15587
|
+
const deselectedElements = visibleElements.filter(
|
|
15588
|
+
(element) => !selectedElementsMap.has(element.id)
|
|
15589
|
+
);
|
|
15590
|
+
const insertionIndex = getFrameChildrenInsertionIndex(
|
|
15591
|
+
deselectedElements,
|
|
15592
|
+
frameToHighlight.id
|
|
15593
|
+
);
|
|
15594
|
+
if (insertionIndex === null) {
|
|
15595
|
+
return visibleElements;
|
|
15596
|
+
}
|
|
15597
|
+
return [
|
|
15598
|
+
...deselectedElements.slice(0, insertionIndex),
|
|
15599
|
+
...selectedElements,
|
|
15600
|
+
...deselectedElements.slice(insertionIndex)
|
|
15601
|
+
];
|
|
15602
|
+
}
|
|
15603
|
+
// NOTE Doesn't destroy everything (scene, rc, etc.) because it may not be
|
|
15604
|
+
// safe to break TS contract here (for upstream cases)
|
|
15605
|
+
destroy() {
|
|
15606
|
+
renderStaticSceneThrottled.cancel();
|
|
15607
|
+
this._getRenderableElements.clear();
|
|
15608
|
+
}
|
|
15609
|
+
};
|
|
15610
|
+
|
|
15611
|
+
// scene/scrollbars.ts
|
|
15612
|
+
import { getGlobalCSSVariable } from "@excalidraw/common";
|
|
15613
|
+
import { getCommonBounds as getCommonBounds4 } from "@excalidraw/element";
|
|
15614
|
+
var SCROLLBAR_MARGIN = 4;
|
|
15615
|
+
var SCROLLBAR_WIDTH = 6;
|
|
15616
|
+
var SCROLLBAR_COLOR = "rgba(0,0,0,0.3)";
|
|
15617
|
+
var getScrollBars = (elements, viewportWidth, viewportHeight, appState) => {
|
|
15618
|
+
if (!elements.size) {
|
|
15619
|
+
return {
|
|
15620
|
+
horizontal: null,
|
|
15621
|
+
vertical: null
|
|
15622
|
+
};
|
|
15623
|
+
}
|
|
15624
|
+
const [elementsMinX, elementsMinY, elementsMaxX, elementsMaxY] = getCommonBounds4(elements);
|
|
15625
|
+
const viewportWidthWithZoom = viewportWidth / appState.zoom.value;
|
|
15626
|
+
const viewportHeightWithZoom = viewportHeight / appState.zoom.value;
|
|
15627
|
+
const safeArea = {
|
|
15628
|
+
top: parseInt(getGlobalCSSVariable("sat")) || 0,
|
|
15629
|
+
bottom: parseInt(getGlobalCSSVariable("sab")) || 0,
|
|
15630
|
+
left: parseInt(getGlobalCSSVariable("sal")) || 0,
|
|
15631
|
+
right: parseInt(getGlobalCSSVariable("sar")) || 0
|
|
15632
|
+
};
|
|
15633
|
+
const isRTL3 = getLanguage().rtl;
|
|
15634
|
+
const viewportMinX = -appState.scrollX + safeArea.left;
|
|
15635
|
+
const viewportMinY = -appState.scrollY + safeArea.top;
|
|
15636
|
+
const viewportMaxX = viewportMinX + viewportWidthWithZoom - safeArea.right;
|
|
15637
|
+
const viewportMaxY = viewportMinY + viewportHeightWithZoom - safeArea.bottom;
|
|
15638
|
+
const sceneMinX = Math.min(elementsMinX, viewportMinX);
|
|
15639
|
+
const sceneMinY = Math.min(elementsMinY, viewportMinY);
|
|
15640
|
+
const sceneMaxX = Math.max(elementsMaxX, viewportMaxX);
|
|
15641
|
+
const sceneMaxY = Math.max(elementsMaxY, viewportMaxY);
|
|
15642
|
+
const sceneWidth = elementsMaxX - elementsMinX;
|
|
15643
|
+
const sceneHeight = elementsMaxY - elementsMinY;
|
|
15644
|
+
const extendedSceneWidth = sceneMaxX - sceneMinX;
|
|
15645
|
+
const extendedSceneHeight = sceneMaxY - sceneMinY;
|
|
15646
|
+
const scrollWidthOffset = Math.max(SCROLLBAR_MARGIN * 2, safeArea.left + safeArea.right) + SCROLLBAR_WIDTH * 2;
|
|
15647
|
+
const scrollbarWidth = viewportWidth * (viewportWidthWithZoom / extendedSceneWidth) - scrollWidthOffset;
|
|
15648
|
+
const scrollbarHeightOffset = Math.max(SCROLLBAR_MARGIN * 2, safeArea.top + safeArea.bottom) + SCROLLBAR_WIDTH * 2;
|
|
15649
|
+
const scrollbarHeight = viewportHeight * (viewportHeightWithZoom / extendedSceneHeight) - scrollbarHeightOffset;
|
|
15650
|
+
const horizontalDeltaMultiplier = extendedSceneWidth > sceneWidth ? extendedSceneWidth * appState.zoom.value / (scrollbarWidth + scrollWidthOffset) : viewportWidth / (scrollbarWidth + scrollWidthOffset);
|
|
15651
|
+
const verticalDeltaMultiplier = extendedSceneHeight > sceneHeight ? extendedSceneHeight * appState.zoom.value / (scrollbarHeight + scrollbarHeightOffset) : viewportHeight / (scrollbarHeight + scrollbarHeightOffset);
|
|
15652
|
+
return {
|
|
15653
|
+
horizontal: viewportMinX === sceneMinX && viewportMaxX === sceneMaxX ? null : {
|
|
15654
|
+
x: Math.max(safeArea.left, SCROLLBAR_MARGIN) + SCROLLBAR_WIDTH + (viewportMinX - sceneMinX) / extendedSceneWidth * viewportWidth,
|
|
15655
|
+
y: viewportHeight - SCROLLBAR_WIDTH - Math.max(SCROLLBAR_MARGIN, safeArea.bottom),
|
|
15656
|
+
width: scrollbarWidth,
|
|
15657
|
+
height: SCROLLBAR_WIDTH,
|
|
15658
|
+
deltaMultiplier: horizontalDeltaMultiplier
|
|
15659
|
+
},
|
|
15660
|
+
vertical: viewportMinY === sceneMinY && viewportMaxY === sceneMaxY ? null : {
|
|
15661
|
+
x: isRTL3 ? Math.max(safeArea.left, SCROLLBAR_MARGIN) : viewportWidth - SCROLLBAR_WIDTH - Math.max(safeArea.right, SCROLLBAR_MARGIN),
|
|
15662
|
+
y: Math.max(safeArea.top, SCROLLBAR_MARGIN) + SCROLLBAR_WIDTH + (viewportMinY - sceneMinY) / extendedSceneHeight * viewportHeight,
|
|
15663
|
+
width: SCROLLBAR_WIDTH,
|
|
15664
|
+
height: scrollbarHeight,
|
|
15665
|
+
deltaMultiplier: verticalDeltaMultiplier
|
|
15666
|
+
}
|
|
15667
|
+
};
|
|
15668
|
+
};
|
|
15669
|
+
var isOverScrollBars = (scrollBars, x, y) => {
|
|
15670
|
+
const [isOverHorizontal, isOverVertical] = [
|
|
15671
|
+
scrollBars.horizontal,
|
|
15672
|
+
scrollBars.vertical
|
|
15673
|
+
].map((scrollBar) => {
|
|
15674
|
+
return scrollBar != null && scrollBar.x <= x && x <= scrollBar.x + scrollBar.width && scrollBar.y <= y && y <= scrollBar.y + scrollBar.height;
|
|
15675
|
+
});
|
|
15676
|
+
const isOverEither = isOverHorizontal || isOverVertical;
|
|
15677
|
+
return { isOverEither, isOverHorizontal, isOverVertical };
|
|
15678
|
+
};
|
|
15679
|
+
|
|
15680
|
+
// snapping.ts
|
|
15681
|
+
import {
|
|
15682
|
+
pointFrom as pointFrom18,
|
|
15683
|
+
pointRotateRads as pointRotateRads14,
|
|
15684
|
+
rangeInclusive,
|
|
15685
|
+
rangeIntersection,
|
|
15686
|
+
rangesOverlap
|
|
15687
|
+
} from "@excalidraw/math";
|
|
15688
|
+
import { TOOL_TYPE, KEYS as KEYS34 } from "@excalidraw/common";
|
|
15689
|
+
import {
|
|
15690
|
+
getCommonBounds as getCommonBounds5,
|
|
15691
|
+
getDraggedElementsBounds,
|
|
15692
|
+
getElementAbsoluteCoords as getElementAbsoluteCoords5
|
|
15693
|
+
} from "@excalidraw/element";
|
|
15694
|
+
import { isBoundToContainer as isBoundToContainer6 } from "@excalidraw/element";
|
|
15695
|
+
import { getMaximumGroups } from "@excalidraw/element";
|
|
15696
|
+
import {
|
|
15697
|
+
getSelectedElements as getSelectedElements4,
|
|
15698
|
+
getVisibleAndNonSelectedElements
|
|
15699
|
+
} from "@excalidraw/element";
|
|
15700
|
+
var SNAP_DISTANCE = 8;
|
|
15701
|
+
var VISIBLE_GAPS_LIMIT_PER_AXIS = 99999;
|
|
15702
|
+
var getSnapDistance = (zoomValue) => {
|
|
15703
|
+
return SNAP_DISTANCE / zoomValue;
|
|
15704
|
+
};
|
|
15705
|
+
var _SnapCache = class _SnapCache {
|
|
15706
|
+
};
|
|
15707
|
+
__publicField(_SnapCache, "referenceSnapPoints", null);
|
|
15708
|
+
__publicField(_SnapCache, "visibleGaps", null);
|
|
15709
|
+
__publicField(_SnapCache, "setReferenceSnapPoints", (snapPoints) => {
|
|
15710
|
+
_SnapCache.referenceSnapPoints = snapPoints;
|
|
15711
|
+
});
|
|
15712
|
+
__publicField(_SnapCache, "getReferenceSnapPoints", () => {
|
|
15713
|
+
return _SnapCache.referenceSnapPoints;
|
|
15714
|
+
});
|
|
15715
|
+
__publicField(_SnapCache, "setVisibleGaps", (gaps) => {
|
|
15716
|
+
_SnapCache.visibleGaps = gaps;
|
|
15717
|
+
});
|
|
15718
|
+
__publicField(_SnapCache, "getVisibleGaps", () => {
|
|
15719
|
+
return _SnapCache.visibleGaps;
|
|
15720
|
+
});
|
|
15721
|
+
__publicField(_SnapCache, "destroy", () => {
|
|
15722
|
+
_SnapCache.referenceSnapPoints = null;
|
|
15723
|
+
_SnapCache.visibleGaps = null;
|
|
15724
|
+
});
|
|
15725
|
+
var SnapCache = _SnapCache;
|
|
15726
|
+
var isGridModeEnabled = (app) => app.props.gridModeEnabled ?? app.state.gridModeEnabled;
|
|
15727
|
+
var isSnappingEnabled = ({
|
|
15728
|
+
event,
|
|
15729
|
+
app,
|
|
15730
|
+
selectedElements
|
|
15731
|
+
}) => {
|
|
15732
|
+
if (event) {
|
|
15733
|
+
const isLassoDragging = app.state.activeTool.type === "lasso" && app.state.selectedElementsAreBeingDragged;
|
|
15734
|
+
return (app.state.activeTool.type !== "lasso" || isLassoDragging) && (app.state.objectsSnapModeEnabled && !event[KEYS34.CTRL_OR_CMD] || !app.state.objectsSnapModeEnabled && event[KEYS34.CTRL_OR_CMD] && !isGridModeEnabled(app));
|
|
15735
|
+
}
|
|
15736
|
+
if (selectedElements.length === 1 && selectedElements[0].type === "arrow") {
|
|
15737
|
+
return false;
|
|
15738
|
+
}
|
|
15739
|
+
return app.state.objectsSnapModeEnabled;
|
|
15740
|
+
};
|
|
15741
|
+
var areRoughlyEqual = (a, b, precision = 0.01) => {
|
|
15742
|
+
return Math.abs(a - b) <= precision;
|
|
15743
|
+
};
|
|
15744
|
+
var getElementsCorners = (elements, elementsMap, {
|
|
15745
|
+
omitCenter,
|
|
15746
|
+
boundingBoxCorners,
|
|
15747
|
+
dragOffset
|
|
15748
|
+
} = {
|
|
15749
|
+
omitCenter: false,
|
|
15750
|
+
boundingBoxCorners: false
|
|
15751
|
+
}) => {
|
|
15752
|
+
let result = [];
|
|
15753
|
+
if (elements.length === 1) {
|
|
15754
|
+
const element = elements[0];
|
|
15755
|
+
let [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords5(
|
|
15756
|
+
element,
|
|
15757
|
+
elementsMap
|
|
15758
|
+
);
|
|
15759
|
+
if (dragOffset) {
|
|
15760
|
+
x1 += dragOffset.x;
|
|
15761
|
+
x2 += dragOffset.x;
|
|
15762
|
+
cx += dragOffset.x;
|
|
15763
|
+
y1 += dragOffset.y;
|
|
15764
|
+
y2 += dragOffset.y;
|
|
15765
|
+
cy += dragOffset.y;
|
|
15766
|
+
}
|
|
15767
|
+
const halfWidth = (x2 - x1) / 2;
|
|
15768
|
+
const halfHeight = (y2 - y1) / 2;
|
|
15769
|
+
if ((element.type === "diamond" || element.type === "ellipse") && !boundingBoxCorners) {
|
|
15770
|
+
const leftMid = pointRotateRads14(
|
|
15771
|
+
pointFrom18(x1, y1 + halfHeight),
|
|
15772
|
+
pointFrom18(cx, cy),
|
|
15773
|
+
element.angle
|
|
15774
|
+
);
|
|
15775
|
+
const topMid = pointRotateRads14(
|
|
15776
|
+
pointFrom18(x1 + halfWidth, y1),
|
|
15777
|
+
pointFrom18(cx, cy),
|
|
15778
|
+
element.angle
|
|
15779
|
+
);
|
|
15780
|
+
const rightMid = pointRotateRads14(
|
|
15781
|
+
pointFrom18(x2, y1 + halfHeight),
|
|
15782
|
+
pointFrom18(cx, cy),
|
|
15783
|
+
element.angle
|
|
15784
|
+
);
|
|
15785
|
+
const bottomMid = pointRotateRads14(
|
|
15786
|
+
pointFrom18(x1 + halfWidth, y2),
|
|
15787
|
+
pointFrom18(cx, cy),
|
|
15788
|
+
element.angle
|
|
15789
|
+
);
|
|
15790
|
+
const center = pointFrom18(cx, cy);
|
|
15791
|
+
result = omitCenter ? [leftMid, topMid, rightMid, bottomMid] : [leftMid, topMid, rightMid, bottomMid, center];
|
|
15792
|
+
} else {
|
|
15793
|
+
const topLeft = pointRotateRads14(
|
|
15794
|
+
pointFrom18(x1, y1),
|
|
15795
|
+
pointFrom18(cx, cy),
|
|
15796
|
+
element.angle
|
|
15797
|
+
);
|
|
15798
|
+
const topRight = pointRotateRads14(
|
|
15799
|
+
pointFrom18(x2, y1),
|
|
15800
|
+
pointFrom18(cx, cy),
|
|
15801
|
+
element.angle
|
|
15802
|
+
);
|
|
15803
|
+
const bottomLeft = pointRotateRads14(
|
|
15804
|
+
pointFrom18(x1, y2),
|
|
15805
|
+
pointFrom18(cx, cy),
|
|
15806
|
+
element.angle
|
|
15807
|
+
);
|
|
15808
|
+
const bottomRight = pointRotateRads14(
|
|
15809
|
+
pointFrom18(x2, y2),
|
|
15810
|
+
pointFrom18(cx, cy),
|
|
15811
|
+
element.angle
|
|
15812
|
+
);
|
|
15813
|
+
const center = pointFrom18(cx, cy);
|
|
15814
|
+
result = omitCenter ? [topLeft, topRight, bottomLeft, bottomRight] : [topLeft, topRight, bottomLeft, bottomRight, center];
|
|
15815
|
+
}
|
|
15816
|
+
} else if (elements.length > 1) {
|
|
15817
|
+
const [minX, minY, maxX, maxY] = getDraggedElementsBounds(
|
|
15818
|
+
elements,
|
|
15819
|
+
dragOffset ?? { x: 0, y: 0 }
|
|
15820
|
+
);
|
|
15821
|
+
const width = maxX - minX;
|
|
15822
|
+
const height = maxY - minY;
|
|
15823
|
+
const topLeft = pointFrom18(minX, minY);
|
|
15824
|
+
const topRight = pointFrom18(maxX, minY);
|
|
15825
|
+
const bottomLeft = pointFrom18(minX, maxY);
|
|
15826
|
+
const bottomRight = pointFrom18(maxX, maxY);
|
|
15827
|
+
const center = pointFrom18(minX + width / 2, minY + height / 2);
|
|
15828
|
+
result = omitCenter ? [topLeft, topRight, bottomLeft, bottomRight] : [topLeft, topRight, bottomLeft, bottomRight, center];
|
|
15829
|
+
}
|
|
15830
|
+
return result.map((p) => pointFrom18(round(p[0]), round(p[1])));
|
|
15831
|
+
};
|
|
15832
|
+
var getReferenceElements = (elements, selectedElements, appState, elementsMap) => getVisibleAndNonSelectedElements(
|
|
15833
|
+
elements,
|
|
15834
|
+
selectedElements,
|
|
15835
|
+
appState,
|
|
15836
|
+
elementsMap
|
|
15837
|
+
);
|
|
15838
|
+
var getVisibleGaps = (elements, selectedElements, appState, elementsMap) => {
|
|
15839
|
+
const referenceElements = getReferenceElements(
|
|
15840
|
+
elements,
|
|
15841
|
+
selectedElements,
|
|
15842
|
+
appState,
|
|
15843
|
+
elementsMap
|
|
15844
|
+
);
|
|
15845
|
+
const referenceBounds = getMaximumGroups(referenceElements, elementsMap).filter(
|
|
15846
|
+
(elementsGroup) => !(elementsGroup.length === 1 && isBoundToContainer6(elementsGroup[0]))
|
|
15847
|
+
).map(
|
|
15848
|
+
(group) => getCommonBounds5(group).map(
|
|
15849
|
+
(bound) => round(bound)
|
|
15850
|
+
)
|
|
15851
|
+
);
|
|
15852
|
+
const horizontallySorted = referenceBounds.sort((a, b) => a[0] - b[0]);
|
|
15853
|
+
const horizontalGaps = [];
|
|
15854
|
+
let c = 0;
|
|
15855
|
+
horizontal:
|
|
15856
|
+
for (let i = 0; i < horizontallySorted.length; i++) {
|
|
15857
|
+
const startBounds = horizontallySorted[i];
|
|
15858
|
+
for (let j = i + 1; j < horizontallySorted.length; j++) {
|
|
15859
|
+
if (++c > VISIBLE_GAPS_LIMIT_PER_AXIS) {
|
|
15860
|
+
break horizontal;
|
|
15861
|
+
}
|
|
15862
|
+
const endBounds = horizontallySorted[j];
|
|
15863
|
+
const [, startMinY, startMaxX, startMaxY] = startBounds;
|
|
15864
|
+
const [endMinX, endMinY, , endMaxY] = endBounds;
|
|
15865
|
+
if (startMaxX < endMinX && rangesOverlap(
|
|
15866
|
+
rangeInclusive(startMinY, startMaxY),
|
|
15867
|
+
rangeInclusive(endMinY, endMaxY)
|
|
15868
|
+
)) {
|
|
15869
|
+
horizontalGaps.push({
|
|
15870
|
+
startBounds,
|
|
15871
|
+
endBounds,
|
|
15872
|
+
startSide: [
|
|
15873
|
+
pointFrom18(startMaxX, startMinY),
|
|
15874
|
+
pointFrom18(startMaxX, startMaxY)
|
|
15875
|
+
],
|
|
15876
|
+
endSide: [pointFrom18(endMinX, endMinY), pointFrom18(endMinX, endMaxY)],
|
|
15877
|
+
length: endMinX - startMaxX,
|
|
15878
|
+
overlap: rangeIntersection(
|
|
15879
|
+
rangeInclusive(startMinY, startMaxY),
|
|
15880
|
+
rangeInclusive(endMinY, endMaxY)
|
|
15881
|
+
)
|
|
15882
|
+
});
|
|
15883
|
+
}
|
|
15884
|
+
}
|
|
15885
|
+
}
|
|
15886
|
+
const verticallySorted = referenceBounds.sort((a, b) => a[1] - b[1]);
|
|
15887
|
+
const verticalGaps = [];
|
|
15888
|
+
c = 0;
|
|
15889
|
+
vertical:
|
|
15890
|
+
for (let i = 0; i < verticallySorted.length; i++) {
|
|
15891
|
+
const startBounds = verticallySorted[i];
|
|
15892
|
+
for (let j = i + 1; j < verticallySorted.length; j++) {
|
|
15893
|
+
if (++c > VISIBLE_GAPS_LIMIT_PER_AXIS) {
|
|
15894
|
+
break vertical;
|
|
15895
|
+
}
|
|
15896
|
+
const endBounds = verticallySorted[j];
|
|
15897
|
+
const [startMinX, , startMaxX, startMaxY] = startBounds;
|
|
15898
|
+
const [endMinX, endMinY, endMaxX] = endBounds;
|
|
15899
|
+
if (startMaxY < endMinY && rangesOverlap(
|
|
15900
|
+
rangeInclusive(startMinX, startMaxX),
|
|
15901
|
+
rangeInclusive(endMinX, endMaxX)
|
|
15902
|
+
)) {
|
|
15903
|
+
verticalGaps.push({
|
|
15904
|
+
startBounds,
|
|
15905
|
+
endBounds,
|
|
15906
|
+
startSide: [
|
|
15907
|
+
pointFrom18(startMinX, startMaxY),
|
|
15908
|
+
pointFrom18(startMaxX, startMaxY)
|
|
15909
|
+
],
|
|
15910
|
+
endSide: [pointFrom18(endMinX, endMinY), pointFrom18(endMaxX, endMinY)],
|
|
15911
|
+
length: endMinY - startMaxY,
|
|
15912
|
+
overlap: rangeIntersection(
|
|
15913
|
+
rangeInclusive(startMinX, startMaxX),
|
|
15914
|
+
rangeInclusive(endMinX, endMaxX)
|
|
15915
|
+
)
|
|
15916
|
+
});
|
|
15917
|
+
}
|
|
15918
|
+
}
|
|
15919
|
+
}
|
|
15920
|
+
return {
|
|
15921
|
+
horizontalGaps,
|
|
15922
|
+
verticalGaps
|
|
15923
|
+
};
|
|
15924
|
+
};
|
|
15925
|
+
var getGapSnaps = (selectedElements, dragOffset, app, event, nearestSnapsX, nearestSnapsY, minOffset) => {
|
|
15926
|
+
if (!isSnappingEnabled({ app, event, selectedElements })) {
|
|
15927
|
+
return [];
|
|
15928
|
+
}
|
|
15929
|
+
if (selectedElements.length === 0) {
|
|
15930
|
+
return [];
|
|
15931
|
+
}
|
|
15932
|
+
const visibleGaps = SnapCache.getVisibleGaps();
|
|
15933
|
+
if (visibleGaps) {
|
|
15934
|
+
const { horizontalGaps, verticalGaps } = visibleGaps;
|
|
15935
|
+
const [minX, minY, maxX, maxY] = getDraggedElementsBounds(
|
|
15936
|
+
selectedElements,
|
|
15937
|
+
dragOffset
|
|
15938
|
+
).map((bound) => round(bound));
|
|
15939
|
+
const centerX = (minX + maxX) / 2;
|
|
15940
|
+
const centerY = (minY + maxY) / 2;
|
|
15941
|
+
for (const gap of horizontalGaps) {
|
|
15942
|
+
if (!rangesOverlap(rangeInclusive(minY, maxY), gap.overlap)) {
|
|
15943
|
+
continue;
|
|
15944
|
+
}
|
|
15945
|
+
const gapMidX = gap.startSide[0][0] + gap.length / 2;
|
|
15946
|
+
const centerOffset = round(gapMidX - centerX);
|
|
15947
|
+
const gapIsLargerThanSelection = gap.length > maxX - minX;
|
|
15948
|
+
if (gapIsLargerThanSelection && Math.abs(centerOffset) <= minOffset.x) {
|
|
15949
|
+
if (Math.abs(centerOffset) < minOffset.x) {
|
|
15950
|
+
nearestSnapsX.length = 0;
|
|
15951
|
+
}
|
|
15952
|
+
minOffset.x = Math.abs(centerOffset);
|
|
15953
|
+
const snap = {
|
|
15954
|
+
type: "gap",
|
|
15955
|
+
direction: "center_horizontal",
|
|
15956
|
+
gap,
|
|
15957
|
+
offset: centerOffset
|
|
15958
|
+
};
|
|
15959
|
+
nearestSnapsX.push(snap);
|
|
15960
|
+
continue;
|
|
15961
|
+
}
|
|
15962
|
+
const [, , endMaxX] = gap.endBounds;
|
|
15963
|
+
const distanceToEndElementX = minX - endMaxX;
|
|
15964
|
+
const sideOffsetRight = round(gap.length - distanceToEndElementX);
|
|
15965
|
+
if (Math.abs(sideOffsetRight) <= minOffset.x) {
|
|
15966
|
+
if (Math.abs(sideOffsetRight) < minOffset.x) {
|
|
15967
|
+
nearestSnapsX.length = 0;
|
|
15968
|
+
}
|
|
15969
|
+
minOffset.x = Math.abs(sideOffsetRight);
|
|
15970
|
+
const snap = {
|
|
15971
|
+
type: "gap",
|
|
15972
|
+
direction: "side_right",
|
|
15973
|
+
gap,
|
|
15974
|
+
offset: sideOffsetRight
|
|
15975
|
+
};
|
|
15976
|
+
nearestSnapsX.push(snap);
|
|
15977
|
+
continue;
|
|
15978
|
+
}
|
|
15979
|
+
const [startMinX, , ,] = gap.startBounds;
|
|
15980
|
+
const distanceToStartElementX = startMinX - maxX;
|
|
15981
|
+
const sideOffsetLeft = round(distanceToStartElementX - gap.length);
|
|
15982
|
+
if (Math.abs(sideOffsetLeft) <= minOffset.x) {
|
|
15983
|
+
if (Math.abs(sideOffsetLeft) < minOffset.x) {
|
|
15984
|
+
nearestSnapsX.length = 0;
|
|
15985
|
+
}
|
|
15986
|
+
minOffset.x = Math.abs(sideOffsetLeft);
|
|
15987
|
+
const snap = {
|
|
15988
|
+
type: "gap",
|
|
15989
|
+
direction: "side_left",
|
|
15990
|
+
gap,
|
|
15991
|
+
offset: sideOffsetLeft
|
|
15992
|
+
};
|
|
15993
|
+
nearestSnapsX.push(snap);
|
|
15994
|
+
continue;
|
|
15995
|
+
}
|
|
15996
|
+
}
|
|
15997
|
+
for (const gap of verticalGaps) {
|
|
15998
|
+
if (!rangesOverlap(rangeInclusive(minX, maxX), gap.overlap)) {
|
|
15999
|
+
continue;
|
|
16000
|
+
}
|
|
16001
|
+
const gapMidY = gap.startSide[0][1] + gap.length / 2;
|
|
16002
|
+
const centerOffset = round(gapMidY - centerY);
|
|
16003
|
+
const gapIsLargerThanSelection = gap.length > maxY - minY;
|
|
16004
|
+
if (gapIsLargerThanSelection && Math.abs(centerOffset) <= minOffset.y) {
|
|
16005
|
+
if (Math.abs(centerOffset) < minOffset.y) {
|
|
16006
|
+
nearestSnapsY.length = 0;
|
|
16007
|
+
}
|
|
16008
|
+
minOffset.y = Math.abs(centerOffset);
|
|
16009
|
+
const snap = {
|
|
16010
|
+
type: "gap",
|
|
16011
|
+
direction: "center_vertical",
|
|
16012
|
+
gap,
|
|
16013
|
+
offset: centerOffset
|
|
16014
|
+
};
|
|
16015
|
+
nearestSnapsY.push(snap);
|
|
16016
|
+
continue;
|
|
16017
|
+
}
|
|
16018
|
+
const [, startMinY, ,] = gap.startBounds;
|
|
16019
|
+
const distanceToStartElementY = startMinY - maxY;
|
|
16020
|
+
const sideOffsetTop = round(distanceToStartElementY - gap.length);
|
|
16021
|
+
if (Math.abs(sideOffsetTop) <= minOffset.y) {
|
|
16022
|
+
if (Math.abs(sideOffsetTop) < minOffset.y) {
|
|
16023
|
+
nearestSnapsY.length = 0;
|
|
16024
|
+
}
|
|
16025
|
+
minOffset.y = Math.abs(sideOffsetTop);
|
|
16026
|
+
const snap = {
|
|
16027
|
+
type: "gap",
|
|
16028
|
+
direction: "side_top",
|
|
16029
|
+
gap,
|
|
16030
|
+
offset: sideOffsetTop
|
|
16031
|
+
};
|
|
16032
|
+
nearestSnapsY.push(snap);
|
|
16122
16033
|
continue;
|
|
16123
16034
|
}
|
|
16124
|
-
|
|
16125
|
-
|
|
16035
|
+
const [, , , endMaxY] = gap.endBounds;
|
|
16036
|
+
const distanceToEndElementY = round(minY - endMaxY);
|
|
16037
|
+
const sideOffsetBottom = gap.length - distanceToEndElementY;
|
|
16038
|
+
if (Math.abs(sideOffsetBottom) <= minOffset.y) {
|
|
16039
|
+
if (Math.abs(sideOffsetBottom) < minOffset.y) {
|
|
16040
|
+
nearestSnapsY.length = 0;
|
|
16041
|
+
}
|
|
16042
|
+
minOffset.y = Math.abs(sideOffsetBottom);
|
|
16043
|
+
const snap = {
|
|
16044
|
+
type: "gap",
|
|
16045
|
+
direction: "side_bottom",
|
|
16046
|
+
gap,
|
|
16047
|
+
offset: sideOffsetBottom
|
|
16048
|
+
};
|
|
16049
|
+
nearestSnapsY.push(snap);
|
|
16050
|
+
continue;
|
|
16126
16051
|
}
|
|
16127
16052
|
}
|
|
16128
|
-
return { elementsMap, newElementCanvasElement };
|
|
16129
|
-
}
|
|
16130
|
-
sortSelectedElementsIntoHighlightedFrame({
|
|
16131
|
-
visibleElements,
|
|
16132
|
-
selectedElements,
|
|
16133
|
-
frameToHighlight
|
|
16134
|
-
}) {
|
|
16135
|
-
if (!selectedElements.length) {
|
|
16136
|
-
return visibleElements;
|
|
16137
|
-
}
|
|
16138
|
-
const selectedElementsMap = arrayToMap24(selectedElements);
|
|
16139
|
-
const deselectedElements = visibleElements.filter(
|
|
16140
|
-
(element) => !selectedElementsMap.has(element.id)
|
|
16141
|
-
);
|
|
16142
|
-
const insertionIndex = getFrameChildrenInsertionIndex(
|
|
16143
|
-
deselectedElements,
|
|
16144
|
-
frameToHighlight.id
|
|
16145
|
-
);
|
|
16146
|
-
if (insertionIndex === null) {
|
|
16147
|
-
return visibleElements;
|
|
16148
|
-
}
|
|
16149
|
-
return [
|
|
16150
|
-
...deselectedElements.slice(0, insertionIndex),
|
|
16151
|
-
...selectedElements,
|
|
16152
|
-
...deselectedElements.slice(insertionIndex)
|
|
16153
|
-
];
|
|
16154
|
-
}
|
|
16155
|
-
// NOTE Doesn't destroy everything (scene, rc, etc.) because it may not be
|
|
16156
|
-
// safe to break TS contract here (for upstream cases)
|
|
16157
|
-
destroy() {
|
|
16158
|
-
renderStaticSceneThrottled.cancel();
|
|
16159
|
-
this._getRenderableElements.clear();
|
|
16160
16053
|
}
|
|
16161
16054
|
};
|
|
16162
|
-
|
|
16163
|
-
|
|
16164
|
-
|
|
16165
|
-
|
|
16166
|
-
|
|
16167
|
-
|
|
16168
|
-
var getContainerCoords2 = (element, appState, elementsMap) => {
|
|
16169
|
-
const [x1, y1] = getElementAbsoluteCoords5(element, elementsMap);
|
|
16170
|
-
const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords2(
|
|
16171
|
-
{ sceneX: x1 + element.width, sceneY: y1 },
|
|
16172
|
-
appState
|
|
16055
|
+
var getReferenceSnapPoints = (elements, selectedElements, appState, elementsMap) => {
|
|
16056
|
+
const referenceElements = getReferenceElements(
|
|
16057
|
+
elements,
|
|
16058
|
+
selectedElements,
|
|
16059
|
+
appState,
|
|
16060
|
+
elementsMap
|
|
16173
16061
|
);
|
|
16174
|
-
|
|
16175
|
-
|
|
16176
|
-
|
|
16062
|
+
return getMaximumGroups(referenceElements, elementsMap).filter(
|
|
16063
|
+
(elementsGroup) => !(elementsGroup.length === 1 && isBoundToContainer6(elementsGroup[0]))
|
|
16064
|
+
).flatMap((elementGroup) => getElementsCorners(elementGroup, elementsMap));
|
|
16177
16065
|
};
|
|
16178
|
-
var
|
|
16179
|
-
|
|
16180
|
-
|
|
16181
|
-
elementsMap
|
|
16182
|
-
}) => {
|
|
16183
|
-
const appState = useExcalidrawAppState();
|
|
16184
|
-
if (appState.contextMenu || appState.newElement || appState.resizingElement || appState.isRotating || appState.openMenu || appState.viewModeEnabled) {
|
|
16185
|
-
return null;
|
|
16066
|
+
var getPointSnaps = (selectedElements, selectionSnapPoints, app, event, nearestSnapsX, nearestSnapsY, minOffset) => {
|
|
16067
|
+
if (!isSnappingEnabled({ app, event, selectedElements }) || selectedElements.length === 0 && selectionSnapPoints.length === 0) {
|
|
16068
|
+
return [];
|
|
16186
16069
|
}
|
|
16187
|
-
const
|
|
16188
|
-
|
|
16189
|
-
|
|
16190
|
-
|
|
16191
|
-
|
|
16192
|
-
|
|
16193
|
-
|
|
16194
|
-
|
|
16195
|
-
|
|
16196
|
-
|
|
16197
|
-
|
|
16198
|
-
|
|
16070
|
+
const referenceSnapPoints = SnapCache.getReferenceSnapPoints();
|
|
16071
|
+
if (referenceSnapPoints) {
|
|
16072
|
+
for (const thisSnapPoint of selectionSnapPoints) {
|
|
16073
|
+
for (const otherSnapPoint of referenceSnapPoints) {
|
|
16074
|
+
const offsetX = otherSnapPoint[0] - thisSnapPoint[0];
|
|
16075
|
+
const offsetY = otherSnapPoint[1] - thisSnapPoint[1];
|
|
16076
|
+
if (Math.abs(offsetX) <= minOffset.x) {
|
|
16077
|
+
if (Math.abs(offsetX) < minOffset.x) {
|
|
16078
|
+
nearestSnapsX.length = 0;
|
|
16079
|
+
}
|
|
16080
|
+
nearestSnapsX.push({
|
|
16081
|
+
type: "point",
|
|
16082
|
+
points: [thisSnapPoint, otherSnapPoint],
|
|
16083
|
+
offset: offsetX
|
|
16084
|
+
});
|
|
16085
|
+
minOffset.x = Math.abs(offsetX);
|
|
16086
|
+
}
|
|
16087
|
+
if (Math.abs(offsetY) <= minOffset.y) {
|
|
16088
|
+
if (Math.abs(offsetY) < minOffset.y) {
|
|
16089
|
+
nearestSnapsY.length = 0;
|
|
16090
|
+
}
|
|
16091
|
+
nearestSnapsY.push({
|
|
16092
|
+
type: "point",
|
|
16093
|
+
points: [thisSnapPoint, otherSnapPoint],
|
|
16094
|
+
offset: offsetY
|
|
16095
|
+
});
|
|
16096
|
+
minOffset.y = Math.abs(offsetY);
|
|
16097
|
+
}
|
|
16098
|
+
}
|
|
16199
16099
|
}
|
|
16200
|
-
|
|
16201
|
-
};
|
|
16202
|
-
|
|
16203
|
-
// laserTrails.ts
|
|
16204
|
-
import { DEFAULT_LASER_COLOR, easeOut } from "@excalidraw/common";
|
|
16205
|
-
|
|
16206
|
-
// animatedTrail.ts
|
|
16207
|
-
import { LaserPointer } from "@excalidraw/laser-pointer";
|
|
16208
|
-
import {
|
|
16209
|
-
SVG_NS,
|
|
16210
|
-
getSvgPathFromStroke as getSvgPathFromStroke2,
|
|
16211
|
-
sceneCoordsToViewportCoords as sceneCoordsToViewportCoords3
|
|
16212
|
-
} from "@excalidraw/common";
|
|
16213
|
-
|
|
16214
|
-
// reactUtils.ts
|
|
16215
|
-
import { version as ReactVersion } from "react";
|
|
16216
|
-
import { unstable_batchedUpdates } from "react-dom";
|
|
16217
|
-
import { throttleRAF } from "@excalidraw/common";
|
|
16218
|
-
var withBatchedUpdates = (func) => (event) => {
|
|
16219
|
-
unstable_batchedUpdates(func, event);
|
|
16100
|
+
}
|
|
16220
16101
|
};
|
|
16221
|
-
var
|
|
16222
|
-
|
|
16223
|
-
|
|
16102
|
+
var snapDraggedElements = (elements, dragOffset, app, event, elementsMap) => {
|
|
16103
|
+
const appState = app.state;
|
|
16104
|
+
const selectedElements = getSelectedElements4(elements, appState);
|
|
16105
|
+
if (!isSnappingEnabled({ app, event, selectedElements }) || selectedElements.length === 0) {
|
|
16106
|
+
return {
|
|
16107
|
+
snapOffset: {
|
|
16108
|
+
x: 0,
|
|
16109
|
+
y: 0
|
|
16110
|
+
},
|
|
16111
|
+
snapLines: []
|
|
16112
|
+
};
|
|
16113
|
+
}
|
|
16114
|
+
dragOffset.x = round(dragOffset.x);
|
|
16115
|
+
dragOffset.y = round(dragOffset.y);
|
|
16116
|
+
const nearestSnapsX = [];
|
|
16117
|
+
const nearestSnapsY = [];
|
|
16118
|
+
const snapDistance = getSnapDistance(appState.zoom.value);
|
|
16119
|
+
const minOffset = {
|
|
16120
|
+
x: snapDistance,
|
|
16121
|
+
y: snapDistance
|
|
16122
|
+
};
|
|
16123
|
+
const selectionPoints = getElementsCorners(selectedElements, elementsMap, {
|
|
16124
|
+
dragOffset
|
|
16224
16125
|
});
|
|
16126
|
+
getPointSnaps(
|
|
16127
|
+
selectedElements,
|
|
16128
|
+
selectionPoints,
|
|
16129
|
+
app,
|
|
16130
|
+
event,
|
|
16131
|
+
nearestSnapsX,
|
|
16132
|
+
nearestSnapsY,
|
|
16133
|
+
minOffset
|
|
16134
|
+
);
|
|
16135
|
+
getGapSnaps(
|
|
16136
|
+
selectedElements,
|
|
16137
|
+
dragOffset,
|
|
16138
|
+
app,
|
|
16139
|
+
event,
|
|
16140
|
+
nearestSnapsX,
|
|
16141
|
+
nearestSnapsY,
|
|
16142
|
+
minOffset
|
|
16143
|
+
);
|
|
16144
|
+
const snapOffset = {
|
|
16145
|
+
x: nearestSnapsX[0]?.offset ?? 0,
|
|
16146
|
+
y: nearestSnapsY[0]?.offset ?? 0
|
|
16147
|
+
};
|
|
16148
|
+
minOffset.x = 0;
|
|
16149
|
+
minOffset.y = 0;
|
|
16150
|
+
nearestSnapsX.length = 0;
|
|
16151
|
+
nearestSnapsY.length = 0;
|
|
16152
|
+
const newDragOffset = {
|
|
16153
|
+
x: round(dragOffset.x + snapOffset.x),
|
|
16154
|
+
y: round(dragOffset.y + snapOffset.y)
|
|
16155
|
+
};
|
|
16156
|
+
getPointSnaps(
|
|
16157
|
+
selectedElements,
|
|
16158
|
+
getElementsCorners(selectedElements, elementsMap, {
|
|
16159
|
+
dragOffset: newDragOffset
|
|
16160
|
+
}),
|
|
16161
|
+
app,
|
|
16162
|
+
event,
|
|
16163
|
+
nearestSnapsX,
|
|
16164
|
+
nearestSnapsY,
|
|
16165
|
+
minOffset
|
|
16166
|
+
);
|
|
16167
|
+
getGapSnaps(
|
|
16168
|
+
selectedElements,
|
|
16169
|
+
newDragOffset,
|
|
16170
|
+
app,
|
|
16171
|
+
event,
|
|
16172
|
+
nearestSnapsX,
|
|
16173
|
+
nearestSnapsY,
|
|
16174
|
+
minOffset
|
|
16175
|
+
);
|
|
16176
|
+
const pointSnapLines = createPointSnapLines(nearestSnapsX, nearestSnapsY);
|
|
16177
|
+
const gapSnapLines = createGapSnapLines(
|
|
16178
|
+
selectedElements,
|
|
16179
|
+
newDragOffset,
|
|
16180
|
+
[...nearestSnapsX, ...nearestSnapsY].filter(
|
|
16181
|
+
(snap) => snap.type === "gap"
|
|
16182
|
+
)
|
|
16183
|
+
);
|
|
16184
|
+
return {
|
|
16185
|
+
snapOffset,
|
|
16186
|
+
snapLines: [...pointSnapLines, ...gapSnapLines]
|
|
16187
|
+
};
|
|
16225
16188
|
};
|
|
16226
|
-
var
|
|
16227
|
-
|
|
16228
|
-
|
|
16229
|
-
|
|
16230
|
-
|
|
16231
|
-
|
|
16232
|
-
|
|
16189
|
+
var round = (x) => {
|
|
16190
|
+
const decimalPlaces = 6;
|
|
16191
|
+
return Math.round(x * 10 ** decimalPlaces) / 10 ** decimalPlaces;
|
|
16192
|
+
};
|
|
16193
|
+
var dedupePoints = (points) => {
|
|
16194
|
+
const map = /* @__PURE__ */ new Map();
|
|
16195
|
+
for (const point of points) {
|
|
16196
|
+
const key = point.join(",");
|
|
16197
|
+
if (!map.has(key)) {
|
|
16198
|
+
map.set(key, point);
|
|
16199
|
+
}
|
|
16233
16200
|
}
|
|
16234
|
-
|
|
16235
|
-
|
|
16236
|
-
|
|
16237
|
-
|
|
16238
|
-
|
|
16239
|
-
|
|
16240
|
-
|
|
16241
|
-
|
|
16242
|
-
|
|
16201
|
+
return Array.from(map.values());
|
|
16202
|
+
};
|
|
16203
|
+
var createPointSnapLines = (nearestSnapsX, nearestSnapsY) => {
|
|
16204
|
+
const snapsX = {};
|
|
16205
|
+
const snapsY = {};
|
|
16206
|
+
if (nearestSnapsX.length > 0) {
|
|
16207
|
+
for (const snap of nearestSnapsX) {
|
|
16208
|
+
if (snap.type === "point") {
|
|
16209
|
+
const key = round(snap.points[0][0]);
|
|
16210
|
+
if (!snapsX[key]) {
|
|
16211
|
+
snapsX[key] = [];
|
|
16243
16212
|
}
|
|
16244
|
-
|
|
16213
|
+
snapsX[key].push(
|
|
16214
|
+
...snap.points.map(
|
|
16215
|
+
(p) => pointFrom18(round(p[0]), round(p[1]))
|
|
16216
|
+
)
|
|
16217
|
+
);
|
|
16245
16218
|
}
|
|
16246
|
-
return true;
|
|
16247
|
-
}
|
|
16248
|
-
return false;
|
|
16249
|
-
};
|
|
16250
|
-
})();
|
|
16251
|
-
|
|
16252
|
-
// renderer/animation.ts
|
|
16253
|
-
var _AnimationController = class _AnimationController {
|
|
16254
|
-
static start(key, animation) {
|
|
16255
|
-
if (_AnimationController.animations.has(key)) {
|
|
16256
|
-
return;
|
|
16257
|
-
}
|
|
16258
|
-
const initialState = animation({
|
|
16259
|
-
deltaTime: 0,
|
|
16260
|
-
state: void 0
|
|
16261
|
-
});
|
|
16262
|
-
if (initialState) {
|
|
16263
|
-
_AnimationController.animations.set(key, {
|
|
16264
|
-
animation,
|
|
16265
|
-
lastTime: 0,
|
|
16266
|
-
state: initialState
|
|
16267
|
-
});
|
|
16268
|
-
_AnimationController.scheduleNextFrame();
|
|
16269
|
-
}
|
|
16270
|
-
}
|
|
16271
|
-
static scheduleNextFrame() {
|
|
16272
|
-
if (_AnimationController.scheduledFrame) {
|
|
16273
|
-
return;
|
|
16274
|
-
}
|
|
16275
|
-
if (isRenderThrottlingEnabled()) {
|
|
16276
|
-
_AnimationController.scheduledFrame = {
|
|
16277
|
-
id: requestAnimationFrame(_AnimationController.tick),
|
|
16278
|
-
type: "raf"
|
|
16279
|
-
};
|
|
16280
|
-
} else {
|
|
16281
|
-
_AnimationController.scheduledFrame = {
|
|
16282
|
-
id: setTimeout(_AnimationController.tick, 0),
|
|
16283
|
-
type: "timeout"
|
|
16284
|
-
};
|
|
16285
16219
|
}
|
|
16286
16220
|
}
|
|
16287
|
-
|
|
16288
|
-
|
|
16289
|
-
|
|
16290
|
-
|
|
16291
|
-
|
|
16292
|
-
|
|
16293
|
-
|
|
16294
|
-
|
|
16221
|
+
if (nearestSnapsY.length > 0) {
|
|
16222
|
+
for (const snap of nearestSnapsY) {
|
|
16223
|
+
if (snap.type === "point") {
|
|
16224
|
+
const key = round(snap.points[0][1]);
|
|
16225
|
+
if (!snapsY[key]) {
|
|
16226
|
+
snapsY[key] = [];
|
|
16227
|
+
}
|
|
16228
|
+
snapsY[key].push(
|
|
16229
|
+
...snap.points.map(
|
|
16230
|
+
(p) => pointFrom18(round(p[0]), round(p[1]))
|
|
16231
|
+
)
|
|
16232
|
+
);
|
|
16233
|
+
}
|
|
16295
16234
|
}
|
|
16296
|
-
_AnimationController.scheduledFrame = null;
|
|
16297
16235
|
}
|
|
16298
|
-
|
|
16299
|
-
|
|
16300
|
-
|
|
16236
|
+
return Object.entries(snapsX).map(([key, points]) => {
|
|
16237
|
+
return {
|
|
16238
|
+
type: "points",
|
|
16239
|
+
points: dedupePoints(
|
|
16240
|
+
points.map((p) => {
|
|
16241
|
+
return pointFrom18(Number(key), p[1]);
|
|
16242
|
+
}).sort((a, b) => a[1] - b[1])
|
|
16243
|
+
)
|
|
16244
|
+
};
|
|
16245
|
+
}).concat(
|
|
16246
|
+
Object.entries(snapsY).map(([key, points]) => {
|
|
16247
|
+
return {
|
|
16248
|
+
type: "points",
|
|
16249
|
+
points: dedupePoints(
|
|
16250
|
+
points.map((p) => {
|
|
16251
|
+
return pointFrom18(p[0], Number(key));
|
|
16252
|
+
}).sort((a, b) => a[0] - b[0])
|
|
16253
|
+
)
|
|
16254
|
+
};
|
|
16255
|
+
})
|
|
16256
|
+
);
|
|
16257
|
+
};
|
|
16258
|
+
var dedupeGapSnapLines = (gapSnapLines) => {
|
|
16259
|
+
const map = /* @__PURE__ */ new Map();
|
|
16260
|
+
for (const gapSnapLine of gapSnapLines) {
|
|
16261
|
+
const key = gapSnapLine.points.flat().map((point) => [round(point)]).join(",");
|
|
16262
|
+
if (!map.has(key)) {
|
|
16263
|
+
map.set(key, gapSnapLine);
|
|
16301
16264
|
}
|
|
16302
|
-
_AnimationController.cancelScheduledFrame();
|
|
16303
|
-
return true;
|
|
16304
16265
|
}
|
|
16305
|
-
|
|
16306
|
-
|
|
16307
|
-
|
|
16308
|
-
|
|
16309
|
-
|
|
16310
|
-
|
|
16311
|
-
|
|
16312
|
-
|
|
16313
|
-
|
|
16314
|
-
|
|
16315
|
-
|
|
16316
|
-
|
|
16317
|
-
|
|
16318
|
-
|
|
16319
|
-
|
|
16320
|
-
|
|
16321
|
-
|
|
16322
|
-
|
|
16266
|
+
return Array.from(map.values());
|
|
16267
|
+
};
|
|
16268
|
+
var createGapSnapLines = (selectedElements, dragOffset, gapSnaps) => {
|
|
16269
|
+
const [minX, minY, maxX, maxY] = getDraggedElementsBounds(
|
|
16270
|
+
selectedElements,
|
|
16271
|
+
dragOffset
|
|
16272
|
+
);
|
|
16273
|
+
const gapSnapLines = [];
|
|
16274
|
+
for (const gapSnap of gapSnaps) {
|
|
16275
|
+
const [startMinX, startMinY, startMaxX, startMaxY] = gapSnap.gap.startBounds;
|
|
16276
|
+
const [endMinX, endMinY, endMaxX, endMaxY] = gapSnap.gap.endBounds;
|
|
16277
|
+
const verticalIntersection = rangeIntersection(
|
|
16278
|
+
rangeInclusive(minY, maxY),
|
|
16279
|
+
gapSnap.gap.overlap
|
|
16280
|
+
);
|
|
16281
|
+
const horizontalGapIntersection = rangeIntersection(
|
|
16282
|
+
rangeInclusive(minX, maxX),
|
|
16283
|
+
gapSnap.gap.overlap
|
|
16284
|
+
);
|
|
16285
|
+
switch (gapSnap.direction) {
|
|
16286
|
+
case "center_horizontal": {
|
|
16287
|
+
if (verticalIntersection) {
|
|
16288
|
+
const gapLineY = (verticalIntersection[0] + verticalIntersection[1]) / 2;
|
|
16289
|
+
gapSnapLines.push(
|
|
16290
|
+
{
|
|
16291
|
+
type: "gap",
|
|
16292
|
+
direction: "horizontal",
|
|
16293
|
+
points: [
|
|
16294
|
+
pointFrom18(gapSnap.gap.startSide[0][0], gapLineY),
|
|
16295
|
+
pointFrom18(minX, gapLineY)
|
|
16296
|
+
]
|
|
16297
|
+
},
|
|
16298
|
+
{
|
|
16299
|
+
type: "gap",
|
|
16300
|
+
direction: "horizontal",
|
|
16301
|
+
points: [
|
|
16302
|
+
pointFrom18(maxX, gapLineY),
|
|
16303
|
+
pointFrom18(gapSnap.gap.endSide[0][0], gapLineY)
|
|
16304
|
+
]
|
|
16305
|
+
}
|
|
16306
|
+
);
|
|
16307
|
+
}
|
|
16308
|
+
break;
|
|
16309
|
+
}
|
|
16310
|
+
case "center_vertical": {
|
|
16311
|
+
if (horizontalGapIntersection) {
|
|
16312
|
+
const gapLineX = (horizontalGapIntersection[0] + horizontalGapIntersection[1]) / 2;
|
|
16313
|
+
gapSnapLines.push(
|
|
16314
|
+
{
|
|
16315
|
+
type: "gap",
|
|
16316
|
+
direction: "vertical",
|
|
16317
|
+
points: [
|
|
16318
|
+
pointFrom18(gapLineX, gapSnap.gap.startSide[0][1]),
|
|
16319
|
+
pointFrom18(gapLineX, minY)
|
|
16320
|
+
]
|
|
16321
|
+
},
|
|
16322
|
+
{
|
|
16323
|
+
type: "gap",
|
|
16324
|
+
direction: "vertical",
|
|
16325
|
+
points: [
|
|
16326
|
+
pointFrom18(gapLineX, maxY),
|
|
16327
|
+
pointFrom18(gapLineX, gapSnap.gap.endSide[0][1])
|
|
16328
|
+
]
|
|
16329
|
+
}
|
|
16330
|
+
);
|
|
16331
|
+
}
|
|
16332
|
+
break;
|
|
16333
|
+
}
|
|
16334
|
+
case "side_right": {
|
|
16335
|
+
if (verticalIntersection) {
|
|
16336
|
+
const gapLineY = (verticalIntersection[0] + verticalIntersection[1]) / 2;
|
|
16337
|
+
gapSnapLines.push(
|
|
16338
|
+
{
|
|
16339
|
+
type: "gap",
|
|
16340
|
+
direction: "horizontal",
|
|
16341
|
+
points: [
|
|
16342
|
+
pointFrom18(startMaxX, gapLineY),
|
|
16343
|
+
pointFrom18(endMinX, gapLineY)
|
|
16344
|
+
]
|
|
16345
|
+
},
|
|
16346
|
+
{
|
|
16347
|
+
type: "gap",
|
|
16348
|
+
direction: "horizontal",
|
|
16349
|
+
points: [pointFrom18(endMaxX, gapLineY), pointFrom18(minX, gapLineY)]
|
|
16350
|
+
}
|
|
16351
|
+
);
|
|
16352
|
+
}
|
|
16353
|
+
break;
|
|
16354
|
+
}
|
|
16355
|
+
case "side_left": {
|
|
16356
|
+
if (verticalIntersection) {
|
|
16357
|
+
const gapLineY = (verticalIntersection[0] + verticalIntersection[1]) / 2;
|
|
16358
|
+
gapSnapLines.push(
|
|
16359
|
+
{
|
|
16360
|
+
type: "gap",
|
|
16361
|
+
direction: "horizontal",
|
|
16362
|
+
points: [
|
|
16363
|
+
pointFrom18(maxX, gapLineY),
|
|
16364
|
+
pointFrom18(startMinX, gapLineY)
|
|
16365
|
+
]
|
|
16366
|
+
},
|
|
16367
|
+
{
|
|
16368
|
+
type: "gap",
|
|
16369
|
+
direction: "horizontal",
|
|
16370
|
+
points: [
|
|
16371
|
+
pointFrom18(startMaxX, gapLineY),
|
|
16372
|
+
pointFrom18(endMinX, gapLineY)
|
|
16373
|
+
]
|
|
16374
|
+
}
|
|
16375
|
+
);
|
|
16323
16376
|
}
|
|
16377
|
+
break;
|
|
16324
16378
|
}
|
|
16325
|
-
|
|
16326
|
-
|
|
16379
|
+
case "side_top": {
|
|
16380
|
+
if (horizontalGapIntersection) {
|
|
16381
|
+
const gapLineX = (horizontalGapIntersection[0] + horizontalGapIntersection[1]) / 2;
|
|
16382
|
+
gapSnapLines.push(
|
|
16383
|
+
{
|
|
16384
|
+
type: "gap",
|
|
16385
|
+
direction: "vertical",
|
|
16386
|
+
points: [
|
|
16387
|
+
pointFrom18(gapLineX, maxY),
|
|
16388
|
+
pointFrom18(gapLineX, startMinY)
|
|
16389
|
+
]
|
|
16390
|
+
},
|
|
16391
|
+
{
|
|
16392
|
+
type: "gap",
|
|
16393
|
+
direction: "vertical",
|
|
16394
|
+
points: [
|
|
16395
|
+
pointFrom18(gapLineX, startMaxY),
|
|
16396
|
+
pointFrom18(gapLineX, endMinY)
|
|
16397
|
+
]
|
|
16398
|
+
}
|
|
16399
|
+
);
|
|
16400
|
+
}
|
|
16401
|
+
break;
|
|
16327
16402
|
}
|
|
16328
|
-
|
|
16329
|
-
|
|
16330
|
-
|
|
16331
|
-
|
|
16332
|
-
|
|
16333
|
-
|
|
16334
|
-
|
|
16335
|
-
|
|
16336
|
-
|
|
16337
|
-
|
|
16338
|
-
|
|
16339
|
-
|
|
16340
|
-
|
|
16341
|
-
|
|
16342
|
-
|
|
16343
|
-
|
|
16344
|
-
|
|
16345
|
-
|
|
16346
|
-
this.app = app;
|
|
16347
|
-
this.options = options;
|
|
16348
|
-
__publicField(this, "currentTrail");
|
|
16349
|
-
__publicField(this, "pastTrails", []);
|
|
16350
|
-
__publicField(this, "container");
|
|
16351
|
-
__publicField(this, "trailElement");
|
|
16352
|
-
__publicField(this, "trailAnimation");
|
|
16353
|
-
__publicField(this, "key");
|
|
16354
|
-
this.key = `animated-trail-${_AnimatedTrail.counter++}`;
|
|
16355
|
-
this.trailElement = document.createElementNS(SVG_NS, "path");
|
|
16356
|
-
if (this.options.animateTrail) {
|
|
16357
|
-
this.trailAnimation = document.createElementNS(SVG_NS, "animate");
|
|
16358
|
-
this.trailAnimation.setAttribute("attributeName", "stroke-dashoffset");
|
|
16359
|
-
this.trailElement.setAttribute("stroke-dasharray", "7 7");
|
|
16360
|
-
this.trailElement.setAttribute("stroke-dashoffset", "10");
|
|
16361
|
-
this.trailAnimation.setAttribute("from", "0");
|
|
16362
|
-
this.trailAnimation.setAttribute("to", `-14`);
|
|
16363
|
-
this.trailAnimation.setAttribute("dur", "0.3s");
|
|
16364
|
-
this.trailElement.appendChild(this.trailAnimation);
|
|
16365
|
-
}
|
|
16366
|
-
}
|
|
16367
|
-
get hasCurrentTrail() {
|
|
16368
|
-
return !!this.currentTrail;
|
|
16369
|
-
}
|
|
16370
|
-
hasLastPoint(x, y) {
|
|
16371
|
-
if (this.currentTrail) {
|
|
16372
|
-
const len = this.currentTrail.originalPoints.length;
|
|
16373
|
-
return this.currentTrail.originalPoints[len - 1][0] === x && this.currentTrail.originalPoints[len - 1][1] === y;
|
|
16374
|
-
}
|
|
16375
|
-
return false;
|
|
16376
|
-
}
|
|
16377
|
-
cleanup() {
|
|
16378
|
-
this.pastTrails = [];
|
|
16379
|
-
this.currentTrail = void 0;
|
|
16380
|
-
if (this.trailElement.parentNode === this.container) {
|
|
16381
|
-
this.container?.removeChild(this.trailElement);
|
|
16382
|
-
}
|
|
16383
|
-
}
|
|
16384
|
-
start(container) {
|
|
16385
|
-
if (container) {
|
|
16386
|
-
this.container = container;
|
|
16387
|
-
}
|
|
16388
|
-
if (this.trailElement.parentNode !== this.container && this.container) {
|
|
16389
|
-
this.container.appendChild(this.trailElement);
|
|
16390
|
-
}
|
|
16391
|
-
if (!AnimationController.running(this.key)) {
|
|
16392
|
-
AnimationController.start(this.key, () => {
|
|
16393
|
-
const needsNext = this.onFrame();
|
|
16394
|
-
if (needsNext) {
|
|
16395
|
-
return { keep: true };
|
|
16403
|
+
case "side_bottom": {
|
|
16404
|
+
if (horizontalGapIntersection) {
|
|
16405
|
+
const gapLineX = (horizontalGapIntersection[0] + horizontalGapIntersection[1]) / 2;
|
|
16406
|
+
gapSnapLines.push(
|
|
16407
|
+
{
|
|
16408
|
+
type: "gap",
|
|
16409
|
+
direction: "vertical",
|
|
16410
|
+
points: [
|
|
16411
|
+
pointFrom18(gapLineX, startMaxY),
|
|
16412
|
+
pointFrom18(gapLineX, endMinY)
|
|
16413
|
+
]
|
|
16414
|
+
},
|
|
16415
|
+
{
|
|
16416
|
+
type: "gap",
|
|
16417
|
+
direction: "vertical",
|
|
16418
|
+
points: [pointFrom18(gapLineX, endMaxY), pointFrom18(gapLineX, minY)]
|
|
16419
|
+
}
|
|
16420
|
+
);
|
|
16396
16421
|
}
|
|
16397
|
-
|
|
16398
|
-
|
|
16399
|
-
});
|
|
16422
|
+
break;
|
|
16423
|
+
}
|
|
16400
16424
|
}
|
|
16401
16425
|
}
|
|
16402
|
-
|
|
16403
|
-
|
|
16404
|
-
|
|
16405
|
-
|
|
16406
|
-
|
|
16407
|
-
|
|
16408
|
-
|
|
16409
|
-
|
|
16410
|
-
|
|
16411
|
-
|
|
16412
|
-
|
|
16413
|
-
|
|
16414
|
-
|
|
16415
|
-
|
|
16426
|
+
return dedupeGapSnapLines(
|
|
16427
|
+
gapSnapLines.map((gapSnapLine) => {
|
|
16428
|
+
return {
|
|
16429
|
+
...gapSnapLine,
|
|
16430
|
+
points: gapSnapLine.points.map(
|
|
16431
|
+
(p) => pointFrom18(round(p[0]), round(p[1]))
|
|
16432
|
+
)
|
|
16433
|
+
};
|
|
16434
|
+
})
|
|
16435
|
+
);
|
|
16436
|
+
};
|
|
16437
|
+
var snapResizingElements = (selectedElements, selectedOriginalElements, app, event, dragOffset, transformHandle) => {
|
|
16438
|
+
if (!isSnappingEnabled({ event, selectedElements, app }) || selectedElements.length === 0 || selectedElements.length === 1 && !areRoughlyEqual(selectedElements[0].angle, 0)) {
|
|
16439
|
+
return {
|
|
16440
|
+
snapOffset: { x: 0, y: 0 },
|
|
16441
|
+
snapLines: []
|
|
16442
|
+
};
|
|
16416
16443
|
}
|
|
16417
|
-
|
|
16418
|
-
|
|
16419
|
-
|
|
16420
|
-
|
|
16421
|
-
|
|
16422
|
-
|
|
16423
|
-
this.update();
|
|
16444
|
+
let [minX, minY, maxX, maxY] = getCommonBounds5(selectedOriginalElements);
|
|
16445
|
+
if (transformHandle) {
|
|
16446
|
+
if (transformHandle.includes("e")) {
|
|
16447
|
+
maxX += dragOffset.x;
|
|
16448
|
+
} else if (transformHandle.includes("w")) {
|
|
16449
|
+
minX += dragOffset.x;
|
|
16424
16450
|
}
|
|
16425
|
-
|
|
16426
|
-
|
|
16427
|
-
|
|
16428
|
-
|
|
16429
|
-
clearTrails() {
|
|
16430
|
-
this.pastTrails = [];
|
|
16431
|
-
this.currentTrail = void 0;
|
|
16432
|
-
this.update();
|
|
16433
|
-
}
|
|
16434
|
-
update() {
|
|
16435
|
-
this.start();
|
|
16436
|
-
if (this.trailAnimation) {
|
|
16437
|
-
this.trailAnimation.setAttribute("begin", "indefinite");
|
|
16438
|
-
this.trailAnimation.setAttribute("repeatCount", "indefinite");
|
|
16451
|
+
if (transformHandle.includes("n")) {
|
|
16452
|
+
minY += dragOffset.y;
|
|
16453
|
+
} else if (transformHandle.includes("s")) {
|
|
16454
|
+
maxY += dragOffset.y;
|
|
16439
16455
|
}
|
|
16440
16456
|
}
|
|
16441
|
-
|
|
16442
|
-
|
|
16443
|
-
|
|
16444
|
-
|
|
16445
|
-
|
|
16446
|
-
|
|
16447
|
-
|
|
16448
|
-
|
|
16449
|
-
|
|
16450
|
-
|
|
16451
|
-
|
|
16452
|
-
|
|
16453
|
-
|
|
16454
|
-
|
|
16455
|
-
|
|
16456
|
-
|
|
16457
|
-
|
|
16458
|
-
|
|
16459
|
-
|
|
16460
|
-
|
|
16461
|
-
|
|
16462
|
-
|
|
16463
|
-
|
|
16464
|
-
|
|
16465
|
-
|
|
16466
|
-
|
|
16467
|
-
|
|
16468
|
-
|
|
16469
|
-
|
|
16470
|
-
|
|
16471
|
-
|
|
16472
|
-
|
|
16457
|
+
const selectionSnapPoints = [];
|
|
16458
|
+
if (transformHandle) {
|
|
16459
|
+
switch (transformHandle) {
|
|
16460
|
+
case "e": {
|
|
16461
|
+
selectionSnapPoints.push(pointFrom18(maxX, minY), pointFrom18(maxX, maxY));
|
|
16462
|
+
break;
|
|
16463
|
+
}
|
|
16464
|
+
case "w": {
|
|
16465
|
+
selectionSnapPoints.push(pointFrom18(minX, minY), pointFrom18(minX, maxY));
|
|
16466
|
+
break;
|
|
16467
|
+
}
|
|
16468
|
+
case "n": {
|
|
16469
|
+
selectionSnapPoints.push(pointFrom18(minX, minY), pointFrom18(maxX, minY));
|
|
16470
|
+
break;
|
|
16471
|
+
}
|
|
16472
|
+
case "s": {
|
|
16473
|
+
selectionSnapPoints.push(pointFrom18(minX, maxY), pointFrom18(maxX, maxY));
|
|
16474
|
+
break;
|
|
16475
|
+
}
|
|
16476
|
+
case "ne": {
|
|
16477
|
+
selectionSnapPoints.push(pointFrom18(maxX, minY));
|
|
16478
|
+
break;
|
|
16479
|
+
}
|
|
16480
|
+
case "nw": {
|
|
16481
|
+
selectionSnapPoints.push(pointFrom18(minX, minY));
|
|
16482
|
+
break;
|
|
16483
|
+
}
|
|
16484
|
+
case "se": {
|
|
16485
|
+
selectionSnapPoints.push(pointFrom18(maxX, maxY));
|
|
16486
|
+
break;
|
|
16487
|
+
}
|
|
16488
|
+
case "sw": {
|
|
16489
|
+
selectionSnapPoints.push(pointFrom18(minX, maxY));
|
|
16490
|
+
break;
|
|
16491
|
+
}
|
|
16473
16492
|
}
|
|
16474
|
-
return true;
|
|
16475
|
-
}
|
|
16476
|
-
drawTrail(trail, state) {
|
|
16477
|
-
const _stroke = trail.getStrokeOutline(trail.options.size / state.zoom.value).map(([x, y]) => {
|
|
16478
|
-
const result = sceneCoordsToViewportCoords3(
|
|
16479
|
-
{ sceneX: x, sceneY: y },
|
|
16480
|
-
state
|
|
16481
|
-
);
|
|
16482
|
-
return [result.x, result.y];
|
|
16483
|
-
});
|
|
16484
|
-
const stroke = this.trailAnimation ? _stroke.slice(0, _stroke.length / 2) : _stroke;
|
|
16485
|
-
return getSvgPathFromStroke2(stroke, true);
|
|
16486
16493
|
}
|
|
16494
|
+
const snapDistance = getSnapDistance(app.state.zoom.value);
|
|
16495
|
+
const minOffset = {
|
|
16496
|
+
x: snapDistance,
|
|
16497
|
+
y: snapDistance
|
|
16498
|
+
};
|
|
16499
|
+
const nearestSnapsX = [];
|
|
16500
|
+
const nearestSnapsY = [];
|
|
16501
|
+
getPointSnaps(
|
|
16502
|
+
selectedOriginalElements,
|
|
16503
|
+
selectionSnapPoints,
|
|
16504
|
+
app,
|
|
16505
|
+
event,
|
|
16506
|
+
nearestSnapsX,
|
|
16507
|
+
nearestSnapsY,
|
|
16508
|
+
minOffset
|
|
16509
|
+
);
|
|
16510
|
+
const snapOffset = {
|
|
16511
|
+
x: nearestSnapsX[0]?.offset ?? 0,
|
|
16512
|
+
y: nearestSnapsY[0]?.offset ?? 0
|
|
16513
|
+
};
|
|
16514
|
+
minOffset.x = 0;
|
|
16515
|
+
minOffset.y = 0;
|
|
16516
|
+
nearestSnapsX.length = 0;
|
|
16517
|
+
nearestSnapsY.length = 0;
|
|
16518
|
+
const [x1, y1, x2, y2] = getCommonBounds5(selectedElements).map(
|
|
16519
|
+
(bound) => round(bound)
|
|
16520
|
+
);
|
|
16521
|
+
const corners = [
|
|
16522
|
+
pointFrom18(x1, y1),
|
|
16523
|
+
pointFrom18(x1, y2),
|
|
16524
|
+
pointFrom18(x2, y1),
|
|
16525
|
+
pointFrom18(x2, y2)
|
|
16526
|
+
];
|
|
16527
|
+
getPointSnaps(
|
|
16528
|
+
selectedElements,
|
|
16529
|
+
corners,
|
|
16530
|
+
app,
|
|
16531
|
+
event,
|
|
16532
|
+
nearestSnapsX,
|
|
16533
|
+
nearestSnapsY,
|
|
16534
|
+
minOffset
|
|
16535
|
+
);
|
|
16536
|
+
const pointSnapLines = createPointSnapLines(nearestSnapsX, nearestSnapsY);
|
|
16537
|
+
return {
|
|
16538
|
+
snapOffset,
|
|
16539
|
+
snapLines: pointSnapLines
|
|
16540
|
+
};
|
|
16487
16541
|
};
|
|
16488
|
-
|
|
16489
|
-
|
|
16490
|
-
|
|
16491
|
-
// laserTrails.ts
|
|
16492
|
-
var LaserTrails = class {
|
|
16493
|
-
constructor(app) {
|
|
16494
|
-
this.app = app;
|
|
16495
|
-
__publicField(this, "localTrail");
|
|
16496
|
-
__publicField(this, "collabTrails", /* @__PURE__ */ new Map());
|
|
16497
|
-
__publicField(this, "container");
|
|
16498
|
-
this.localTrail = new AnimatedTrail(app, {
|
|
16499
|
-
...this.getTrailOptions(),
|
|
16500
|
-
fill: () => DEFAULT_LASER_COLOR
|
|
16501
|
-
});
|
|
16502
|
-
}
|
|
16503
|
-
getTrailOptions() {
|
|
16542
|
+
var snapNewElement = (newElement7, app, event, origin, dragOffset, elementsMap) => {
|
|
16543
|
+
if (!isSnappingEnabled({ event, selectedElements: [newElement7], app })) {
|
|
16504
16544
|
return {
|
|
16505
|
-
|
|
16506
|
-
|
|
16507
|
-
sizeMapping: (c) => {
|
|
16508
|
-
const DECAY_TIME = 1e3;
|
|
16509
|
-
const DECAY_LENGTH = 50;
|
|
16510
|
-
const t2 = Math.max(
|
|
16511
|
-
0,
|
|
16512
|
-
1 - (performance.now() - c.pressure) / DECAY_TIME
|
|
16513
|
-
);
|
|
16514
|
-
const l = (DECAY_LENGTH - Math.min(DECAY_LENGTH, c.totalLength - c.currentIndex)) / DECAY_LENGTH;
|
|
16515
|
-
return Math.min(easeOut(l), easeOut(t2));
|
|
16516
|
-
}
|
|
16545
|
+
snapOffset: { x: 0, y: 0 },
|
|
16546
|
+
snapLines: []
|
|
16517
16547
|
};
|
|
16518
16548
|
}
|
|
16519
|
-
|
|
16520
|
-
|
|
16521
|
-
|
|
16522
|
-
|
|
16523
|
-
|
|
16524
|
-
|
|
16525
|
-
|
|
16526
|
-
|
|
16527
|
-
|
|
16528
|
-
|
|
16529
|
-
|
|
16530
|
-
|
|
16531
|
-
|
|
16532
|
-
|
|
16533
|
-
|
|
16534
|
-
|
|
16535
|
-
|
|
16536
|
-
|
|
16537
|
-
|
|
16538
|
-
|
|
16539
|
-
|
|
16540
|
-
|
|
16541
|
-
|
|
16542
|
-
|
|
16543
|
-
|
|
16544
|
-
|
|
16549
|
+
const selectionSnapPoints = [
|
|
16550
|
+
pointFrom18(origin.x + dragOffset.x, origin.y + dragOffset.y)
|
|
16551
|
+
];
|
|
16552
|
+
const snapDistance = getSnapDistance(app.state.zoom.value);
|
|
16553
|
+
const minOffset = {
|
|
16554
|
+
x: snapDistance,
|
|
16555
|
+
y: snapDistance
|
|
16556
|
+
};
|
|
16557
|
+
const nearestSnapsX = [];
|
|
16558
|
+
const nearestSnapsY = [];
|
|
16559
|
+
getPointSnaps(
|
|
16560
|
+
[newElement7],
|
|
16561
|
+
selectionSnapPoints,
|
|
16562
|
+
app,
|
|
16563
|
+
event,
|
|
16564
|
+
nearestSnapsX,
|
|
16565
|
+
nearestSnapsY,
|
|
16566
|
+
minOffset
|
|
16567
|
+
);
|
|
16568
|
+
const snapOffset = {
|
|
16569
|
+
x: nearestSnapsX[0]?.offset ?? 0,
|
|
16570
|
+
y: nearestSnapsY[0]?.offset ?? 0
|
|
16571
|
+
};
|
|
16572
|
+
minOffset.x = 0;
|
|
16573
|
+
minOffset.y = 0;
|
|
16574
|
+
nearestSnapsX.length = 0;
|
|
16575
|
+
nearestSnapsY.length = 0;
|
|
16576
|
+
const corners = getElementsCorners([newElement7], elementsMap, {
|
|
16577
|
+
boundingBoxCorners: true,
|
|
16578
|
+
omitCenter: true
|
|
16579
|
+
});
|
|
16580
|
+
getPointSnaps(
|
|
16581
|
+
[newElement7],
|
|
16582
|
+
corners,
|
|
16583
|
+
app,
|
|
16584
|
+
event,
|
|
16585
|
+
nearestSnapsX,
|
|
16586
|
+
nearestSnapsY,
|
|
16587
|
+
minOffset
|
|
16588
|
+
);
|
|
16589
|
+
const pointSnapLines = createPointSnapLines(nearestSnapsX, nearestSnapsY);
|
|
16590
|
+
return {
|
|
16591
|
+
snapOffset,
|
|
16592
|
+
snapLines: pointSnapLines
|
|
16593
|
+
};
|
|
16594
|
+
};
|
|
16595
|
+
var getSnapLinesAtPointer = (elements, app, pointer, event, elementsMap) => {
|
|
16596
|
+
if (!isSnappingEnabled({ event, selectedElements: [], app })) {
|
|
16597
|
+
return {
|
|
16598
|
+
originOffset: { x: 0, y: 0 },
|
|
16599
|
+
snapLines: []
|
|
16600
|
+
};
|
|
16545
16601
|
}
|
|
16546
|
-
|
|
16547
|
-
|
|
16548
|
-
|
|
16549
|
-
|
|
16550
|
-
|
|
16551
|
-
|
|
16552
|
-
|
|
16553
|
-
|
|
16554
|
-
|
|
16555
|
-
|
|
16556
|
-
|
|
16557
|
-
|
|
16558
|
-
|
|
16559
|
-
|
|
16602
|
+
const referenceElements = getVisibleAndNonSelectedElements(
|
|
16603
|
+
elements,
|
|
16604
|
+
[],
|
|
16605
|
+
app.state,
|
|
16606
|
+
elementsMap
|
|
16607
|
+
);
|
|
16608
|
+
const snapDistance = getSnapDistance(app.state.zoom.value);
|
|
16609
|
+
const minOffset = {
|
|
16610
|
+
x: snapDistance,
|
|
16611
|
+
y: snapDistance
|
|
16612
|
+
};
|
|
16613
|
+
const horizontalSnapLines = [];
|
|
16614
|
+
const verticalSnapLines = [];
|
|
16615
|
+
for (const referenceElement of referenceElements) {
|
|
16616
|
+
const corners = getElementsCorners([referenceElement], elementsMap);
|
|
16617
|
+
for (const corner of corners) {
|
|
16618
|
+
const offsetX = corner[0] - pointer.x;
|
|
16619
|
+
if (Math.abs(offsetX) <= Math.abs(minOffset.x)) {
|
|
16620
|
+
if (Math.abs(offsetX) < Math.abs(minOffset.x)) {
|
|
16621
|
+
verticalSnapLines.length = 0;
|
|
16622
|
+
}
|
|
16623
|
+
verticalSnapLines.push({
|
|
16624
|
+
type: "pointer",
|
|
16625
|
+
points: [corner, pointFrom18(corner[0], pointer.y)],
|
|
16626
|
+
direction: "vertical"
|
|
16560
16627
|
});
|
|
16561
|
-
|
|
16562
|
-
this.collabTrails.set(key, trail);
|
|
16628
|
+
minOffset.x = offsetX;
|
|
16563
16629
|
}
|
|
16564
|
-
|
|
16565
|
-
|
|
16566
|
-
|
|
16567
|
-
|
|
16568
|
-
if (buttonDown && !hasTrail) {
|
|
16569
|
-
trail.startPath(collaborator.pointer.x, collaborator.pointer.y);
|
|
16570
|
-
}
|
|
16571
|
-
const lastPointOriginal = !trail.hasLastPoint(
|
|
16572
|
-
collaborator.pointer.x,
|
|
16573
|
-
collaborator.pointer.y
|
|
16574
|
-
);
|
|
16575
|
-
if (buttonDown && lastPointOriginal) {
|
|
16576
|
-
trail.addPointToPath(collaborator.pointer.x, collaborator.pointer.y);
|
|
16577
|
-
}
|
|
16578
|
-
if (buttonUp && hasTrail) {
|
|
16579
|
-
trail.addPointToPath(collaborator.pointer.x, collaborator.pointer.y);
|
|
16580
|
-
trail.endPath();
|
|
16630
|
+
const offsetY = corner[1] - pointer.y;
|
|
16631
|
+
if (Math.abs(offsetY) <= Math.abs(minOffset.y)) {
|
|
16632
|
+
if (Math.abs(offsetY) < Math.abs(minOffset.y)) {
|
|
16633
|
+
horizontalSnapLines.length = 0;
|
|
16581
16634
|
}
|
|
16635
|
+
horizontalSnapLines.push({
|
|
16636
|
+
type: "pointer",
|
|
16637
|
+
points: [corner, pointFrom18(pointer.x, corner[1])],
|
|
16638
|
+
direction: "horizontal"
|
|
16639
|
+
});
|
|
16640
|
+
minOffset.y = offsetY;
|
|
16582
16641
|
}
|
|
16583
16642
|
}
|
|
16584
16643
|
}
|
|
16644
|
+
return {
|
|
16645
|
+
originOffset: {
|
|
16646
|
+
x: verticalSnapLines.length > 0 ? verticalSnapLines[0].points[0][0] - pointer.x : 0,
|
|
16647
|
+
y: horizontalSnapLines.length > 0 ? horizontalSnapLines[0].points[0][1] - pointer.y : 0
|
|
16648
|
+
},
|
|
16649
|
+
snapLines: [...verticalSnapLines, ...horizontalSnapLines]
|
|
16650
|
+
};
|
|
16651
|
+
};
|
|
16652
|
+
var isActiveToolNonLinearSnappable = (activeToolType) => {
|
|
16653
|
+
return activeToolType === TOOL_TYPE.rectangle || activeToolType === TOOL_TYPE.ellipse || activeToolType === TOOL_TYPE.diamond || activeToolType === TOOL_TYPE.frame || activeToolType === TOOL_TYPE.magicframe || activeToolType === TOOL_TYPE.image || activeToolType === TOOL_TYPE.text;
|
|
16585
16654
|
};
|
|
16586
16655
|
|
|
16587
16656
|
// textAutoResizeHandle.ts
|
|
@@ -17359,75 +17428,6 @@ var textWysiwyg = ({
|
|
|
17359
17428
|
return handleSubmit;
|
|
17360
17429
|
};
|
|
17361
17430
|
|
|
17362
|
-
// scene/scrollbars.ts
|
|
17363
|
-
import { getGlobalCSSVariable } from "@excalidraw/common";
|
|
17364
|
-
import { getCommonBounds as getCommonBounds5 } from "@excalidraw/element";
|
|
17365
|
-
var SCROLLBAR_MARGIN = 4;
|
|
17366
|
-
var SCROLLBAR_WIDTH = 6;
|
|
17367
|
-
var SCROLLBAR_COLOR = "rgba(0,0,0,0.3)";
|
|
17368
|
-
var getScrollBars = (elements, viewportWidth, viewportHeight, appState) => {
|
|
17369
|
-
if (!elements.size) {
|
|
17370
|
-
return {
|
|
17371
|
-
horizontal: null,
|
|
17372
|
-
vertical: null
|
|
17373
|
-
};
|
|
17374
|
-
}
|
|
17375
|
-
const [elementsMinX, elementsMinY, elementsMaxX, elementsMaxY] = getCommonBounds5(elements);
|
|
17376
|
-
const viewportWidthWithZoom = viewportWidth / appState.zoom.value;
|
|
17377
|
-
const viewportHeightWithZoom = viewportHeight / appState.zoom.value;
|
|
17378
|
-
const safeArea = {
|
|
17379
|
-
top: parseInt(getGlobalCSSVariable("sat")) || 0,
|
|
17380
|
-
bottom: parseInt(getGlobalCSSVariable("sab")) || 0,
|
|
17381
|
-
left: parseInt(getGlobalCSSVariable("sal")) || 0,
|
|
17382
|
-
right: parseInt(getGlobalCSSVariable("sar")) || 0
|
|
17383
|
-
};
|
|
17384
|
-
const isRTL3 = getLanguage().rtl;
|
|
17385
|
-
const viewportMinX = -appState.scrollX + safeArea.left;
|
|
17386
|
-
const viewportMinY = -appState.scrollY + safeArea.top;
|
|
17387
|
-
const viewportMaxX = viewportMinX + viewportWidthWithZoom - safeArea.right;
|
|
17388
|
-
const viewportMaxY = viewportMinY + viewportHeightWithZoom - safeArea.bottom;
|
|
17389
|
-
const sceneMinX = Math.min(elementsMinX, viewportMinX);
|
|
17390
|
-
const sceneMinY = Math.min(elementsMinY, viewportMinY);
|
|
17391
|
-
const sceneMaxX = Math.max(elementsMaxX, viewportMaxX);
|
|
17392
|
-
const sceneMaxY = Math.max(elementsMaxY, viewportMaxY);
|
|
17393
|
-
const sceneWidth = elementsMaxX - elementsMinX;
|
|
17394
|
-
const sceneHeight = elementsMaxY - elementsMinY;
|
|
17395
|
-
const extendedSceneWidth = sceneMaxX - sceneMinX;
|
|
17396
|
-
const extendedSceneHeight = sceneMaxY - sceneMinY;
|
|
17397
|
-
const scrollWidthOffset = Math.max(SCROLLBAR_MARGIN * 2, safeArea.left + safeArea.right) + SCROLLBAR_WIDTH * 2;
|
|
17398
|
-
const scrollbarWidth = viewportWidth * (viewportWidthWithZoom / extendedSceneWidth) - scrollWidthOffset;
|
|
17399
|
-
const scrollbarHeightOffset = Math.max(SCROLLBAR_MARGIN * 2, safeArea.top + safeArea.bottom) + SCROLLBAR_WIDTH * 2;
|
|
17400
|
-
const scrollbarHeight = viewportHeight * (viewportHeightWithZoom / extendedSceneHeight) - scrollbarHeightOffset;
|
|
17401
|
-
const horizontalDeltaMultiplier = extendedSceneWidth > sceneWidth ? extendedSceneWidth * appState.zoom.value / (scrollbarWidth + scrollWidthOffset) : viewportWidth / (scrollbarWidth + scrollWidthOffset);
|
|
17402
|
-
const verticalDeltaMultiplier = extendedSceneHeight > sceneHeight ? extendedSceneHeight * appState.zoom.value / (scrollbarHeight + scrollbarHeightOffset) : viewportHeight / (scrollbarHeight + scrollbarHeightOffset);
|
|
17403
|
-
return {
|
|
17404
|
-
horizontal: viewportMinX === sceneMinX && viewportMaxX === sceneMaxX ? null : {
|
|
17405
|
-
x: Math.max(safeArea.left, SCROLLBAR_MARGIN) + SCROLLBAR_WIDTH + (viewportMinX - sceneMinX) / extendedSceneWidth * viewportWidth,
|
|
17406
|
-
y: viewportHeight - SCROLLBAR_WIDTH - Math.max(SCROLLBAR_MARGIN, safeArea.bottom),
|
|
17407
|
-
width: scrollbarWidth,
|
|
17408
|
-
height: SCROLLBAR_WIDTH,
|
|
17409
|
-
deltaMultiplier: horizontalDeltaMultiplier
|
|
17410
|
-
},
|
|
17411
|
-
vertical: viewportMinY === sceneMinY && viewportMaxY === sceneMaxY ? null : {
|
|
17412
|
-
x: isRTL3 ? Math.max(safeArea.left, SCROLLBAR_MARGIN) : viewportWidth - SCROLLBAR_WIDTH - Math.max(safeArea.right, SCROLLBAR_MARGIN),
|
|
17413
|
-
y: Math.max(safeArea.top, SCROLLBAR_MARGIN) + SCROLLBAR_WIDTH + (viewportMinY - sceneMinY) / extendedSceneHeight * viewportHeight,
|
|
17414
|
-
width: SCROLLBAR_WIDTH,
|
|
17415
|
-
height: scrollbarHeight,
|
|
17416
|
-
deltaMultiplier: verticalDeltaMultiplier
|
|
17417
|
-
}
|
|
17418
|
-
};
|
|
17419
|
-
};
|
|
17420
|
-
var isOverScrollBars = (scrollBars, x, y) => {
|
|
17421
|
-
const [isOverHorizontal, isOverVertical] = [
|
|
17422
|
-
scrollBars.horizontal,
|
|
17423
|
-
scrollBars.vertical
|
|
17424
|
-
].map((scrollBar) => {
|
|
17425
|
-
return scrollBar != null && scrollBar.x <= x && x <= scrollBar.x + scrollBar.width && scrollBar.y <= y && y <= scrollBar.y + scrollBar.height;
|
|
17426
|
-
});
|
|
17427
|
-
const isOverEither = isOverHorizontal || isOverVertical;
|
|
17428
|
-
return { isOverEither, isOverHorizontal, isOverVertical };
|
|
17429
|
-
};
|
|
17430
|
-
|
|
17431
17431
|
// lasso/index.ts
|
|
17432
17432
|
import {
|
|
17433
17433
|
pointFrom as pointFrom21
|
|
@@ -19586,6 +19586,122 @@ var getConvertibleType = (element) => {
|
|
|
19586
19586
|
};
|
|
19587
19587
|
var ConvertElementTypePopup_default = ConvertElementTypePopup;
|
|
19588
19588
|
|
|
19589
|
+
// components/AppStateObserver.ts
|
|
19590
|
+
var AppStateObserver = class {
|
|
19591
|
+
constructor(getState) {
|
|
19592
|
+
this.getState = getState;
|
|
19593
|
+
__publicField(this, "listeners", []);
|
|
19594
|
+
__publicField(this, "onStateChange", (propOrOpts, callback, opts) => {
|
|
19595
|
+
const {
|
|
19596
|
+
predicate,
|
|
19597
|
+
getValue,
|
|
19598
|
+
callback: stateChangeCallback,
|
|
19599
|
+
once,
|
|
19600
|
+
matchesImmediately
|
|
19601
|
+
} = this.normalize(propOrOpts, callback, opts);
|
|
19602
|
+
if (stateChangeCallback) {
|
|
19603
|
+
if (matchesImmediately) {
|
|
19604
|
+
queueMicrotask(() => {
|
|
19605
|
+
const state = this.getState();
|
|
19606
|
+
stateChangeCallback(getValue(state), state);
|
|
19607
|
+
});
|
|
19608
|
+
if (once) {
|
|
19609
|
+
return () => {
|
|
19610
|
+
};
|
|
19611
|
+
}
|
|
19612
|
+
}
|
|
19613
|
+
return this.subscribe({
|
|
19614
|
+
predicate,
|
|
19615
|
+
getValue,
|
|
19616
|
+
callback: stateChangeCallback,
|
|
19617
|
+
once
|
|
19618
|
+
});
|
|
19619
|
+
}
|
|
19620
|
+
if (matchesImmediately) {
|
|
19621
|
+
return Promise.resolve(getValue(this.getState()));
|
|
19622
|
+
}
|
|
19623
|
+
return new Promise((resolve) => {
|
|
19624
|
+
this.subscribe({
|
|
19625
|
+
predicate,
|
|
19626
|
+
getValue,
|
|
19627
|
+
callback: (value) => resolve(value),
|
|
19628
|
+
once: true
|
|
19629
|
+
});
|
|
19630
|
+
});
|
|
19631
|
+
});
|
|
19632
|
+
}
|
|
19633
|
+
isStateChangePredicateOptions(propOrOpts) {
|
|
19634
|
+
return typeof propOrOpts === "object" && !Array.isArray(propOrOpts) && "predicate" in propOrOpts;
|
|
19635
|
+
}
|
|
19636
|
+
subscribe(listener) {
|
|
19637
|
+
this.listeners.push(listener);
|
|
19638
|
+
return () => {
|
|
19639
|
+
this.listeners = this.listeners.filter(
|
|
19640
|
+
(existingListener) => existingListener !== listener
|
|
19641
|
+
);
|
|
19642
|
+
};
|
|
19643
|
+
}
|
|
19644
|
+
normalize(propOrOpts, callback, opts) {
|
|
19645
|
+
let predicate;
|
|
19646
|
+
let getValue;
|
|
19647
|
+
let normalizedCallback = callback;
|
|
19648
|
+
let once = opts?.once ?? false;
|
|
19649
|
+
let matchesImmediately = false;
|
|
19650
|
+
if (this.isStateChangePredicateOptions(propOrOpts)) {
|
|
19651
|
+
const {
|
|
19652
|
+
predicate: predicateFn,
|
|
19653
|
+
callback: callbackFromOpts,
|
|
19654
|
+
once: onceFromOpts
|
|
19655
|
+
} = propOrOpts;
|
|
19656
|
+
predicate = predicateFn;
|
|
19657
|
+
getValue = (appState) => appState;
|
|
19658
|
+
normalizedCallback = callbackFromOpts ? (_value, appState) => callbackFromOpts(appState) : void 0;
|
|
19659
|
+
once = onceFromOpts ?? false;
|
|
19660
|
+
matchesImmediately = predicateFn(this.getState());
|
|
19661
|
+
} else if (typeof propOrOpts === "function") {
|
|
19662
|
+
const selector = propOrOpts;
|
|
19663
|
+
predicate = (appState, prevState) => selector(appState) !== selector(prevState);
|
|
19664
|
+
getValue = (appState) => selector(appState);
|
|
19665
|
+
} else if (Array.isArray(propOrOpts)) {
|
|
19666
|
+
const keys = propOrOpts;
|
|
19667
|
+
predicate = (appState, prevState) => keys.some((key) => appState[key] !== prevState[key]);
|
|
19668
|
+
getValue = (appState) => appState;
|
|
19669
|
+
} else {
|
|
19670
|
+
const key = propOrOpts;
|
|
19671
|
+
predicate = (appState, prevState) => appState[key] !== prevState[key];
|
|
19672
|
+
getValue = (appState) => appState[key];
|
|
19673
|
+
}
|
|
19674
|
+
return {
|
|
19675
|
+
predicate,
|
|
19676
|
+
getValue,
|
|
19677
|
+
callback: normalizedCallback,
|
|
19678
|
+
once,
|
|
19679
|
+
matchesImmediately
|
|
19680
|
+
};
|
|
19681
|
+
}
|
|
19682
|
+
flush(prevState) {
|
|
19683
|
+
if (!this.listeners.length) {
|
|
19684
|
+
return;
|
|
19685
|
+
}
|
|
19686
|
+
const state = this.getState();
|
|
19687
|
+
const listenersToKeep = [];
|
|
19688
|
+
for (const listener of this.listeners) {
|
|
19689
|
+
if (listener.predicate(state, prevState)) {
|
|
19690
|
+
listener.callback(listener.getValue(state), state);
|
|
19691
|
+
if (!listener.once) {
|
|
19692
|
+
listenersToKeep.push(listener);
|
|
19693
|
+
}
|
|
19694
|
+
} else {
|
|
19695
|
+
listenersToKeep.push(listener);
|
|
19696
|
+
}
|
|
19697
|
+
}
|
|
19698
|
+
this.listeners = listenersToKeep;
|
|
19699
|
+
}
|
|
19700
|
+
clear() {
|
|
19701
|
+
this.listeners = [];
|
|
19702
|
+
}
|
|
19703
|
+
};
|
|
19704
|
+
|
|
19589
19705
|
// components/Trans.tsx
|
|
19590
19706
|
import React17 from "react";
|
|
19591
19707
|
var SPLIT_REGEX = /({{[\w-]+}})|(<[\w-]+>)|(<\/[\w-]+>)/g;
|
|
@@ -31384,122 +31500,6 @@ var NewElementCanvas = (props) => {
|
|
|
31384
31500
|
};
|
|
31385
31501
|
var NewElementCanvas_default = NewElementCanvas;
|
|
31386
31502
|
|
|
31387
|
-
// components/AppStateObserver.ts
|
|
31388
|
-
var AppStateObserver = class {
|
|
31389
|
-
constructor(getState) {
|
|
31390
|
-
this.getState = getState;
|
|
31391
|
-
__publicField(this, "listeners", []);
|
|
31392
|
-
__publicField(this, "onStateChange", (propOrOpts, callback, opts) => {
|
|
31393
|
-
const {
|
|
31394
|
-
predicate,
|
|
31395
|
-
getValue,
|
|
31396
|
-
callback: stateChangeCallback,
|
|
31397
|
-
once,
|
|
31398
|
-
matchesImmediately
|
|
31399
|
-
} = this.normalize(propOrOpts, callback, opts);
|
|
31400
|
-
if (stateChangeCallback) {
|
|
31401
|
-
if (matchesImmediately) {
|
|
31402
|
-
queueMicrotask(() => {
|
|
31403
|
-
const state = this.getState();
|
|
31404
|
-
stateChangeCallback(getValue(state), state);
|
|
31405
|
-
});
|
|
31406
|
-
if (once) {
|
|
31407
|
-
return () => {
|
|
31408
|
-
};
|
|
31409
|
-
}
|
|
31410
|
-
}
|
|
31411
|
-
return this.subscribe({
|
|
31412
|
-
predicate,
|
|
31413
|
-
getValue,
|
|
31414
|
-
callback: stateChangeCallback,
|
|
31415
|
-
once
|
|
31416
|
-
});
|
|
31417
|
-
}
|
|
31418
|
-
if (matchesImmediately) {
|
|
31419
|
-
return Promise.resolve(getValue(this.getState()));
|
|
31420
|
-
}
|
|
31421
|
-
return new Promise((resolve) => {
|
|
31422
|
-
this.subscribe({
|
|
31423
|
-
predicate,
|
|
31424
|
-
getValue,
|
|
31425
|
-
callback: (value) => resolve(value),
|
|
31426
|
-
once: true
|
|
31427
|
-
});
|
|
31428
|
-
});
|
|
31429
|
-
});
|
|
31430
|
-
}
|
|
31431
|
-
isStateChangePredicateOptions(propOrOpts) {
|
|
31432
|
-
return typeof propOrOpts === "object" && !Array.isArray(propOrOpts) && "predicate" in propOrOpts;
|
|
31433
|
-
}
|
|
31434
|
-
subscribe(listener) {
|
|
31435
|
-
this.listeners.push(listener);
|
|
31436
|
-
return () => {
|
|
31437
|
-
this.listeners = this.listeners.filter(
|
|
31438
|
-
(existingListener) => existingListener !== listener
|
|
31439
|
-
);
|
|
31440
|
-
};
|
|
31441
|
-
}
|
|
31442
|
-
normalize(propOrOpts, callback, opts) {
|
|
31443
|
-
let predicate;
|
|
31444
|
-
let getValue;
|
|
31445
|
-
let normalizedCallback = callback;
|
|
31446
|
-
let once = opts?.once ?? false;
|
|
31447
|
-
let matchesImmediately = false;
|
|
31448
|
-
if (this.isStateChangePredicateOptions(propOrOpts)) {
|
|
31449
|
-
const {
|
|
31450
|
-
predicate: predicateFn,
|
|
31451
|
-
callback: callbackFromOpts,
|
|
31452
|
-
once: onceFromOpts
|
|
31453
|
-
} = propOrOpts;
|
|
31454
|
-
predicate = predicateFn;
|
|
31455
|
-
getValue = (appState) => appState;
|
|
31456
|
-
normalizedCallback = callbackFromOpts ? (_value, appState) => callbackFromOpts(appState) : void 0;
|
|
31457
|
-
once = onceFromOpts ?? false;
|
|
31458
|
-
matchesImmediately = predicateFn(this.getState());
|
|
31459
|
-
} else if (typeof propOrOpts === "function") {
|
|
31460
|
-
const selector = propOrOpts;
|
|
31461
|
-
predicate = (appState, prevState) => selector(appState) !== selector(prevState);
|
|
31462
|
-
getValue = (appState) => selector(appState);
|
|
31463
|
-
} else if (Array.isArray(propOrOpts)) {
|
|
31464
|
-
const keys = propOrOpts;
|
|
31465
|
-
predicate = (appState, prevState) => keys.some((key) => appState[key] !== prevState[key]);
|
|
31466
|
-
getValue = (appState) => appState;
|
|
31467
|
-
} else {
|
|
31468
|
-
const key = propOrOpts;
|
|
31469
|
-
predicate = (appState, prevState) => appState[key] !== prevState[key];
|
|
31470
|
-
getValue = (appState) => appState[key];
|
|
31471
|
-
}
|
|
31472
|
-
return {
|
|
31473
|
-
predicate,
|
|
31474
|
-
getValue,
|
|
31475
|
-
callback: normalizedCallback,
|
|
31476
|
-
once,
|
|
31477
|
-
matchesImmediately
|
|
31478
|
-
};
|
|
31479
|
-
}
|
|
31480
|
-
flush(prevState) {
|
|
31481
|
-
if (!this.listeners.length) {
|
|
31482
|
-
return;
|
|
31483
|
-
}
|
|
31484
|
-
const state = this.getState();
|
|
31485
|
-
const listenersToKeep = [];
|
|
31486
|
-
for (const listener of this.listeners) {
|
|
31487
|
-
if (listener.predicate(state, prevState)) {
|
|
31488
|
-
listener.callback(listener.getValue(state), state);
|
|
31489
|
-
if (!listener.once) {
|
|
31490
|
-
listenersToKeep.push(listener);
|
|
31491
|
-
}
|
|
31492
|
-
} else {
|
|
31493
|
-
listenersToKeep.push(listener);
|
|
31494
|
-
}
|
|
31495
|
-
}
|
|
31496
|
-
this.listeners = listenersToKeep;
|
|
31497
|
-
}
|
|
31498
|
-
clear() {
|
|
31499
|
-
this.listeners = [];
|
|
31500
|
-
}
|
|
31501
|
-
};
|
|
31502
|
-
|
|
31503
31503
|
// components/UnlockPopup.tsx
|
|
31504
31504
|
import {
|
|
31505
31505
|
getCommonBounds as getCommonBounds10,
|
|
@@ -31709,8 +31709,8 @@ var App = class _App extends React40.Component {
|
|
|
31709
31709
|
__publicField(this, "missingPointerEventCleanupEmitter", new Emitter2());
|
|
31710
31710
|
__publicField(this, "onRemoveEventListenersEmitter", new Emitter2());
|
|
31711
31711
|
__publicField(this, "api");
|
|
31712
|
-
__publicField(this, "addImageElementsToScene", async (imageFiles, sceneX, sceneY) => {
|
|
31713
|
-
await this.insertImages(imageFiles, sceneX, sceneY);
|
|
31712
|
+
__publicField(this, "addImageElementsToScene", async (imageFiles, sceneX, sceneY, options) => {
|
|
31713
|
+
await this.insertImages(imageFiles, sceneX, sceneY, options);
|
|
31714
31714
|
});
|
|
31715
31715
|
__publicField(this, "updateEditorAtom", (atom2, ...args) => {
|
|
31716
31716
|
const result = editorJotaiStore.set(atom2, ...args);
|
|
@@ -36238,7 +36238,8 @@ var App = class _App extends React40.Component {
|
|
|
36238
36238
|
);
|
|
36239
36239
|
}
|
|
36240
36240
|
});
|
|
36241
|
-
__publicField(this, "insertImages", async (imageFiles, sceneX, sceneY) => {
|
|
36241
|
+
__publicField(this, "insertImages", async (imageFiles, sceneX, sceneY, options) => {
|
|
36242
|
+
const waitFor = options?.waitFor ?? "inserted";
|
|
36242
36243
|
const gridPadding = 50 / this.state.zoom.value;
|
|
36243
36244
|
const placeholders = positionElementsOnGrid(
|
|
36244
36245
|
imageFiles.map(() => this.newImagePlaceholder({ sceneX, sceneY })),
|
|
@@ -36281,8 +36282,17 @@ var App = class _App extends React40.Component {
|
|
|
36281
36282
|
elements: nextElements,
|
|
36282
36283
|
captureUpdate: CaptureUpdateAction41.IMMEDIATELY
|
|
36283
36284
|
});
|
|
36284
|
-
|
|
36285
|
-
this.
|
|
36285
|
+
await new Promise((resolve) => {
|
|
36286
|
+
this.setState({}, () => {
|
|
36287
|
+
this.actionManager.executeAction(actionFinalize);
|
|
36288
|
+
if (waitFor === "painted") {
|
|
36289
|
+
requestAnimationFrame(() => {
|
|
36290
|
+
requestAnimationFrame(() => resolve());
|
|
36291
|
+
});
|
|
36292
|
+
return;
|
|
36293
|
+
}
|
|
36294
|
+
resolve();
|
|
36295
|
+
});
|
|
36286
36296
|
});
|
|
36287
36297
|
});
|
|
36288
36298
|
__publicField(this, "handleAppOnDrop", async (event) => {
|