canvu-react 0.4.62 → 0.4.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chatbot.d.cts +1 -1
- package/dist/chatbot.d.ts +1 -1
- package/dist/react.cjs +510 -79
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +91 -4
- package/dist/react.d.ts +91 -4
- package/dist/react.js +510 -79
- package/dist/react.js.map +1 -1
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.d.cts +1 -1
- package/dist/realtime.d.ts +1 -1
- package/dist/realtime.js.map +1 -1
- package/dist/{types--jCoyZIF.d.cts → types-Ce4-OZbd.d.cts} +127 -1
- package/dist/{types-C_PMen-D.d.ts → types-PsLgDGZT.d.ts} +127 -1
- package/package.json +1 -1
package/dist/react.cjs
CHANGED
|
@@ -2119,7 +2119,7 @@ var collapseButtonStyle = {
|
|
|
2119
2119
|
cursor: "pointer",
|
|
2120
2120
|
padding: 0
|
|
2121
2121
|
};
|
|
2122
|
-
var
|
|
2122
|
+
var defaultCollapsedButtonStyle = {
|
|
2123
2123
|
display: "inline-flex",
|
|
2124
2124
|
alignItems: "center",
|
|
2125
2125
|
justifyContent: "center",
|
|
@@ -2148,7 +2148,10 @@ function ImagesMenu({
|
|
|
2148
2148
|
onItemsChange,
|
|
2149
2149
|
onFocusItem,
|
|
2150
2150
|
labels,
|
|
2151
|
-
defaultOpen = false
|
|
2151
|
+
defaultOpen = false,
|
|
2152
|
+
collapsedButtonClassName,
|
|
2153
|
+
collapsedButtonStyle,
|
|
2154
|
+
renderCollapsedButton
|
|
2152
2155
|
}) {
|
|
2153
2156
|
const managed = react.useMemo(() => items.filter(isManagedImage), [items]);
|
|
2154
2157
|
const sensors = core.useSensors(
|
|
@@ -2169,18 +2172,26 @@ function ImagesMenu({
|
|
|
2169
2172
|
duplicate: labels?.duplicate ?? labels?.copy ?? defaultLabels.duplicate
|
|
2170
2173
|
};
|
|
2171
2174
|
if (collapsed) {
|
|
2172
|
-
|
|
2173
|
-
"button",
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2175
|
+
const buttonProps = {
|
|
2176
|
+
type: "button",
|
|
2177
|
+
"data-slot": "images-menu-collapsed",
|
|
2178
|
+
className: collapsedButtonClassName,
|
|
2179
|
+
style: {
|
|
2180
|
+
...defaultCollapsedButtonStyle,
|
|
2181
|
+
...collapsedButtonStyle ?? {}
|
|
2182
|
+
},
|
|
2183
|
+
"aria-label": resolvedLabels.expand,
|
|
2184
|
+
title: resolvedLabels.expand,
|
|
2185
|
+
onClick: () => setCollapsed(false)
|
|
2186
|
+
};
|
|
2187
|
+
if (renderCollapsedButton) {
|
|
2188
|
+
return renderCollapsedButton({
|
|
2189
|
+
count: managed.length,
|
|
2190
|
+
label: resolvedLabels.expand,
|
|
2191
|
+
buttonProps
|
|
2192
|
+
});
|
|
2193
|
+
}
|
|
2194
|
+
return /* @__PURE__ */ jsxRuntime.jsx("button", { ...buttonProps, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Images, { size: 20 }) });
|
|
2184
2195
|
}
|
|
2185
2196
|
const onDragEnd = (event) => {
|
|
2186
2197
|
const { active, over } = event;
|
|
@@ -3142,7 +3153,9 @@ function ToolPluginComponent({
|
|
|
3142
3153
|
toolTransform,
|
|
3143
3154
|
createItem,
|
|
3144
3155
|
selectAfterCreate,
|
|
3145
|
-
onSelectModeItemClick
|
|
3156
|
+
onSelectModeItemClick,
|
|
3157
|
+
onBeforeInteraction,
|
|
3158
|
+
onAfterInteraction
|
|
3146
3159
|
}) {
|
|
3147
3160
|
const contribution = react.useMemo(
|
|
3148
3161
|
() => ({
|
|
@@ -3155,9 +3168,27 @@ function ToolPluginComponent({
|
|
|
3155
3168
|
selectAfterCreate,
|
|
3156
3169
|
onSelectModeItemClick
|
|
3157
3170
|
}
|
|
3158
|
-
] : void 0
|
|
3171
|
+
] : void 0,
|
|
3172
|
+
interactionHooks: onBeforeInteraction || onAfterInteraction ? {
|
|
3173
|
+
onBeforeInteraction: onBeforeInteraction ? (detail) => {
|
|
3174
|
+
if (detail.toolId !== tool.id) return void 0;
|
|
3175
|
+
return onBeforeInteraction(detail);
|
|
3176
|
+
} : void 0,
|
|
3177
|
+
onAfterInteraction: onAfterInteraction ? (detail) => {
|
|
3178
|
+
if (detail.toolId !== tool.id) return;
|
|
3179
|
+
onAfterInteraction(detail);
|
|
3180
|
+
} : void 0
|
|
3181
|
+
} : void 0
|
|
3159
3182
|
}),
|
|
3160
|
-
[
|
|
3183
|
+
[
|
|
3184
|
+
createItem,
|
|
3185
|
+
onAfterInteraction,
|
|
3186
|
+
onBeforeInteraction,
|
|
3187
|
+
onSelectModeItemClick,
|
|
3188
|
+
selectAfterCreate,
|
|
3189
|
+
tool,
|
|
3190
|
+
toolTransform
|
|
3191
|
+
]
|
|
3161
3192
|
);
|
|
3162
3193
|
useCanvuPluginContribution(pluginId, contribution);
|
|
3163
3194
|
return null;
|
|
@@ -3168,6 +3199,8 @@ function createToolPlugin(options) {
|
|
|
3168
3199
|
toolTransform,
|
|
3169
3200
|
selectAfterCreate,
|
|
3170
3201
|
onSelectModeItemClick,
|
|
3202
|
+
onBeforeInteraction,
|
|
3203
|
+
onAfterInteraction,
|
|
3171
3204
|
...tool
|
|
3172
3205
|
} = options;
|
|
3173
3206
|
const pluginId = `canvu.plugin.tool:${tool.id}`;
|
|
@@ -3182,7 +3215,9 @@ function createToolPlugin(options) {
|
|
|
3182
3215
|
toolTransform,
|
|
3183
3216
|
createItem,
|
|
3184
3217
|
selectAfterCreate,
|
|
3185
|
-
onSelectModeItemClick
|
|
3218
|
+
onSelectModeItemClick,
|
|
3219
|
+
onBeforeInteraction,
|
|
3220
|
+
onAfterInteraction
|
|
3186
3221
|
}
|
|
3187
3222
|
);
|
|
3188
3223
|
}
|
|
@@ -8132,6 +8167,8 @@ var VectorViewport = react.forwardRef(
|
|
|
8132
8167
|
selectedIds: selectedIdsProp,
|
|
8133
8168
|
onSelectionChange,
|
|
8134
8169
|
onItemsChange: consumerOnItemsChange,
|
|
8170
|
+
onBeforeInteraction: consumerOnBeforeInteraction,
|
|
8171
|
+
onAfterInteraction: consumerOnAfterInteraction,
|
|
8135
8172
|
onActivateLink,
|
|
8136
8173
|
onWorldPointerDown: consumerOnWorldPointerDown,
|
|
8137
8174
|
toolbar,
|
|
@@ -8257,6 +8294,24 @@ var VectorViewport = react.forwardRef(
|
|
|
8257
8294
|
(contribution) => contribution.callbacks?.onCameraChange
|
|
8258
8295
|
)
|
|
8259
8296
|
);
|
|
8297
|
+
const beforeInteractionHooks = react.useMemo(
|
|
8298
|
+
() => [
|
|
8299
|
+
consumerOnBeforeInteraction,
|
|
8300
|
+
...orderedPluginContributions.map(
|
|
8301
|
+
(contribution) => contribution.interactionHooks?.onBeforeInteraction
|
|
8302
|
+
)
|
|
8303
|
+
].filter((hook) => hook != null),
|
|
8304
|
+
[consumerOnBeforeInteraction, orderedPluginContributions]
|
|
8305
|
+
);
|
|
8306
|
+
const afterInteractionHooks = react.useMemo(
|
|
8307
|
+
() => [
|
|
8308
|
+
consumerOnAfterInteraction,
|
|
8309
|
+
...orderedPluginContributions.map(
|
|
8310
|
+
(contribution) => contribution.interactionHooks?.onAfterInteraction
|
|
8311
|
+
)
|
|
8312
|
+
].filter((hook) => hook != null),
|
|
8313
|
+
[consumerOnAfterInteraction, orderedPluginContributions]
|
|
8314
|
+
);
|
|
8260
8315
|
const onItemsChange = react.useMemo(() => {
|
|
8261
8316
|
const middlewares = orderedPluginContributions.map((contribution) => contribution.wrapOnItemsChange).filter(
|
|
8262
8317
|
(middleware) => middleware != null
|
|
@@ -8400,6 +8455,81 @@ var VectorViewport = react.forwardRef(
|
|
|
8400
8455
|
[items]
|
|
8401
8456
|
);
|
|
8402
8457
|
itemsRef.current = normalizedItems;
|
|
8458
|
+
const beforeInteractionHooksRef = react.useRef(beforeInteractionHooks);
|
|
8459
|
+
beforeInteractionHooksRef.current = beforeInteractionHooks;
|
|
8460
|
+
const afterInteractionHooksRef = react.useRef(afterInteractionHooks);
|
|
8461
|
+
afterInteractionHooksRef.current = afterInteractionHooks;
|
|
8462
|
+
const canvuInteractionSeqRef = react.useRef(0);
|
|
8463
|
+
const activeCanvuInteractionRef = react.useRef(null);
|
|
8464
|
+
const makeInteractionPoint = react.useCallback(
|
|
8465
|
+
(input) => ({
|
|
8466
|
+
worldX: input.worldX,
|
|
8467
|
+
worldY: input.worldY,
|
|
8468
|
+
clientX: input.clientX,
|
|
8469
|
+
clientY: input.clientY
|
|
8470
|
+
}),
|
|
8471
|
+
[]
|
|
8472
|
+
);
|
|
8473
|
+
const startCanvuInteraction = react.useCallback(
|
|
8474
|
+
(input) => {
|
|
8475
|
+
const start = makeInteractionPoint(input);
|
|
8476
|
+
const detail = {
|
|
8477
|
+
interactionId: `canvu-interaction-${++canvuInteractionSeqRef.current}`,
|
|
8478
|
+
kind: input.kind,
|
|
8479
|
+
toolId: input.toolId,
|
|
8480
|
+
pointerType: input.pointerType,
|
|
8481
|
+
button: input.button,
|
|
8482
|
+
shiftKey: input.shiftKey,
|
|
8483
|
+
altKey: input.altKey,
|
|
8484
|
+
metaKey: input.metaKey,
|
|
8485
|
+
ctrlKey: input.ctrlKey,
|
|
8486
|
+
start,
|
|
8487
|
+
current: start,
|
|
8488
|
+
selectedIds: [...effectiveSelectedIdsRef.current],
|
|
8489
|
+
itemIds: [...input.itemIds ?? []],
|
|
8490
|
+
items: itemsRef.current
|
|
8491
|
+
};
|
|
8492
|
+
for (const hook of beforeInteractionHooksRef.current) {
|
|
8493
|
+
if (hook(detail) === "handled") {
|
|
8494
|
+
return null;
|
|
8495
|
+
}
|
|
8496
|
+
}
|
|
8497
|
+
activeCanvuInteractionRef.current = detail;
|
|
8498
|
+
return detail;
|
|
8499
|
+
},
|
|
8500
|
+
[makeInteractionPoint]
|
|
8501
|
+
);
|
|
8502
|
+
const updateCanvuInteractionCurrent = react.useCallback(
|
|
8503
|
+
(input) => {
|
|
8504
|
+
const detail = activeCanvuInteractionRef.current;
|
|
8505
|
+
if (!detail) return;
|
|
8506
|
+
activeCanvuInteractionRef.current = {
|
|
8507
|
+
...detail,
|
|
8508
|
+
current: makeInteractionPoint(input)
|
|
8509
|
+
};
|
|
8510
|
+
},
|
|
8511
|
+
[makeInteractionPoint]
|
|
8512
|
+
);
|
|
8513
|
+
const finishCanvuInteraction = react.useCallback(
|
|
8514
|
+
(outcome, options) => {
|
|
8515
|
+
const detail = activeCanvuInteractionRef.current;
|
|
8516
|
+
if (!detail) return;
|
|
8517
|
+
activeCanvuInteractionRef.current = null;
|
|
8518
|
+
const current = options?.current ? makeInteractionPoint(options.current) : detail.current;
|
|
8519
|
+
const info = options?.info;
|
|
8520
|
+
const afterDetail = {
|
|
8521
|
+
...detail,
|
|
8522
|
+
current,
|
|
8523
|
+
itemIds: detail.itemIds.length > 0 ? detail.itemIds : [...info?.itemIds ?? []],
|
|
8524
|
+
outcome,
|
|
8525
|
+
...info ? { info } : {}
|
|
8526
|
+
};
|
|
8527
|
+
for (const hook of afterInteractionHooksRef.current) {
|
|
8528
|
+
hook(afterDetail);
|
|
8529
|
+
}
|
|
8530
|
+
},
|
|
8531
|
+
[makeInteractionPoint]
|
|
8532
|
+
);
|
|
8403
8533
|
onWorldPointerDownRef.current = onWorldPointerDown;
|
|
8404
8534
|
const originalOnItemsChangeRef = react.useRef(onItemsChange);
|
|
8405
8535
|
originalOnItemsChangeRef.current = onItemsChange;
|
|
@@ -8640,9 +8770,14 @@ var VectorViewport = react.forwardRef(
|
|
|
8640
8770
|
);
|
|
8641
8771
|
if (item) {
|
|
8642
8772
|
const exists = itemsRef.current.some((it) => it.id === id);
|
|
8773
|
+
const info = {
|
|
8774
|
+
motive: "draw",
|
|
8775
|
+
itemIds: [id],
|
|
8776
|
+
toolId: args.tool
|
|
8777
|
+
};
|
|
8643
8778
|
change(
|
|
8644
8779
|
exists ? replaceItem(itemsRef.current, id, item) : [...itemsRef.current, item],
|
|
8645
|
-
|
|
8780
|
+
info
|
|
8646
8781
|
);
|
|
8647
8782
|
patchCurrentStrokeStyle({
|
|
8648
8783
|
stroke: item.stroke ?? DEFAULT_STROKE_STYLE.stroke,
|
|
@@ -8650,10 +8785,15 @@ var VectorViewport = react.forwardRef(
|
|
|
8650
8785
|
strokeOpacity: item.strokeOpacity,
|
|
8651
8786
|
strokeDash: item.strokeDash
|
|
8652
8787
|
});
|
|
8788
|
+
if (!shouldKeepToolForContinuousPenInput(args.tool, args.pointerType)) {
|
|
8789
|
+
requestAutoResetTool(args.tool);
|
|
8790
|
+
}
|
|
8791
|
+
return info;
|
|
8653
8792
|
}
|
|
8654
8793
|
if (!shouldKeepToolForContinuousPenInput(args.tool, args.pointerType)) {
|
|
8655
8794
|
requestAutoResetTool(args.tool);
|
|
8656
8795
|
}
|
|
8796
|
+
return void 0;
|
|
8657
8797
|
},
|
|
8658
8798
|
[
|
|
8659
8799
|
patchCurrentStrokeStyle,
|
|
@@ -8784,17 +8924,19 @@ var VectorViewport = react.forwardRef(
|
|
|
8784
8924
|
}
|
|
8785
8925
|
emitRemoteStrokePreviewClear();
|
|
8786
8926
|
setPlacementPreview(null);
|
|
8787
|
-
commitCompletedStroke({
|
|
8927
|
+
const info = commitCompletedStroke({
|
|
8788
8928
|
tool,
|
|
8789
8929
|
pointerType,
|
|
8790
8930
|
points: [...pts],
|
|
8791
8931
|
style,
|
|
8792
8932
|
itemId
|
|
8793
8933
|
});
|
|
8934
|
+
finishCanvuInteraction("completed", { info });
|
|
8794
8935
|
},
|
|
8795
8936
|
[
|
|
8796
8937
|
commitCompletedStroke,
|
|
8797
8938
|
emitRemoteStrokePreviewClear,
|
|
8939
|
+
finishCanvuInteraction,
|
|
8798
8940
|
releaseInteractionPointer,
|
|
8799
8941
|
renderSceneWithLivePenStroke
|
|
8800
8942
|
]
|
|
@@ -9864,12 +10006,26 @@ var VectorViewport = react.forwardRef(
|
|
|
9864
10006
|
if (!raw) return void 0;
|
|
9865
10007
|
return raw.toolKind === "arrow" && raw.arrowBind ? bakeArrowItemToAbsolute(raw, canonical) : raw;
|
|
9866
10008
|
};
|
|
10009
|
+
const startInteraction = (kind, itemIds) => startCanvuInteraction({
|
|
10010
|
+
kind,
|
|
10011
|
+
toolId: tool,
|
|
10012
|
+
pointerType: e.pointerType,
|
|
10013
|
+
button: e.button,
|
|
10014
|
+
worldX,
|
|
10015
|
+
worldY,
|
|
10016
|
+
clientX: e.clientX,
|
|
10017
|
+
clientY: e.clientY,
|
|
10018
|
+
shiftKey: e.shiftKey,
|
|
10019
|
+
altKey: e.altKey,
|
|
10020
|
+
metaKey: e.metaKey,
|
|
10021
|
+
ctrlKey: e.ctrlKey,
|
|
10022
|
+
itemIds
|
|
10023
|
+
});
|
|
10024
|
+
const stopHandledInteraction = () => {
|
|
10025
|
+
e.preventDefault();
|
|
10026
|
+
e.stopPropagation();
|
|
10027
|
+
};
|
|
9867
10028
|
if (tool === "eraser") {
|
|
9868
|
-
dragStateRef.current = { kind: "erase" };
|
|
9869
|
-
eraserPreviewIdsRef.current = /* @__PURE__ */ new Set();
|
|
9870
|
-
setEraserPreviewIds([]);
|
|
9871
|
-
setEraserTrail([{ x: worldX, y: worldY, t: Date.now() }]);
|
|
9872
|
-
setEraserActive(true);
|
|
9873
10029
|
const toErase = collectEraserTargetsAtWorldPoint(
|
|
9874
10030
|
resolved,
|
|
9875
10031
|
worldX,
|
|
@@ -9879,6 +10035,15 @@ var VectorViewport = react.forwardRef(
|
|
|
9879
10035
|
ignoreLocked: true
|
|
9880
10036
|
}
|
|
9881
10037
|
);
|
|
10038
|
+
if (!startInteraction("erase", toErase)) {
|
|
10039
|
+
stopHandledInteraction();
|
|
10040
|
+
return;
|
|
10041
|
+
}
|
|
10042
|
+
dragStateRef.current = { kind: "erase" };
|
|
10043
|
+
eraserPreviewIdsRef.current = /* @__PURE__ */ new Set();
|
|
10044
|
+
setEraserPreviewIds([]);
|
|
10045
|
+
setEraserTrail([{ x: worldX, y: worldY, t: Date.now() }]);
|
|
10046
|
+
setEraserActive(true);
|
|
9882
10047
|
if (toErase.length > 0) {
|
|
9883
10048
|
for (const id of toErase) {
|
|
9884
10049
|
eraserPreviewIdsRef.current.add(id);
|
|
@@ -9911,6 +10076,10 @@ var VectorViewport = react.forwardRef(
|
|
|
9911
10076
|
const snapSpin = bakedSnapshot(selected.id);
|
|
9912
10077
|
if (!snapSpin) return;
|
|
9913
10078
|
const pivot = itemPivotWorld(selected);
|
|
10079
|
+
if (!startInteraction("rotate", [selected.id])) {
|
|
10080
|
+
stopHandledInteraction();
|
|
10081
|
+
return;
|
|
10082
|
+
}
|
|
9914
10083
|
dragStateRef.current = {
|
|
9915
10084
|
kind: "rotate",
|
|
9916
10085
|
id: selected.id,
|
|
@@ -9935,6 +10104,10 @@ var VectorViewport = react.forwardRef(
|
|
|
9935
10104
|
if (hb) {
|
|
9936
10105
|
const snapRs = bakedSnapshot(selected.id);
|
|
9937
10106
|
if (!snapRs) return;
|
|
10107
|
+
if (!startInteraction("resize", [selected.id])) {
|
|
10108
|
+
stopHandledInteraction();
|
|
10109
|
+
return;
|
|
10110
|
+
}
|
|
9938
10111
|
dragStateRef.current = {
|
|
9939
10112
|
kind: "resize",
|
|
9940
10113
|
id: selected.id,
|
|
@@ -9967,6 +10140,10 @@ var VectorViewport = react.forwardRef(
|
|
|
9967
10140
|
moveSnapshots[id] = snap;
|
|
9968
10141
|
}
|
|
9969
10142
|
}
|
|
10143
|
+
if (!startInteraction("select-mode-item-click", [hit.id])) {
|
|
10144
|
+
stopHandledInteraction();
|
|
10145
|
+
return;
|
|
10146
|
+
}
|
|
9970
10147
|
dragStateRef.current = {
|
|
9971
10148
|
kind: "select-mode-item-click",
|
|
9972
10149
|
id: hit.id,
|
|
@@ -9983,7 +10160,14 @@ var VectorViewport = react.forwardRef(
|
|
|
9983
10160
|
}
|
|
9984
10161
|
if (e.shiftKey) {
|
|
9985
10162
|
const next = cur.includes(hit.id) ? cur.filter((id) => id !== hit.id) : [...cur, hit.id];
|
|
10163
|
+
if (!startInteraction("select-mode-item-click", [hit.id])) {
|
|
10164
|
+
stopHandledInteraction();
|
|
10165
|
+
return;
|
|
10166
|
+
}
|
|
9986
10167
|
setEffectiveSelectedIdsRef.current(next);
|
|
10168
|
+
finishCanvuInteraction("completed", {
|
|
10169
|
+
info: { motive: "custom", itemIds: [hit.id], toolId: tool }
|
|
10170
|
+
});
|
|
9987
10171
|
e.preventDefault();
|
|
9988
10172
|
e.stopPropagation();
|
|
9989
10173
|
return;
|
|
@@ -9991,7 +10175,6 @@ var VectorViewport = react.forwardRef(
|
|
|
9991
10175
|
let idsToMove;
|
|
9992
10176
|
if (!cur.includes(hit.id)) {
|
|
9993
10177
|
idsToMove = [hit.id];
|
|
9994
|
-
setEffectiveSelectedIdsRef.current(idsToMove);
|
|
9995
10178
|
} else {
|
|
9996
10179
|
idsToMove = [...cur];
|
|
9997
10180
|
}
|
|
@@ -10002,6 +10185,13 @@ var VectorViewport = react.forwardRef(
|
|
|
10002
10185
|
snapshots[id] = snap;
|
|
10003
10186
|
}
|
|
10004
10187
|
}
|
|
10188
|
+
if (!startInteraction("move", idsToMove)) {
|
|
10189
|
+
stopHandledInteraction();
|
|
10190
|
+
return;
|
|
10191
|
+
}
|
|
10192
|
+
if (!cur.includes(hit.id)) {
|
|
10193
|
+
setEffectiveSelectedIdsRef.current(idsToMove);
|
|
10194
|
+
}
|
|
10005
10195
|
dragStateRef.current = {
|
|
10006
10196
|
kind: "move",
|
|
10007
10197
|
ids: idsToMove,
|
|
@@ -10026,9 +10216,14 @@ var VectorViewport = react.forwardRef(
|
|
|
10026
10216
|
}
|
|
10027
10217
|
}
|
|
10028
10218
|
if (Object.keys(snapshots).length > 0) {
|
|
10219
|
+
const moveIds = Object.keys(snapshots);
|
|
10220
|
+
if (!startInteraction("move", moveIds)) {
|
|
10221
|
+
stopHandledInteraction();
|
|
10222
|
+
return;
|
|
10223
|
+
}
|
|
10029
10224
|
dragStateRef.current = {
|
|
10030
10225
|
kind: "move",
|
|
10031
|
-
ids:
|
|
10226
|
+
ids: moveIds,
|
|
10032
10227
|
snapshots,
|
|
10033
10228
|
startWorld: { x: worldX, y: worldY }
|
|
10034
10229
|
};
|
|
@@ -10039,6 +10234,10 @@ var VectorViewport = react.forwardRef(
|
|
|
10039
10234
|
}
|
|
10040
10235
|
}
|
|
10041
10236
|
}
|
|
10237
|
+
if (!startInteraction("marquee")) {
|
|
10238
|
+
stopHandledInteraction();
|
|
10239
|
+
return;
|
|
10240
|
+
}
|
|
10042
10241
|
dragStateRef.current = {
|
|
10043
10242
|
kind: "marquee",
|
|
10044
10243
|
startWorld: { x: worldX, y: worldY },
|
|
@@ -10067,6 +10266,10 @@ var VectorViewport = react.forwardRef(
|
|
|
10067
10266
|
);
|
|
10068
10267
|
const straightLine = tool === "draw" ? createStraightStrokeState(startPoint, e.clientX, e.clientY) : void 0;
|
|
10069
10268
|
const directPenStroke = e.pointerType === "pen" && (tool === "draw" || tool === "marker");
|
|
10269
|
+
if (!startInteraction("stroke")) {
|
|
10270
|
+
stopHandledInteraction();
|
|
10271
|
+
return;
|
|
10272
|
+
}
|
|
10070
10273
|
let itemId;
|
|
10071
10274
|
if (directPenStroke) {
|
|
10072
10275
|
itemId = createShapeId();
|
|
@@ -10110,6 +10313,10 @@ var VectorViewport = react.forwardRef(
|
|
|
10110
10313
|
return;
|
|
10111
10314
|
}
|
|
10112
10315
|
if (tool === "text" || tool === "image") {
|
|
10316
|
+
if (!startInteraction("tap")) {
|
|
10317
|
+
stopHandledInteraction();
|
|
10318
|
+
return;
|
|
10319
|
+
}
|
|
10113
10320
|
dragStateRef.current = {
|
|
10114
10321
|
kind: "tap",
|
|
10115
10322
|
tool,
|
|
@@ -10123,6 +10330,10 @@ var VectorViewport = react.forwardRef(
|
|
|
10123
10330
|
}
|
|
10124
10331
|
const cp = customPlacementRef.current;
|
|
10125
10332
|
if (tool === "rect" || tool === "ellipse" || tool === "architectural-cloud" || tool === "line" || tool === "arrow" || cp && tool === cp.toolId) {
|
|
10333
|
+
if (!startInteraction("place")) {
|
|
10334
|
+
stopHandledInteraction();
|
|
10335
|
+
return;
|
|
10336
|
+
}
|
|
10126
10337
|
dragStateRef.current = {
|
|
10127
10338
|
kind: "place",
|
|
10128
10339
|
tool,
|
|
@@ -10140,8 +10351,10 @@ var VectorViewport = react.forwardRef(
|
|
|
10140
10351
|
captureInteractionPointer,
|
|
10141
10352
|
emitRemoteStrokePreview,
|
|
10142
10353
|
finalizeStrokeDragState,
|
|
10354
|
+
finishCanvuInteraction,
|
|
10143
10355
|
renderSceneWithLivePenStroke,
|
|
10144
10356
|
screenToWorld,
|
|
10357
|
+
startCanvuInteraction,
|
|
10145
10358
|
startOrRestartStraightStrokeHoldTimer
|
|
10146
10359
|
]
|
|
10147
10360
|
);
|
|
@@ -10170,14 +10383,32 @@ var VectorViewport = react.forwardRef(
|
|
|
10170
10383
|
e.stopImmediatePropagation();
|
|
10171
10384
|
return;
|
|
10172
10385
|
}
|
|
10173
|
-
wrapperRef.current?.focus({ preventScroll: true });
|
|
10174
|
-
setContextMenu(null);
|
|
10175
10386
|
const startPoint = pointerSampleToWorldPoint(
|
|
10176
10387
|
screenToWorld,
|
|
10177
10388
|
e.clientX,
|
|
10178
10389
|
e.clientY,
|
|
10179
10390
|
e.pressure
|
|
10180
10391
|
);
|
|
10392
|
+
if (!startCanvuInteraction({
|
|
10393
|
+
kind: "stroke",
|
|
10394
|
+
toolId: tool,
|
|
10395
|
+
pointerType: e.pointerType,
|
|
10396
|
+
button: e.button,
|
|
10397
|
+
worldX: startPoint.x,
|
|
10398
|
+
worldY: startPoint.y,
|
|
10399
|
+
clientX: e.clientX,
|
|
10400
|
+
clientY: e.clientY,
|
|
10401
|
+
shiftKey: e.shiftKey,
|
|
10402
|
+
altKey: e.altKey,
|
|
10403
|
+
metaKey: e.metaKey,
|
|
10404
|
+
ctrlKey: e.ctrlKey
|
|
10405
|
+
})) {
|
|
10406
|
+
e.preventDefault();
|
|
10407
|
+
e.stopImmediatePropagation();
|
|
10408
|
+
return;
|
|
10409
|
+
}
|
|
10410
|
+
wrapperRef.current?.focus({ preventScroll: true });
|
|
10411
|
+
setContextMenu(null);
|
|
10181
10412
|
const straightLine = tool === "draw" ? createStraightStrokeState(startPoint, e.clientX, e.clientY) : void 0;
|
|
10182
10413
|
const itemId = createShapeId();
|
|
10183
10414
|
const item = createFreehandStrokeItem(
|
|
@@ -10225,6 +10456,7 @@ var VectorViewport = react.forwardRef(
|
|
|
10225
10456
|
interactive,
|
|
10226
10457
|
renderSceneWithLivePenStroke,
|
|
10227
10458
|
screenToWorld,
|
|
10459
|
+
startCanvuInteraction,
|
|
10228
10460
|
startOrRestartStraightStrokeHoldTimer
|
|
10229
10461
|
]);
|
|
10230
10462
|
react.useEffect(() => {
|
|
@@ -10275,15 +10507,32 @@ var VectorViewport = react.forwardRef(
|
|
|
10275
10507
|
stopTouchEvent(ev);
|
|
10276
10508
|
return;
|
|
10277
10509
|
}
|
|
10278
|
-
wrapperRef.current?.focus({ preventScroll: true });
|
|
10279
|
-
setContextMenu(null);
|
|
10280
|
-
penDetectedRef.current = true;
|
|
10281
10510
|
const startPoint = pointerSampleToWorldPoint(
|
|
10282
10511
|
screenToWorld,
|
|
10283
10512
|
touch.clientX,
|
|
10284
10513
|
touch.clientY,
|
|
10285
10514
|
touchPressure(touch)
|
|
10286
10515
|
);
|
|
10516
|
+
if (!startCanvuInteraction({
|
|
10517
|
+
kind: "stroke",
|
|
10518
|
+
toolId: tool,
|
|
10519
|
+
pointerType: "pen",
|
|
10520
|
+
button: 0,
|
|
10521
|
+
worldX: startPoint.x,
|
|
10522
|
+
worldY: startPoint.y,
|
|
10523
|
+
clientX: touch.clientX,
|
|
10524
|
+
clientY: touch.clientY,
|
|
10525
|
+
shiftKey: ev.shiftKey,
|
|
10526
|
+
altKey: ev.altKey,
|
|
10527
|
+
metaKey: ev.metaKey,
|
|
10528
|
+
ctrlKey: ev.ctrlKey
|
|
10529
|
+
})) {
|
|
10530
|
+
stopTouchEvent(ev);
|
|
10531
|
+
return;
|
|
10532
|
+
}
|
|
10533
|
+
wrapperRef.current?.focus({ preventScroll: true });
|
|
10534
|
+
setContextMenu(null);
|
|
10535
|
+
penDetectedRef.current = true;
|
|
10287
10536
|
const straightLine = tool === "draw" ? createStraightStrokeState(startPoint, touch.clientX, touch.clientY) : void 0;
|
|
10288
10537
|
const itemId = createShapeId();
|
|
10289
10538
|
const item = createFreehandStrokeItem(
|
|
@@ -10329,6 +10578,12 @@ var VectorViewport = react.forwardRef(
|
|
|
10329
10578
|
touch.clientY,
|
|
10330
10579
|
touchPressure(touch)
|
|
10331
10580
|
);
|
|
10581
|
+
updateCanvuInteractionCurrent({
|
|
10582
|
+
worldX: endpoint.x,
|
|
10583
|
+
worldY: endpoint.y,
|
|
10584
|
+
clientX: touch.clientX,
|
|
10585
|
+
clientY: touch.clientY
|
|
10586
|
+
});
|
|
10332
10587
|
if (updateStraightStrokeForMove(st, touch.clientX, touch.clientY, endpoint)) {
|
|
10333
10588
|
debugApplePencilPointer("touchmove-stroke", {
|
|
10334
10589
|
touchId: touch.identifier,
|
|
@@ -10370,16 +10625,42 @@ var VectorViewport = react.forwardRef(
|
|
|
10370
10625
|
if (st.kind !== "stroke") return;
|
|
10371
10626
|
const touch = findChangedTouch(ev.changedTouches);
|
|
10372
10627
|
if (!touch) return;
|
|
10628
|
+
const currentPoint = pointerSampleToWorldPoint(
|
|
10629
|
+
screenToWorld,
|
|
10630
|
+
touch.clientX,
|
|
10631
|
+
touch.clientY,
|
|
10632
|
+
touchPressure(touch)
|
|
10633
|
+
);
|
|
10634
|
+
updateCanvuInteractionCurrent({
|
|
10635
|
+
worldX: currentPoint.x,
|
|
10636
|
+
worldY: currentPoint.y,
|
|
10637
|
+
clientX: touch.clientX,
|
|
10638
|
+
clientY: touch.clientY
|
|
10639
|
+
});
|
|
10640
|
+
if (ev.type === "touchcancel") {
|
|
10641
|
+
clearStraightStrokeHoldTimer(st);
|
|
10642
|
+
dragStateRef.current = { kind: "idle" };
|
|
10643
|
+
releaseInteractionPointer();
|
|
10644
|
+
if (st.itemId) {
|
|
10645
|
+
renderSceneWithLivePenStroke(null);
|
|
10646
|
+
}
|
|
10647
|
+
emitRemoteStrokePreviewClear();
|
|
10648
|
+
setPlacementPreview(null);
|
|
10649
|
+
finishCanvuInteraction("cancelled", {
|
|
10650
|
+
current: {
|
|
10651
|
+
worldX: currentPoint.x,
|
|
10652
|
+
worldY: currentPoint.y,
|
|
10653
|
+
clientX: touch.clientX,
|
|
10654
|
+
clientY: touch.clientY
|
|
10655
|
+
}
|
|
10656
|
+
});
|
|
10657
|
+
stopTouchEvent(ev);
|
|
10658
|
+
return;
|
|
10659
|
+
}
|
|
10373
10660
|
const cam = cameraRef.current;
|
|
10374
10661
|
if (cam) {
|
|
10375
10662
|
if (st.straightLine?.active) {
|
|
10376
|
-
|
|
10377
|
-
screenToWorld,
|
|
10378
|
-
touch.clientX,
|
|
10379
|
-
touch.clientY,
|
|
10380
|
-
touchPressure(touch)
|
|
10381
|
-
);
|
|
10382
|
-
setStraightStrokeEndpoint(st, endpoint);
|
|
10663
|
+
setStraightStrokeEndpoint(st, currentPoint);
|
|
10383
10664
|
} else {
|
|
10384
10665
|
const completedPoints = appendTouchToStrokePoints(
|
|
10385
10666
|
st.points,
|
|
@@ -10430,12 +10711,17 @@ var VectorViewport = react.forwardRef(
|
|
|
10430
10711
|
}, [
|
|
10431
10712
|
applePencilNav,
|
|
10432
10713
|
emitRemoteStrokePreview,
|
|
10714
|
+
emitRemoteStrokePreviewClear,
|
|
10433
10715
|
finalizeStrokeDragState,
|
|
10716
|
+
finishCanvuInteraction,
|
|
10434
10717
|
interactive,
|
|
10718
|
+
releaseInteractionPointer,
|
|
10435
10719
|
renderSceneWithLivePenStroke,
|
|
10436
10720
|
screenToWorld,
|
|
10437
10721
|
setStraightStrokeEndpoint,
|
|
10722
|
+
startCanvuInteraction,
|
|
10438
10723
|
startOrRestartStraightStrokeHoldTimer,
|
|
10724
|
+
updateCanvuInteractionCurrent,
|
|
10439
10725
|
updateStraightStrokeForMove
|
|
10440
10726
|
]);
|
|
10441
10727
|
react.useEffect(() => {
|
|
@@ -10448,6 +10734,12 @@ var VectorViewport = react.forwardRef(
|
|
|
10448
10734
|
if (st.kind === "tap") return;
|
|
10449
10735
|
if (st.kind === "marquee") {
|
|
10450
10736
|
const { worldX: worldX2, worldY: worldY2 } = screenToWorld(ev.clientX, ev.clientY);
|
|
10737
|
+
updateCanvuInteractionCurrent({
|
|
10738
|
+
worldX: worldX2,
|
|
10739
|
+
worldY: worldY2,
|
|
10740
|
+
clientX: ev.clientX,
|
|
10741
|
+
clientY: ev.clientY
|
|
10742
|
+
});
|
|
10451
10743
|
const raw = rectFromCorners(st.startWorld, { x: worldX2, y: worldY2 });
|
|
10452
10744
|
setPlacementPreview({ kind: "marquee", rect: raw });
|
|
10453
10745
|
const nextCand = collectItemIdsInRect(
|
|
@@ -10475,6 +10767,12 @@ var VectorViewport = react.forwardRef(
|
|
|
10475
10767
|
ev.clientY,
|
|
10476
10768
|
ev.pointerType === "pen" ? ev.pressure : void 0
|
|
10477
10769
|
);
|
|
10770
|
+
updateCanvuInteractionCurrent({
|
|
10771
|
+
worldX: endpoint.x,
|
|
10772
|
+
worldY: endpoint.y,
|
|
10773
|
+
clientX: ev.clientX,
|
|
10774
|
+
clientY: ev.clientY
|
|
10775
|
+
});
|
|
10478
10776
|
if (updateStraightStrokeForMove(st, ev.clientX, ev.clientY, endpoint)) {
|
|
10479
10777
|
return;
|
|
10480
10778
|
}
|
|
@@ -10523,6 +10821,12 @@ var VectorViewport = react.forwardRef(
|
|
|
10523
10821
|
}
|
|
10524
10822
|
if (st.kind === "erase") {
|
|
10525
10823
|
const { worldX: worldX2, worldY: worldY2 } = screenToWorld(ev.clientX, ev.clientY);
|
|
10824
|
+
updateCanvuInteractionCurrent({
|
|
10825
|
+
worldX: worldX2,
|
|
10826
|
+
worldY: worldY2,
|
|
10827
|
+
clientX: ev.clientX,
|
|
10828
|
+
clientY: ev.clientY
|
|
10829
|
+
});
|
|
10526
10830
|
const lineHitWorld = 10 / cam.zoom;
|
|
10527
10831
|
setEraserTrail(
|
|
10528
10832
|
(prev) => pruneEraserTrail([...prev, { x: worldX2, y: worldY2, t: Date.now() }])
|
|
@@ -10548,6 +10852,12 @@ var VectorViewport = react.forwardRef(
|
|
|
10548
10852
|
const change = onItemsChangeRef.current;
|
|
10549
10853
|
if (!change) return;
|
|
10550
10854
|
const { worldX, worldY } = screenToWorld(ev.clientX, ev.clientY);
|
|
10855
|
+
updateCanvuInteractionCurrent({
|
|
10856
|
+
worldX,
|
|
10857
|
+
worldY,
|
|
10858
|
+
clientX: ev.clientX,
|
|
10859
|
+
clientY: ev.clientY
|
|
10860
|
+
});
|
|
10551
10861
|
if (st.kind === "select-mode-item-click") {
|
|
10552
10862
|
const screenDx = ev.clientX - st.startScreen.x;
|
|
10553
10863
|
const screenDy = ev.clientY - st.startScreen.y;
|
|
@@ -10680,29 +10990,64 @@ var VectorViewport = react.forwardRef(
|
|
|
10680
10990
|
setPlacementPreview(null);
|
|
10681
10991
|
marqueeCandidateIdsRef.current = [];
|
|
10682
10992
|
setMarqueeCandidateIds([]);
|
|
10993
|
+
finishCanvuInteraction("cancelled");
|
|
10683
10994
|
return;
|
|
10684
10995
|
}
|
|
10996
|
+
const finishOutcome = ev.type === "pointercancel" ? "cancelled" : "completed";
|
|
10997
|
+
const currentWorld = screenToWorld(ev.clientX, ev.clientY);
|
|
10998
|
+
const currentInteractionPoint = {
|
|
10999
|
+
worldX: currentWorld.worldX,
|
|
11000
|
+
worldY: currentWorld.worldY,
|
|
11001
|
+
clientX: ev.clientX,
|
|
11002
|
+
clientY: ev.clientY
|
|
11003
|
+
};
|
|
11004
|
+
updateCanvuInteractionCurrent(currentInteractionPoint);
|
|
10685
11005
|
if (st.kind === "move" || st.kind === "resize" || st.kind === "rotate") {
|
|
11006
|
+
const info = st.kind === "move" ? { motive: "move", itemIds: [...st.ids] } : st.kind === "resize" ? { motive: "resize", itemIds: [st.id] } : { motive: "rotate", itemIds: [st.id] };
|
|
10686
11007
|
dragStateRef.current = { kind: "idle" };
|
|
10687
11008
|
releaseInteractionPointer();
|
|
11009
|
+
finishCanvuInteraction(finishOutcome, {
|
|
11010
|
+
current: currentInteractionPoint,
|
|
11011
|
+
...finishOutcome === "completed" ? { info } : {}
|
|
11012
|
+
});
|
|
10688
11013
|
return;
|
|
10689
11014
|
}
|
|
10690
11015
|
if (st.kind === "select-mode-item-click") {
|
|
10691
11016
|
dragStateRef.current = { kind: "idle" };
|
|
10692
11017
|
releaseInteractionPointer();
|
|
10693
|
-
if (
|
|
11018
|
+
if (finishOutcome === "cancelled") {
|
|
11019
|
+
finishCanvuInteraction("cancelled", {
|
|
11020
|
+
current: currentInteractionPoint
|
|
11021
|
+
});
|
|
11022
|
+
return;
|
|
11023
|
+
}
|
|
10694
11024
|
const dx = ev.clientX - st.startScreen.x;
|
|
10695
11025
|
const dy = ev.clientY - st.startScreen.y;
|
|
10696
|
-
if (Math.hypot(dx, dy) > TAP_PX)
|
|
11026
|
+
if (Math.hypot(dx, dy) > TAP_PX) {
|
|
11027
|
+
finishCanvuInteraction("cancelled", {
|
|
11028
|
+
current: currentInteractionPoint
|
|
11029
|
+
});
|
|
11030
|
+
return;
|
|
11031
|
+
}
|
|
10697
11032
|
const item = itemsRef.current.find((candidate) => candidate.id === st.id) ?? resolvedItemsRef.current.find((candidate) => candidate.id === st.id);
|
|
10698
|
-
if (!item)
|
|
11033
|
+
if (!item) {
|
|
11034
|
+
finishCanvuInteraction("cancelled", {
|
|
11035
|
+
current: currentInteractionPoint
|
|
11036
|
+
});
|
|
11037
|
+
return;
|
|
11038
|
+
}
|
|
10699
11039
|
const placement = findSelectModeItemClickPlacement(
|
|
10700
11040
|
item,
|
|
10701
11041
|
allCustomPlacementsRef.current
|
|
10702
11042
|
);
|
|
10703
11043
|
const onSelectModeItemClick = placement?.onSelectModeItemClick;
|
|
10704
|
-
if (!onSelectModeItemClick)
|
|
10705
|
-
|
|
11044
|
+
if (!onSelectModeItemClick) {
|
|
11045
|
+
finishCanvuInteraction("cancelled", {
|
|
11046
|
+
current: currentInteractionPoint
|
|
11047
|
+
});
|
|
11048
|
+
return;
|
|
11049
|
+
}
|
|
11050
|
+
const { worldX, worldY } = currentWorld;
|
|
10706
11051
|
onSelectModeItemClick({
|
|
10707
11052
|
item,
|
|
10708
11053
|
worldX,
|
|
@@ -10723,6 +11068,10 @@ var VectorViewport = react.forwardRef(
|
|
|
10723
11068
|
},
|
|
10724
11069
|
setSelectedIds: (ids) => setEffectiveSelectedIdsRef.current(ids)
|
|
10725
11070
|
});
|
|
11071
|
+
finishCanvuInteraction("completed", {
|
|
11072
|
+
current: currentInteractionPoint,
|
|
11073
|
+
info: { motive: "custom", itemIds: [item.id], toolId: "select" }
|
|
11074
|
+
});
|
|
10726
11075
|
return;
|
|
10727
11076
|
}
|
|
10728
11077
|
if (st.kind === "marquee") {
|
|
@@ -10731,16 +11080,25 @@ var VectorViewport = react.forwardRef(
|
|
|
10731
11080
|
setPlacementPreview(null);
|
|
10732
11081
|
marqueeCandidateIdsRef.current = [];
|
|
10733
11082
|
setMarqueeCandidateIds([]);
|
|
10734
|
-
const { worldX, worldY } =
|
|
11083
|
+
const { worldX, worldY } = currentWorld;
|
|
10735
11084
|
const raw = rectFromCorners(st.startWorld, { x: worldX, y: worldY });
|
|
10736
11085
|
const br = normalizeRect(raw);
|
|
10737
11086
|
const screenDx = ev.clientX - st.startScreen.x;
|
|
10738
11087
|
const screenDy = ev.clientY - st.startScreen.y;
|
|
11088
|
+
if (finishOutcome === "cancelled") {
|
|
11089
|
+
finishCanvuInteraction("cancelled", {
|
|
11090
|
+
current: currentInteractionPoint
|
|
11091
|
+
});
|
|
11092
|
+
return;
|
|
11093
|
+
}
|
|
10739
11094
|
const tooSmall = Math.hypot(screenDx, screenDy) < TAP_PX || br.width < MIN_MARQUEE_WORLD && br.height < MIN_MARQUEE_WORLD;
|
|
10740
11095
|
if (tooSmall) {
|
|
10741
11096
|
if (!st.shiftKey) {
|
|
10742
11097
|
setEffectiveSelectedIdsRef.current([]);
|
|
10743
11098
|
}
|
|
11099
|
+
finishCanvuInteraction("cancelled", {
|
|
11100
|
+
current: currentInteractionPoint
|
|
11101
|
+
});
|
|
10744
11102
|
return;
|
|
10745
11103
|
}
|
|
10746
11104
|
const picked = collectItemIdsInRect(resolvedItemsRef.current, br);
|
|
@@ -10757,9 +11115,26 @@ var VectorViewport = react.forwardRef(
|
|
|
10757
11115
|
} else {
|
|
10758
11116
|
setEffectiveSelectedIdsRef.current(picked);
|
|
10759
11117
|
}
|
|
11118
|
+
finishCanvuInteraction("completed", {
|
|
11119
|
+
current: currentInteractionPoint
|
|
11120
|
+
});
|
|
10760
11121
|
return;
|
|
10761
11122
|
}
|
|
10762
11123
|
if (st.kind === "stroke") {
|
|
11124
|
+
if (finishOutcome === "cancelled") {
|
|
11125
|
+
clearStraightStrokeHoldTimer(st);
|
|
11126
|
+
dragStateRef.current = { kind: "idle" };
|
|
11127
|
+
releaseInteractionPointer();
|
|
11128
|
+
if (st.itemId) {
|
|
11129
|
+
renderSceneWithLivePenStroke(null);
|
|
11130
|
+
}
|
|
11131
|
+
emitRemoteStrokePreviewClear();
|
|
11132
|
+
setPlacementPreview(null);
|
|
11133
|
+
finishCanvuInteraction("cancelled", {
|
|
11134
|
+
current: currentInteractionPoint
|
|
11135
|
+
});
|
|
11136
|
+
return;
|
|
11137
|
+
}
|
|
10763
11138
|
const completedPoints = (() => {
|
|
10764
11139
|
if (st.straightLine?.active) {
|
|
10765
11140
|
const endpoint = pointerSampleToWorldPoint(
|
|
@@ -10790,15 +11165,20 @@ var VectorViewport = react.forwardRef(
|
|
|
10790
11165
|
}
|
|
10791
11166
|
if (st.kind === "erase") {
|
|
10792
11167
|
const change = onItemsChangeRef.current;
|
|
11168
|
+
const erasedIds = [...eraserPreviewIdsRef.current];
|
|
11169
|
+
const info = erasedIds.length > 0 ? {
|
|
11170
|
+
motive: "erase",
|
|
11171
|
+
itemIds: erasedIds,
|
|
11172
|
+
toolId: "eraser"
|
|
11173
|
+
} : void 0;
|
|
10793
11174
|
if (change && eraserPreviewIdsRef.current.size > 0) {
|
|
10794
11175
|
const idSet = new Set(eraserPreviewIdsRef.current);
|
|
10795
|
-
|
|
10796
|
-
|
|
10797
|
-
|
|
10798
|
-
|
|
10799
|
-
|
|
10800
|
-
|
|
10801
|
-
);
|
|
11176
|
+
if (finishOutcome === "completed") {
|
|
11177
|
+
change(
|
|
11178
|
+
itemsRef.current.filter((i) => !idSet.has(i.id)),
|
|
11179
|
+
info
|
|
11180
|
+
);
|
|
11181
|
+
}
|
|
10802
11182
|
}
|
|
10803
11183
|
eraserPreviewIdsRef.current.clear();
|
|
10804
11184
|
setEraserPreviewIds([]);
|
|
@@ -10806,7 +11186,13 @@ var VectorViewport = react.forwardRef(
|
|
|
10806
11186
|
setEraserActive(false);
|
|
10807
11187
|
dragStateRef.current = { kind: "idle" };
|
|
10808
11188
|
releaseInteractionPointer();
|
|
10809
|
-
|
|
11189
|
+
if (finishOutcome === "completed") {
|
|
11190
|
+
requestAutoResetTool("eraser");
|
|
11191
|
+
}
|
|
11192
|
+
finishCanvuInteraction(finishOutcome, {
|
|
11193
|
+
current: currentInteractionPoint,
|
|
11194
|
+
...finishOutcome === "completed" && info ? { info } : {}
|
|
11195
|
+
});
|
|
10810
11196
|
return;
|
|
10811
11197
|
}
|
|
10812
11198
|
if (st.kind === "tap") {
|
|
@@ -10814,11 +11200,22 @@ var VectorViewport = react.forwardRef(
|
|
|
10814
11200
|
const dy = ev.clientY - st.startScreen.y;
|
|
10815
11201
|
dragStateRef.current = { kind: "idle" };
|
|
10816
11202
|
releaseInteractionPointer();
|
|
10817
|
-
if (Math.hypot(dx, dy) > TAP_PX)
|
|
11203
|
+
if (finishOutcome === "cancelled" || Math.hypot(dx, dy) > TAP_PX) {
|
|
11204
|
+
finishCanvuInteraction("cancelled", {
|
|
11205
|
+
current: currentInteractionPoint
|
|
11206
|
+
});
|
|
11207
|
+
return;
|
|
11208
|
+
}
|
|
10818
11209
|
const change = onItemsChangeRef.current;
|
|
10819
|
-
if (!change)
|
|
11210
|
+
if (!change) {
|
|
11211
|
+
finishCanvuInteraction("cancelled", {
|
|
11212
|
+
current: currentInteractionPoint
|
|
11213
|
+
});
|
|
11214
|
+
return;
|
|
11215
|
+
}
|
|
10820
11216
|
const id = createShapeId();
|
|
10821
11217
|
const { x: worldX, y: worldY } = st.startWorld;
|
|
11218
|
+
let info;
|
|
10822
11219
|
if (st.tool === "text") {
|
|
10823
11220
|
const fs = strokeStyleRef.current.textFontSize;
|
|
10824
11221
|
const baseline = textBaselineYFor(fs);
|
|
@@ -10841,11 +11238,12 @@ var VectorViewport = react.forwardRef(
|
|
|
10841
11238
|
bounds: { ...newItem.bounds }
|
|
10842
11239
|
};
|
|
10843
11240
|
const hidden = applyTextDraftWhileEditing(newItem, "");
|
|
10844
|
-
|
|
11241
|
+
info = {
|
|
10845
11242
|
motive: "text-create",
|
|
10846
11243
|
itemIds: [id],
|
|
10847
11244
|
toolId: st.tool
|
|
10848
|
-
}
|
|
11245
|
+
};
|
|
11246
|
+
change([...itemsRef.current, hidden], info);
|
|
10849
11247
|
setEffectiveSelectedIdsRef.current([id]);
|
|
10850
11248
|
setEditingTextId(id);
|
|
10851
11249
|
setDraftText("");
|
|
@@ -10854,6 +11252,10 @@ var VectorViewport = react.forwardRef(
|
|
|
10854
11252
|
imageInputRef.current?.click();
|
|
10855
11253
|
}
|
|
10856
11254
|
requestAutoResetTool(st.tool);
|
|
11255
|
+
finishCanvuInteraction("completed", {
|
|
11256
|
+
current: currentInteractionPoint,
|
|
11257
|
+
...info ? { info } : {}
|
|
11258
|
+
});
|
|
10857
11259
|
return;
|
|
10858
11260
|
}
|
|
10859
11261
|
if (st.kind === "place") {
|
|
@@ -10864,11 +11266,19 @@ var VectorViewport = react.forwardRef(
|
|
|
10864
11266
|
dragStateRef.current = { kind: "idle" };
|
|
10865
11267
|
releaseInteractionPointer();
|
|
10866
11268
|
setPlacementPreview(null);
|
|
10867
|
-
if (!change)
|
|
11269
|
+
if (finishOutcome === "cancelled" || !change) {
|
|
11270
|
+
finishCanvuInteraction("cancelled", {
|
|
11271
|
+
current: currentInteractionPoint
|
|
11272
|
+
});
|
|
11273
|
+
return;
|
|
11274
|
+
}
|
|
10868
11275
|
if (st.tool === "arrow") {
|
|
10869
11276
|
const screenDx = ev.clientX - st.startScreen.x;
|
|
10870
11277
|
const screenDy = ev.clientY - st.startScreen.y;
|
|
10871
11278
|
if (Math.hypot(screenDx, screenDy) < MIN_ARROW_DRAG_PX) {
|
|
11279
|
+
finishCanvuInteraction("cancelled", {
|
|
11280
|
+
current: currentInteractionPoint
|
|
11281
|
+
});
|
|
10872
11282
|
return;
|
|
10873
11283
|
}
|
|
10874
11284
|
const maxDist = ARROW_BIND_SNAP_PX / cam.zoom;
|
|
@@ -10900,18 +11310,23 @@ var VectorViewport = react.forwardRef(
|
|
|
10900
11310
|
...snapB ? { end: snapB.binding } : {}
|
|
10901
11311
|
};
|
|
10902
11312
|
}
|
|
11313
|
+
const info2 = {
|
|
11314
|
+
motive: "place",
|
|
11315
|
+
itemIds: [id2],
|
|
11316
|
+
toolId: st.tool
|
|
11317
|
+
};
|
|
10903
11318
|
change(
|
|
10904
11319
|
[
|
|
10905
11320
|
...itemsRef.current,
|
|
10906
11321
|
createLineItem(id2, rawArrow, line, "arrow", pen2, arrowBind)
|
|
10907
11322
|
],
|
|
10908
|
-
|
|
10909
|
-
motive: "place",
|
|
10910
|
-
itemIds: [id2],
|
|
10911
|
-
toolId: st.tool
|
|
10912
|
-
}
|
|
11323
|
+
info2
|
|
10913
11324
|
);
|
|
10914
11325
|
setEffectiveSelectedIdsRef.current([id2]);
|
|
11326
|
+
finishCanvuInteraction("completed", {
|
|
11327
|
+
current: currentInteractionPoint,
|
|
11328
|
+
info: info2
|
|
11329
|
+
});
|
|
10915
11330
|
return;
|
|
10916
11331
|
}
|
|
10917
11332
|
let raw = rectFromCorners(a, b);
|
|
@@ -10936,47 +11351,61 @@ var VectorViewport = react.forwardRef(
|
|
|
10936
11351
|
}
|
|
10937
11352
|
const id = createShapeId();
|
|
10938
11353
|
const pen = strokeStyleRef.current;
|
|
11354
|
+
let info;
|
|
10939
11355
|
if (cpUp && st.tool === cpUp.toolId) {
|
|
10940
11356
|
const item = tagCustomPlacementItem(
|
|
10941
11357
|
cpUp.createItem({ id, bounds: br }),
|
|
10942
11358
|
cpUp.toolId
|
|
10943
11359
|
);
|
|
10944
|
-
|
|
11360
|
+
info = {
|
|
10945
11361
|
motive: "place",
|
|
10946
11362
|
itemIds: [id],
|
|
10947
11363
|
toolId: st.tool
|
|
10948
|
-
}
|
|
11364
|
+
};
|
|
11365
|
+
change(itemsRef.current.concat(item), info);
|
|
10949
11366
|
if (cpUp.selectAfterCreate !== false) {
|
|
10950
11367
|
setEffectiveSelectedIdsRef.current([id]);
|
|
10951
11368
|
}
|
|
11369
|
+
finishCanvuInteraction("completed", {
|
|
11370
|
+
current: currentInteractionPoint,
|
|
11371
|
+
info
|
|
11372
|
+
});
|
|
10952
11373
|
return;
|
|
10953
11374
|
}
|
|
10954
11375
|
if (st.tool === "rect") {
|
|
10955
|
-
|
|
11376
|
+
info = {
|
|
10956
11377
|
motive: "place",
|
|
10957
11378
|
itemIds: [id],
|
|
10958
11379
|
toolId: st.tool
|
|
10959
|
-
}
|
|
11380
|
+
};
|
|
11381
|
+
change([...itemsRef.current, createRectangleItem(id, raw, pen)], info);
|
|
10960
11382
|
setEffectiveSelectedIdsRef.current([id]);
|
|
10961
11383
|
} else if (st.tool === "ellipse") {
|
|
10962
|
-
|
|
11384
|
+
info = {
|
|
10963
11385
|
motive: "place",
|
|
10964
11386
|
itemIds: [id],
|
|
10965
11387
|
toolId: st.tool
|
|
10966
|
-
}
|
|
11388
|
+
};
|
|
11389
|
+
change([...itemsRef.current, createEllipseItem(id, raw, pen)], info);
|
|
10967
11390
|
setEffectiveSelectedIdsRef.current([id]);
|
|
10968
11391
|
} else if (st.tool === "architectural-cloud") {
|
|
11392
|
+
info = {
|
|
11393
|
+
motive: "place",
|
|
11394
|
+
itemIds: [id],
|
|
11395
|
+
toolId: st.tool
|
|
11396
|
+
};
|
|
10969
11397
|
change(
|
|
10970
11398
|
[...itemsRef.current, createArchitecturalCloudItem(id, raw, pen)],
|
|
10971
|
-
|
|
10972
|
-
motive: "place",
|
|
10973
|
-
itemIds: [id],
|
|
10974
|
-
toolId: st.tool
|
|
10975
|
-
}
|
|
11399
|
+
info
|
|
10976
11400
|
);
|
|
10977
11401
|
setEffectiveSelectedIdsRef.current([id]);
|
|
10978
11402
|
} else if (st.tool === "line" || st.tool === "arrow") {
|
|
10979
11403
|
const line = lineEndpointsToLocal(raw, lineA, lineB);
|
|
11404
|
+
info = {
|
|
11405
|
+
motive: "place",
|
|
11406
|
+
itemIds: [id],
|
|
11407
|
+
toolId: st.tool
|
|
11408
|
+
};
|
|
10980
11409
|
change(
|
|
10981
11410
|
[
|
|
10982
11411
|
...itemsRef.current,
|
|
@@ -10988,15 +11417,15 @@ var VectorViewport = react.forwardRef(
|
|
|
10988
11417
|
pen
|
|
10989
11418
|
)
|
|
10990
11419
|
],
|
|
10991
|
-
|
|
10992
|
-
motive: "place",
|
|
10993
|
-
itemIds: [id],
|
|
10994
|
-
toolId: st.tool
|
|
10995
|
-
}
|
|
11420
|
+
info
|
|
10996
11421
|
);
|
|
10997
11422
|
setEffectiveSelectedIdsRef.current([id]);
|
|
10998
11423
|
}
|
|
10999
11424
|
requestAutoResetTool(st.tool);
|
|
11425
|
+
finishCanvuInteraction("completed", {
|
|
11426
|
+
current: currentInteractionPoint,
|
|
11427
|
+
...info ? { info } : {}
|
|
11428
|
+
});
|
|
11000
11429
|
}
|
|
11001
11430
|
};
|
|
11002
11431
|
document.addEventListener("pointermove", onMove);
|
|
@@ -11014,11 +11443,13 @@ var VectorViewport = react.forwardRef(
|
|
|
11014
11443
|
pruneEraserTrail,
|
|
11015
11444
|
pruneLaserTrail,
|
|
11016
11445
|
finalizeStrokeDragState,
|
|
11446
|
+
finishCanvuInteraction,
|
|
11017
11447
|
renderSceneWithLivePenStroke,
|
|
11018
11448
|
releaseInteractionPointer,
|
|
11019
11449
|
requestAutoResetTool,
|
|
11020
11450
|
screenToWorld,
|
|
11021
11451
|
setStraightStrokeEndpoint,
|
|
11452
|
+
updateCanvuInteractionCurrent,
|
|
11022
11453
|
updateStraightStrokeForMove
|
|
11023
11454
|
]);
|
|
11024
11455
|
const selectedItemsForOverlay = react.useMemo(() => {
|