@oh-just-another/state 0.58.0 → 0.60.0
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 +158 -0
- package/README.md +78 -27
- package/dist/.tsbuildinfo +1 -1
- package/dist/actions/actionArrange.d.ts +13 -0
- package/dist/actions/actionArrange.d.ts.map +1 -0
- package/dist/actions/actionArrange.js +130 -0
- package/dist/actions/actionArrange.js.map +1 -0
- package/dist/actions/actionClipboard.d.ts +2 -0
- package/dist/actions/actionClipboard.d.ts.map +1 -1
- package/dist/actions/actionClipboard.js +32 -1
- package/dist/actions/actionClipboard.js.map +1 -1
- package/dist/actions/actionKeyboard.d.ts.map +1 -1
- package/dist/actions/actionKeyboard.js +77 -9
- package/dist/actions/actionKeyboard.js.map +1 -1
- package/dist/actions/actionMode.d.ts +4 -0
- package/dist/actions/actionMode.d.ts.map +1 -1
- package/dist/actions/actionMode.js +54 -0
- package/dist/actions/actionMode.js.map +1 -1
- package/dist/actions/actionSelection.d.ts.map +1 -1
- package/dist/actions/actionSelection.js +1 -0
- package/dist/actions/actionSelection.js.map +1 -1
- package/dist/actions/actionText.d.ts +5 -0
- package/dist/actions/actionText.d.ts.map +1 -0
- package/dist/actions/actionText.js +37 -0
- package/dist/actions/actionText.js.map +1 -0
- package/dist/actions/actionView.d.ts +6 -0
- package/dist/actions/actionView.d.ts.map +1 -1
- package/dist/actions/actionView.js +20 -2
- package/dist/actions/actionView.js.map +1 -1
- package/dist/actions/actionZoom.d.ts.map +1 -1
- package/dist/actions/actionZoom.js +5 -0
- package/dist/actions/actionZoom.js.map +1 -1
- package/dist/actions/index.d.ts +6 -4
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +6 -4
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/registry.d.ts.map +1 -1
- package/dist/actions/registry.js +17 -0
- package/dist/actions/registry.js.map +1 -1
- package/dist/actions/types.d.ts +10 -1
- package/dist/actions/types.d.ts.map +1 -1
- package/dist/actions/types.js.map +1 -1
- package/dist/auto-layout-scheduler.d.ts +1 -3
- package/dist/auto-layout-scheduler.d.ts.map +1 -1
- package/dist/auto-layout-scheduler.js +1 -2
- package/dist/auto-layout-scheduler.js.map +1 -1
- package/dist/built-in-handlers.d.ts.map +1 -1
- package/dist/built-in-handlers.js +14 -1
- package/dist/built-in-handlers.js.map +1 -1
- package/dist/clipboard.d.ts +0 -14
- package/dist/clipboard.d.ts.map +1 -1
- package/dist/clipboard.js +1 -1
- package/dist/clipboard.js.map +1 -1
- package/dist/constants.d.ts +208 -41
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +210 -25
- package/dist/constants.js.map +1 -1
- package/dist/dom-events.d.ts +8 -2
- package/dist/dom-events.d.ts.map +1 -1
- package/dist/dom-events.js +12 -0
- package/dist/dom-events.js.map +1 -1
- package/dist/editor/animation-scene.d.ts +36 -0
- package/dist/editor/animation-scene.d.ts.map +1 -0
- package/dist/editor/animation-scene.js +194 -0
- package/dist/editor/animation-scene.js.map +1 -0
- package/dist/editor/animation.d.ts +43 -0
- package/dist/editor/animation.d.ts.map +1 -0
- package/dist/editor/animation.js +80 -0
- package/dist/editor/animation.js.map +1 -0
- package/dist/editor/applies/arrange.d.ts +46 -0
- package/dist/editor/applies/arrange.d.ts.map +1 -0
- package/dist/editor/applies/arrange.js +162 -0
- package/dist/editor/applies/arrange.js.map +1 -0
- package/dist/editor/applies/create.d.ts +0 -6
- package/dist/editor/applies/create.d.ts.map +1 -1
- package/dist/editor/applies/create.js +1 -1
- package/dist/editor/applies/create.js.map +1 -1
- package/dist/editor/applies/edge.d.ts +8 -1
- package/dist/editor/applies/edge.d.ts.map +1 -1
- package/dist/editor/applies/edge.js +31 -1
- package/dist/editor/applies/edge.js.map +1 -1
- package/dist/editor/applies/link-move.d.ts +0 -8
- package/dist/editor/applies/link-move.d.ts.map +1 -1
- package/dist/editor/applies/link-move.js +1 -1
- package/dist/editor/applies/link-move.js.map +1 -1
- package/dist/editor/applies/move.d.ts +6 -0
- package/dist/editor/applies/move.d.ts.map +1 -1
- package/dist/editor/applies/move.js +6 -0
- package/dist/editor/applies/move.js.map +1 -1
- package/dist/editor/applies/resize.d.ts +26 -5
- package/dist/editor/applies/resize.d.ts.map +1 -1
- package/dist/editor/applies/resize.js +91 -13
- package/dist/editor/applies/resize.js.map +1 -1
- package/dist/editor/caret-blink.d.ts +18 -0
- package/dist/editor/caret-blink.d.ts.map +1 -0
- package/dist/editor/caret-blink.js +42 -0
- package/dist/editor/caret-blink.js.map +1 -0
- package/dist/editor/container-ops.d.ts.map +1 -1
- package/dist/editor/container-ops.js +2 -2
- package/dist/editor/container-ops.js.map +1 -1
- package/dist/editor/dirty-rect.d.ts +23 -0
- package/dist/editor/dirty-rect.d.ts.map +1 -0
- package/dist/editor/dirty-rect.js +115 -0
- package/dist/editor/dirty-rect.js.map +1 -0
- package/dist/editor/gif-playback.d.ts +45 -0
- package/dist/editor/gif-playback.d.ts.map +1 -0
- package/dist/editor/gif-playback.js +125 -0
- package/dist/editor/gif-playback.js.map +1 -0
- package/dist/editor/hit-test.d.ts +3 -3
- package/dist/editor/hit-test.d.ts.map +1 -1
- package/dist/editor/hit-test.js +40 -15
- package/dist/editor/hit-test.js.map +1 -1
- package/dist/editor/interaction-state.d.ts +184 -0
- package/dist/editor/interaction-state.d.ts.map +1 -0
- package/dist/editor/interaction-state.js +139 -0
- package/dist/editor/interaction-state.js.map +1 -0
- package/dist/editor/link-handle-drag.d.ts +152 -0
- package/dist/editor/link-handle-drag.d.ts.map +1 -0
- package/dist/editor/link-handle-drag.js +300 -0
- package/dist/editor/link-handle-drag.js.map +1 -0
- package/dist/editor/long-press.d.ts.map +1 -1
- package/dist/editor/long-press.js +2 -2
- package/dist/editor/long-press.js.map +1 -1
- package/dist/editor/pinch.d.ts.map +1 -1
- package/dist/editor/pinch.js +6 -6
- package/dist/editor/pinch.js.map +1 -1
- package/dist/editor/pointer-binding.d.ts +9 -11
- package/dist/editor/pointer-binding.d.ts.map +1 -1
- package/dist/editor/pointer-binding.js +1191 -890
- package/dist/editor/pointer-binding.js.map +1 -1
- package/dist/editor/public/arrange-group.d.ts +3 -9
- package/dist/editor/public/arrange-group.d.ts.map +1 -1
- package/dist/editor/public/arrange-group.js +4 -6
- package/dist/editor/public/arrange-group.js.map +1 -1
- package/dist/editor/public/brush.d.ts +31 -12
- package/dist/editor/public/brush.d.ts.map +1 -1
- package/dist/editor/public/brush.js +66 -17
- package/dist/editor/public/brush.js.map +1 -1
- package/dist/editor/public/clipboard.d.ts +2 -4
- package/dist/editor/public/clipboard.d.ts.map +1 -1
- package/dist/editor/public/clipboard.js +2 -4
- package/dist/editor/public/clipboard.js.map +1 -1
- package/dist/editor/public/cursor.d.ts +29 -0
- package/dist/editor/public/cursor.d.ts.map +1 -0
- package/dist/editor/public/cursor.js +146 -0
- package/dist/editor/public/cursor.js.map +1 -0
- package/dist/editor/public/eraser.d.ts +55 -0
- package/dist/editor/public/eraser.d.ts.map +1 -0
- package/dist/editor/public/eraser.js +65 -0
- package/dist/editor/public/eraser.js.map +1 -0
- package/dist/editor/public/frame-name.d.ts +20 -0
- package/dist/editor/public/frame-name.d.ts.map +1 -0
- package/dist/editor/public/frame-name.js +54 -0
- package/dist/editor/public/frame-name.js.map +1 -0
- package/dist/editor/public/image-insert.d.ts +1 -1
- package/dist/editor/public/image-insert.d.ts.map +1 -1
- package/dist/editor/public/laser.d.ts +38 -0
- package/dist/editor/public/laser.d.ts.map +1 -0
- package/dist/editor/public/laser.js +42 -0
- package/dist/editor/public/laser.js.map +1 -0
- package/dist/editor/public/layers.d.ts.map +1 -1
- package/dist/editor/public/layers.js +2 -2
- package/dist/editor/public/layers.js.map +1 -1
- package/dist/editor/public/link.d.ts +11 -2
- package/dist/editor/public/link.d.ts.map +1 -1
- package/dist/editor/public/link.js +70 -2
- package/dist/editor/public/link.js.map +1 -1
- package/dist/editor/public/placement.d.ts +60 -2
- package/dist/editor/public/placement.d.ts.map +1 -1
- package/dist/editor/public/placement.js +193 -2
- package/dist/editor/public/placement.js.map +1 -1
- package/dist/editor/public/selection-ops.d.ts +35 -1
- package/dist/editor/public/selection-ops.d.ts.map +1 -1
- package/dist/editor/public/selection-ops.js +97 -2
- package/dist/editor/public/selection-ops.js.map +1 -1
- package/dist/editor/public/stroke-eraser-coverage.d.ts +37 -0
- package/dist/editor/public/stroke-eraser-coverage.d.ts.map +1 -0
- package/dist/editor/public/stroke-eraser-coverage.js +168 -0
- package/dist/editor/public/stroke-eraser-coverage.js.map +1 -0
- package/dist/editor/public/stroke-eraser.d.ts +50 -0
- package/dist/editor/public/stroke-eraser.d.ts.map +1 -0
- package/dist/editor/public/stroke-eraser.js +176 -0
- package/dist/editor/public/stroke-eraser.js.map +1 -0
- package/dist/editor/public/stroke-smoothing.d.ts +21 -0
- package/dist/editor/public/stroke-smoothing.d.ts.map +1 -0
- package/dist/editor/public/stroke-smoothing.js +37 -0
- package/dist/editor/public/stroke-smoothing.js.map +1 -0
- package/dist/editor/public/text-edit.d.ts +1 -10
- package/dist/editor/public/text-edit.d.ts.map +1 -1
- package/dist/editor/public/text-edit.js +2 -16
- package/dist/editor/public/text-edit.js.map +1 -1
- package/dist/editor/public/tool-ops.d.ts +130 -0
- package/dist/editor/public/tool-ops.d.ts.map +1 -0
- package/dist/editor/public/tool-ops.js +392 -0
- package/dist/editor/public/tool-ops.js.map +1 -0
- package/dist/editor/public/z-order.d.ts +1 -12
- package/dist/editor/public/z-order.d.ts.map +1 -1
- package/dist/editor/public/z-order.js +5 -5
- package/dist/editor/public/z-order.js.map +1 -1
- package/dist/editor/public/zoom-pan.d.ts +15 -4
- package/dist/editor/public/zoom-pan.d.ts.map +1 -1
- package/dist/editor/public/zoom-pan.js +39 -7
- package/dist/editor/public/zoom-pan.js.map +1 -1
- package/dist/editor/render-orchestrator.d.ts +177 -5
- package/dist/editor/render-orchestrator.d.ts.map +1 -1
- package/dist/editor/render-orchestrator.js +519 -358
- package/dist/editor/render-orchestrator.js.map +1 -1
- package/dist/editor/resize-helpers.d.ts +21 -5
- package/dist/editor/resize-helpers.d.ts.map +1 -1
- package/dist/editor/resize-helpers.js +59 -19
- package/dist/editor/resize-helpers.js.map +1 -1
- package/dist/editor/text-edit.d.ts +136 -0
- package/dist/editor/text-edit.d.ts.map +1 -0
- package/dist/editor/text-edit.js +328 -0
- package/dist/editor/text-edit.js.map +1 -0
- package/dist/editor/viewport-helpers.d.ts.map +1 -1
- package/dist/editor/viewport-helpers.js +3 -3
- package/dist/editor/viewport-helpers.js.map +1 -1
- package/dist/editor-events.d.ts +1 -1
- package/dist/editor-events.d.ts.map +1 -1
- package/dist/editor.d.ts +603 -346
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +1843 -1630
- package/dist/editor.js.map +1 -1
- package/dist/file-drop.d.ts.map +1 -1
- package/dist/file-drop.js +1 -2
- package/dist/file-drop.js.map +1 -1
- package/dist/frame-helpers.d.ts.map +1 -1
- package/dist/frame-helpers.js +5 -5
- package/dist/frame-helpers.js.map +1 -1
- package/dist/group-helpers.d.ts.map +1 -1
- package/dist/group-helpers.js +4 -4
- package/dist/group-helpers.js.map +1 -1
- package/dist/handle.d.ts +59 -6
- package/dist/handle.d.ts.map +1 -1
- package/dist/handle.js +99 -7
- package/dist/handle.js.map +1 -1
- package/dist/hotkeys-binding.d.ts +26 -0
- package/dist/hotkeys-binding.d.ts.map +1 -0
- package/dist/hotkeys-binding.js +35 -0
- package/dist/hotkeys-binding.js.map +1 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -3
- package/dist/index.js.map +1 -1
- package/dist/link-selection.d.ts +3 -5
- package/dist/link-selection.d.ts.map +1 -1
- package/dist/link-selection.js +3 -12
- package/dist/link-selection.js.map +1 -1
- package/dist/machine.d.ts +27 -1
- package/dist/machine.d.ts.map +1 -1
- package/dist/machine.js +38 -0
- package/dist/machine.js.map +1 -1
- package/dist/modes.d.ts +15 -1
- package/dist/modes.d.ts.map +1 -1
- package/dist/modes.js.map +1 -1
- package/dist/overlay.d.ts +92 -6
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +582 -125
- package/dist/overlay.js.map +1 -1
- package/dist/search.d.ts +37 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +45 -0
- package/dist/search.js.map +1 -0
- package/dist/selection.d.ts.map +1 -1
- package/dist/selection.js +2 -10
- package/dist/selection.js.map +1 -1
- package/dist/util.d.ts +8 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +17 -0
- package/dist/util.js.map +1 -0
- package/package.json +7 -7
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { getElement } from "@oh-just-another/scene";
|
|
2
|
+
import { cursorForHandle } from "../../handle.js";
|
|
3
|
+
import { ANCHOR_DOT_ACTIVE_RADIUS, LINK_START_ANCHOR_OUTSET } from "../../constants.js";
|
|
4
|
+
import { anchorOverlayPoints } from "../anchor-points.js";
|
|
5
|
+
/** Resize handle → cursor override role. */
|
|
6
|
+
const RESIZE_ROLE = {
|
|
7
|
+
nw: "resize-nwse",
|
|
8
|
+
se: "resize-nwse",
|
|
9
|
+
ne: "resize-nesw",
|
|
10
|
+
sw: "resize-nesw",
|
|
11
|
+
n: "resize-ns",
|
|
12
|
+
s: "resize-ns",
|
|
13
|
+
e: "resize-ew",
|
|
14
|
+
w: "resize-ew",
|
|
15
|
+
};
|
|
16
|
+
/** Build a CSS `cursor` value from a {@link CursorSpec}. */
|
|
17
|
+
const cssCursor = (spec, fallbackKeyword) => {
|
|
18
|
+
if (typeof spec === "string")
|
|
19
|
+
return spec;
|
|
20
|
+
const hx = spec.hotspot?.x ?? 0;
|
|
21
|
+
const hy = spec.hotspot?.y ?? 0;
|
|
22
|
+
const img = spec.url2x !== undefined
|
|
23
|
+
? `image-set(url("${spec.url}") 1x, url("${spec.url2x}") 2x)`
|
|
24
|
+
: `url("${spec.url}")`;
|
|
25
|
+
return `${img} ${String(hx)} ${String(hy)}, ${spec.fallback ?? fallbackKeyword}`;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Resolve a cursor role to a CSS `cursor` value: a host-registered custom image
|
|
29
|
+
* (via {@link Editor.setCursorOverride}) if present, else `fallbackKeyword`.
|
|
30
|
+
*/
|
|
31
|
+
const resolveCursor = (editor, role, fallbackKeyword) => {
|
|
32
|
+
const spec = editor.getCursorOverride(role);
|
|
33
|
+
return spec === undefined ? fallbackKeyword : cssCursor(spec, fallbackKeyword);
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* True when `p` is within the grab radius of one of the single selected
|
|
37
|
+
* element's link-start dots — used to show a `crosshair` (start a link).
|
|
38
|
+
* Mirrors the anchor-drag hit-test in pointer-binding so the cursor matches
|
|
39
|
+
* exactly where a press would begin a link.
|
|
40
|
+
*/
|
|
41
|
+
const isOverLinkStartDot = (editor, p) => {
|
|
42
|
+
if (editor.mode !== "select" || editor._selection.size !== 1)
|
|
43
|
+
return false;
|
|
44
|
+
const id = [...editor._selection][0];
|
|
45
|
+
if (id === undefined)
|
|
46
|
+
return false;
|
|
47
|
+
const shape = getElement(editor._scene, id);
|
|
48
|
+
if (!shape)
|
|
49
|
+
return false;
|
|
50
|
+
const zoom = editor._scene.viewport.zoom || 1;
|
|
51
|
+
const { worldPoints } = anchorOverlayPoints(shape, LINK_START_ANCHOR_OUTSET / zoom);
|
|
52
|
+
const grab = (ANCHOR_DOT_ACTIVE_RADIUS + editor.anchorStartHitSlop) / zoom;
|
|
53
|
+
const grab2 = grab * grab;
|
|
54
|
+
for (const wp of worldPoints) {
|
|
55
|
+
const dx = wp.x - p.x;
|
|
56
|
+
const dy = wp.y - p.y;
|
|
57
|
+
if (dx * dx + dy * dy <= grab2)
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* The CSS cursor for the current interaction state. Priority: active gesture →
|
|
64
|
+
* text edit → pan affordance → draw tool → idle hover hit-test. Pure read of
|
|
65
|
+
* editor state; no side effects.
|
|
66
|
+
*/
|
|
67
|
+
export const computeCursor = (editor, p) => {
|
|
68
|
+
// Each outcome is a (role, fallback-keyword) pair; `resolveCursor` returns a
|
|
69
|
+
// host-registered custom image for that role if one exists, else the keyword.
|
|
70
|
+
const r = (role, keyword) => resolveCursor(editor, role, keyword);
|
|
71
|
+
const resizeRole = (h) => r(RESIZE_ROLE[h], cursorForHandle(h));
|
|
72
|
+
// 1. Active gestures (highest priority — what the pointer is doing now).
|
|
73
|
+
if (editor.panGesture)
|
|
74
|
+
return r("pan-active", "grabbing");
|
|
75
|
+
if (editor.linkDragFromAnchor?.moved === true)
|
|
76
|
+
return r("draw", "crosshair");
|
|
77
|
+
if (editor.isDraggingWaypoint || editor.isDraggingSegment)
|
|
78
|
+
return r("move", "grabbing");
|
|
79
|
+
if (editor.annotationDrag?.moved === true)
|
|
80
|
+
return r("move", "grabbing");
|
|
81
|
+
if (editor.brushStroke)
|
|
82
|
+
return r("draw", "crosshair");
|
|
83
|
+
// Machine-driven drag past the threshold (`gestureTx` opens then): resize
|
|
84
|
+
// shows the handle's arrow; element / link move shows grabbing.
|
|
85
|
+
if (editor.gestureTx) {
|
|
86
|
+
const t = editor.actor.getSnapshot().context.pressTarget;
|
|
87
|
+
if (t && (t.kind === "handle" || t.kind === "group-handle"))
|
|
88
|
+
return resizeRole(t.handle);
|
|
89
|
+
if (t?.kind === "rotate-handle")
|
|
90
|
+
return r("rotate", "grabbing");
|
|
91
|
+
if (t && (t.kind === "element" || t.kind === "link" || t.kind === "edge-endpoint")) {
|
|
92
|
+
return r("move", "grabbing");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// 1b. Armed colour-picker pipette → crosshair, waiting for the pick click.
|
|
96
|
+
if (editor.isEyedropperArmed)
|
|
97
|
+
return r("draw", "crosshair");
|
|
98
|
+
// 2. In-canvas text editing → I-beam.
|
|
99
|
+
if (editor.editingTextElement !== null)
|
|
100
|
+
return r("text", "text");
|
|
101
|
+
// 3. Pan affordance (idle): Space held or hand tool.
|
|
102
|
+
if (editor.spaceHeld || editor.mode === "hand")
|
|
103
|
+
return r("pan-ready", "grab");
|
|
104
|
+
// 4. Draw tools (idle, before a gesture starts).
|
|
105
|
+
switch (editor.mode) {
|
|
106
|
+
case "draw-rect":
|
|
107
|
+
case "draw-ellipse":
|
|
108
|
+
case "draw-frame":
|
|
109
|
+
case "draw-edge":
|
|
110
|
+
case "brush":
|
|
111
|
+
case "laser":
|
|
112
|
+
case "eyedropper":
|
|
113
|
+
case "crop":
|
|
114
|
+
return r("draw", "crosshair");
|
|
115
|
+
// Erase hides the OS cursor: the overlay paints a size-matched ring (and a
|
|
116
|
+
// fading trail while dragging) in its place, so `none` lets that composite
|
|
117
|
+
// cleanly at any radius.
|
|
118
|
+
case "erase":
|
|
119
|
+
return r("erase", "none");
|
|
120
|
+
case "draw-text":
|
|
121
|
+
return r("text", "text");
|
|
122
|
+
default:
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
// 5. Idle hover in select mode — key off the hit-test target.
|
|
126
|
+
if (p) {
|
|
127
|
+
if (isOverLinkStartDot(editor, p))
|
|
128
|
+
return r("link-start", "crosshair");
|
|
129
|
+
const t = editor.hitTest(p);
|
|
130
|
+
switch (t.kind) {
|
|
131
|
+
case "handle":
|
|
132
|
+
case "group-handle":
|
|
133
|
+
return resizeRole(t.handle);
|
|
134
|
+
case "rotate-handle":
|
|
135
|
+
return r("rotate", "grab");
|
|
136
|
+
case "edge-endpoint":
|
|
137
|
+
return r("link-handle", "grab");
|
|
138
|
+
case "annotation":
|
|
139
|
+
return r("annotation", "pointer");
|
|
140
|
+
default:
|
|
141
|
+
return r("default", "default");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return r("default", "default");
|
|
145
|
+
};
|
|
146
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../../src/editor/public/cursor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Element, Scene, Patch } from "@oh-just-another/scene";
|
|
2
|
+
import type { ElementId, Vec2 } from "@oh-just-another/types";
|
|
3
|
+
import type { Interval } from "./stroke-eraser-coverage.js";
|
|
4
|
+
/**
|
|
5
|
+
* Mutable state of an in-progress eraser stroke. The editor owns one instance
|
|
6
|
+
* and delegates the four lifecycle calls (begin / extend / commit / cancel)
|
|
7
|
+
* through it. `pending` is the set of element ids swept so far (previewed
|
|
8
|
+
* dimmed, deleted on release); `last` is the previous sampled world point so
|
|
9
|
+
* the next extend can sample the segment between them.
|
|
10
|
+
*
|
|
11
|
+
* `strokeMode` (Shift held at press) switches the gesture to STROKE-ERASE:
|
|
12
|
+
* brush strokes are cut into fragments instead of deleted whole; non-brush
|
|
13
|
+
* shapes still object-erase. `erased` maps each touched brush id to the covered
|
|
14
|
+
* arc-length spans erased so far — the editor grows it INCREMENTALLY (each move
|
|
15
|
+
* accumulates only the new segment via `markErasedIntervals`), so the cost per
|
|
16
|
+
* move is O(points) instead of O(points × path length) per frame. The eraser cuts
|
|
17
|
+
* the stroke's GEOMETRY by arc length, not by vertex, so a big disc grazing a
|
|
18
|
+
* sparse line still removes the covered span. Unused in object mode.
|
|
19
|
+
*/
|
|
20
|
+
export interface EraseStrokeState {
|
|
21
|
+
readonly pending: Set<ElementId>;
|
|
22
|
+
last: Vec2;
|
|
23
|
+
/** Per-brush covered arc-length spans, grown incrementally in stroke mode. */
|
|
24
|
+
readonly erased: Map<ElementId, Interval[]>;
|
|
25
|
+
/** Shift held at press: cut brush strokes instead of deleting them. */
|
|
26
|
+
readonly strokeMode: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare const beginEraseStroke: (world: Vec2, strokeMode?: boolean) => EraseStrokeState;
|
|
29
|
+
/**
|
|
30
|
+
* Sample points along the segment `from → to` at {@link ERASER_SAMPLE_STEP}
|
|
31
|
+
* spacing, hit-test each through `hitAt`, and mark every hit element in
|
|
32
|
+
* `pending`. Sampling (rather than testing only the endpoint) stops a fast
|
|
33
|
+
* swipe from skipping small shapes between two pointer-move events.
|
|
34
|
+
*
|
|
35
|
+
* `restore` flips the direction: normally hits are ADDED to `pending`
|
|
36
|
+
* (marked-for-erase); with `restore` (Alt held) a hit already in `pending` is
|
|
37
|
+
* REMOVED (un-marked), so dragging back over a marked shape with Alt rescues it
|
|
38
|
+
* — matching the Excalidraw eraser. Returns `true` when `pending` changed (so
|
|
39
|
+
* the caller can skip a redundant re-render). Mutates `pending` in place.
|
|
40
|
+
*
|
|
41
|
+
* In `strokeMode` (Shift), brush hits are skipped here — brushes are cut by the
|
|
42
|
+
* path-based stroke-erase on commit, not added to the object-delete `pending`.
|
|
43
|
+
*/
|
|
44
|
+
export declare const sampleErase: (from: Vec2, to: Vec2, hitAt: (p: Vec2) => Element | undefined, pending: Set<ElementId>, restore?: boolean, strokeMode?: boolean) => boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Produce the scene + patches that delete every id in `pending` (dropping any
|
|
47
|
+
* attached links first, exactly like a Delete-key delete). Returns `null` when
|
|
48
|
+
* nothing valid remains to erase. Reuses {@link computeDeleteSelection} so the
|
|
49
|
+
* eraser and the selection-delete share one implementation.
|
|
50
|
+
*/
|
|
51
|
+
export declare const computeEraseCommit: (scene: Scene, pending: ReadonlySet<ElementId>) => {
|
|
52
|
+
readonly scene: Scene;
|
|
53
|
+
readonly patches: Patch[];
|
|
54
|
+
} | null;
|
|
55
|
+
//# sourceMappingURL=eraser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eraser.d.ts","sourceRoot":"","sources":["../../../src/editor/public/eraser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAI9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAE5D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;IACjC,IAAI,EAAE,IAAI,CAAC;IACX,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5C,uEAAuE;IACvE,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED,eAAO,MAAM,gBAAgB,GAAI,OAAO,IAAI,EAAE,oBAAkB,KAAG,gBAKjE,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,WAAW,GACtB,MAAM,IAAI,EACV,IAAI,IAAI,EACR,OAAO,CAAC,CAAC,EAAE,IAAI,KAAK,OAAO,GAAG,SAAS,EACvC,SAAS,GAAG,CAAC,SAAS,CAAC,EACvB,iBAAe,EACf,oBAAkB,KACjB,OAmBF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,OAAO,KAAK,EACZ,SAAS,WAAW,CAAC,SAAS,CAAC,KAC9B;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAA;CAAE,GAAG,IAOzD,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as Selection from "../../selection.js";
|
|
2
|
+
import { computeDeleteSelection } from "./selection-ops.js";
|
|
3
|
+
import { ERASER_SAMPLE_STEP } from "../../constants.js";
|
|
4
|
+
export const beginEraseStroke = (world, strokeMode = false) => ({
|
|
5
|
+
pending: new Set(),
|
|
6
|
+
last: world,
|
|
7
|
+
erased: new Map(),
|
|
8
|
+
strokeMode,
|
|
9
|
+
});
|
|
10
|
+
/**
|
|
11
|
+
* Sample points along the segment `from → to` at {@link ERASER_SAMPLE_STEP}
|
|
12
|
+
* spacing, hit-test each through `hitAt`, and mark every hit element in
|
|
13
|
+
* `pending`. Sampling (rather than testing only the endpoint) stops a fast
|
|
14
|
+
* swipe from skipping small shapes between two pointer-move events.
|
|
15
|
+
*
|
|
16
|
+
* `restore` flips the direction: normally hits are ADDED to `pending`
|
|
17
|
+
* (marked-for-erase); with `restore` (Alt held) a hit already in `pending` is
|
|
18
|
+
* REMOVED (un-marked), so dragging back over a marked shape with Alt rescues it
|
|
19
|
+
* — matching the Excalidraw eraser. Returns `true` when `pending` changed (so
|
|
20
|
+
* the caller can skip a redundant re-render). Mutates `pending` in place.
|
|
21
|
+
*
|
|
22
|
+
* In `strokeMode` (Shift), brush hits are skipped here — brushes are cut by the
|
|
23
|
+
* path-based stroke-erase on commit, not added to the object-delete `pending`.
|
|
24
|
+
*/
|
|
25
|
+
export const sampleErase = (from, to, hitAt, pending, restore = false, strokeMode = false) => {
|
|
26
|
+
const dx = to.x - from.x;
|
|
27
|
+
const dy = to.y - from.y;
|
|
28
|
+
const dist = Math.hypot(dx, dy);
|
|
29
|
+
const steps = Math.max(1, Math.ceil(dist / ERASER_SAMPLE_STEP));
|
|
30
|
+
let changed = false;
|
|
31
|
+
for (let i = 1; i <= steps; i++) {
|
|
32
|
+
const t = i / steps;
|
|
33
|
+
const hit = hitAt({ x: from.x + dx * t, y: from.y + dy * t });
|
|
34
|
+
if (!hit)
|
|
35
|
+
continue;
|
|
36
|
+
if (strokeMode && hit.type === "brush")
|
|
37
|
+
continue;
|
|
38
|
+
if (restore) {
|
|
39
|
+
if (pending.delete(hit.id))
|
|
40
|
+
changed = true;
|
|
41
|
+
}
|
|
42
|
+
else if (!pending.has(hit.id)) {
|
|
43
|
+
pending.add(hit.id);
|
|
44
|
+
changed = true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return changed;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Produce the scene + patches that delete every id in `pending` (dropping any
|
|
51
|
+
* attached links first, exactly like a Delete-key delete). Returns `null` when
|
|
52
|
+
* nothing valid remains to erase. Reuses {@link computeDeleteSelection} so the
|
|
53
|
+
* eraser and the selection-delete share one implementation.
|
|
54
|
+
*/
|
|
55
|
+
export const computeEraseCommit = (scene, pending) => {
|
|
56
|
+
let sel = Selection.EMPTY;
|
|
57
|
+
for (const id of pending) {
|
|
58
|
+
if (scene.elements.has(id))
|
|
59
|
+
sel = Selection.add(sel, id);
|
|
60
|
+
}
|
|
61
|
+
if (sel.size === 0)
|
|
62
|
+
return null;
|
|
63
|
+
return computeDeleteSelection(scene, sel, new Set());
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=eraser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eraser.js","sourceRoot":"","sources":["../../../src/editor/public/eraser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AA4BxD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAW,EAAE,UAAU,GAAG,KAAK,EAAoB,EAAE,CAAC,CAAC;IACtF,OAAO,EAAE,IAAI,GAAG,EAAa;IAC7B,IAAI,EAAE,KAAK;IACX,MAAM,EAAE,IAAI,GAAG,EAAyB;IACxC,UAAU;CACX,CAAC,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,IAAU,EACV,EAAQ,EACR,KAAuC,EACvC,OAAuB,EACvB,OAAO,GAAG,KAAK,EACf,UAAU,GAAG,KAAK,EACT,EAAE;IACX,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACzB,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACzB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC,CAAC,CAAC;IAChE,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACpB,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,IAAI,UAAU,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;YAAE,SAAS;QACjD,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,OAAO,GAAG,IAAI,CAAC;QAC7C,CAAC;aAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpB,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,KAAY,EACZ,OAA+B,EAC8B,EAAE;IAC/D,IAAI,GAAG,GAAwB,SAAS,CAAC,KAAK,CAAC;IAC/C,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,sBAAsB,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;AACvD,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Scene, type Patch } from "@oh-just-another/scene";
|
|
2
|
+
import type { ElementId, Vec2 } from "@oh-just-another/types";
|
|
3
|
+
/**
|
|
4
|
+
* Frame whose header strip (the label bar ABOVE the body) contains the world
|
|
5
|
+
* point — top-most by z-order. Used to route a double-click on the header to a
|
|
6
|
+
* name edit, since the header sits outside the frame's hit-test bounds. Assumes
|
|
7
|
+
* unrotated frames (the common case).
|
|
8
|
+
*/
|
|
9
|
+
export declare const frameHeaderAt: (scene: Scene, p: Vec2) => ElementId | null;
|
|
10
|
+
/**
|
|
11
|
+
* Compute the patch committing an edited frame name. Empty / whitespace-only
|
|
12
|
+
* clears the stored name (the renderer falls back to "Frame"). Returns `null`
|
|
13
|
+
* when the shape isn't a frame or the name is unchanged — the caller still
|
|
14
|
+
* clears the editing state and notifies.
|
|
15
|
+
*/
|
|
16
|
+
export declare const computeFrameNameCommit: (scene: Scene, id: ElementId, name: string) => {
|
|
17
|
+
readonly scene: Scene;
|
|
18
|
+
readonly patch: Patch;
|
|
19
|
+
} | null;
|
|
20
|
+
//# sourceMappingURL=frame-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-name.d.ts","sourceRoot":"","sources":["../../../src/editor/public/frame-name.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,KAAK,EACV,KAAK,KAAK,EACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,EAAE,GAAG,IAAI,KAAG,SAAS,GAAG,IAmBjE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GACjC,OAAO,KAAK,EACZ,IAAI,SAAS,EACb,MAAM,MAAM,KACX;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG,IAcrD,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { getElement, updateElement, isFrame, FRAME_HEADER_HEIGHT, } from "@oh-just-another/scene";
|
|
2
|
+
/**
|
|
3
|
+
* Frame whose header strip (the label bar ABOVE the body) contains the world
|
|
4
|
+
* point — top-most by z-order. Used to route a double-click on the header to a
|
|
5
|
+
* name edit, since the header sits outside the frame's hit-test bounds. Assumes
|
|
6
|
+
* unrotated frames (the common case).
|
|
7
|
+
*/
|
|
8
|
+
export const frameHeaderAt = (scene, p) => {
|
|
9
|
+
let bestId = null;
|
|
10
|
+
let bestOrder = "";
|
|
11
|
+
for (const s of scene.elements.values()) {
|
|
12
|
+
if (!isFrame(s))
|
|
13
|
+
continue;
|
|
14
|
+
const hx = s.position.x;
|
|
15
|
+
// The header strip can extend up to the frame's full width (it hugs the
|
|
16
|
+
// label but is capped there), so the rename hit zone spans it.
|
|
17
|
+
const hw = s.width * s.scale.x;
|
|
18
|
+
const hh = FRAME_HEADER_HEIGHT * s.scale.y;
|
|
19
|
+
const hyTop = s.position.y - hh;
|
|
20
|
+
if (p.x >= hx && p.x <= hx + hw && p.y >= hyTop && p.y <= hyTop + hh) {
|
|
21
|
+
if (bestId === null || s.order > bestOrder) {
|
|
22
|
+
bestId = s.id;
|
|
23
|
+
bestOrder = s.order;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return bestId;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Compute the patch committing an edited frame name. Empty / whitespace-only
|
|
31
|
+
* clears the stored name (the renderer falls back to "Frame"). Returns `null`
|
|
32
|
+
* when the shape isn't a frame or the name is unchanged — the caller still
|
|
33
|
+
* clears the editing state and notifies.
|
|
34
|
+
*/
|
|
35
|
+
export const computeFrameNameCommit = (scene, id, name) => {
|
|
36
|
+
const shape = getElement(scene, id);
|
|
37
|
+
if (shape === undefined || !isFrame(shape))
|
|
38
|
+
return null;
|
|
39
|
+
const trimmed = name.trim();
|
|
40
|
+
const current = shape.name ?? "";
|
|
41
|
+
if (trimmed === current)
|
|
42
|
+
return null;
|
|
43
|
+
const r = updateElement(scene, id, (s) => {
|
|
44
|
+
const copy = { ...s };
|
|
45
|
+
// `exactOptionalPropertyTypes`: drop the key when cleared.
|
|
46
|
+
if (trimmed === "")
|
|
47
|
+
delete copy.name;
|
|
48
|
+
else
|
|
49
|
+
copy.name = trimmed;
|
|
50
|
+
return copy;
|
|
51
|
+
});
|
|
52
|
+
return { scene: r.scene, patch: r.patch };
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=frame-name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-name.js","sourceRoot":"","sources":["../../../src/editor/public/frame-name.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,aAAa,EACb,OAAO,EACP,mBAAmB,GAGpB,MAAM,wBAAwB,CAAC;AAGhC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAY,EAAE,CAAO,EAAoB,EAAE;IACvE,IAAI,MAAM,GAAqB,IAAI,CAAC;IACpC,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QACxC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YAAE,SAAS;QAC1B,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACxB,wEAAwE;QACxE,+DAA+D;QAC/D,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/B,MAAM,EAAE,GAAG,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC;QAChC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;YACrE,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,GAAG,SAAS,EAAE,CAAC;gBAC3C,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;gBACd,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,KAAY,EACZ,EAAa,EACb,IAAY,EAC6C,EAAE;IAC3D,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACpC,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACxD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAI,KAA2B,CAAC,IAAI,IAAI,EAAE,CAAC;IACxD,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,CAAC,GAAG,aAAa,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE;QACvC,MAAM,IAAI,GAAG,EAAE,GAAG,CAAC,EAAkC,CAAC;QACtD,2DAA2D;QAC3D,IAAI,OAAO,KAAK,EAAE;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC;;YAChC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;AAC5C,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-insert.d.ts","sourceRoot":"","sources":["../../../src/editor/public/image-insert.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,KAAK,EACV,KAAK,OAAO,EACZ,KAAK,KAAK,EAEX,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAG/E;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAC5B,OAAO,KAAK,EACZ,OAAO;IACL,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,CAAC,EAAE,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"image-insert.d.ts","sourceRoot":"","sources":["../../../src/editor/public/image-insert.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,KAAK,EACV,KAAK,OAAO,EACZ,KAAK,KAAK,EAEX,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAG/E;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAC5B,OAAO,KAAK,EACZ,OAAO;IACL,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,CAAC,EAAE,WAAW,GAAG,gBAAgB,CAAC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,EACD,IAAI,SAAS,EACb,SAAS,OAAO,KACf,OA0BF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,KAAK,EACZ,MAAM,IAAI,EACV,MAAM,MAAM,GAAG,SAAS,EACxB,YAAY,MAAM,MAAM,KACvB,OAAO,CAAC;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAS/E,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,kBAAkB,GAAI,OAAO,KAAK,KAAG,OAKjD,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Vec2 } from "@oh-just-another/types";
|
|
2
|
+
/** One point of a laser trail — world position plus the time it was laid down. */
|
|
3
|
+
export interface LaserPoint {
|
|
4
|
+
readonly x: number;
|
|
5
|
+
readonly y: number;
|
|
6
|
+
/** Birth timestamp (ms, `performance.now()` domain) — drives the fade. */
|
|
7
|
+
readonly t: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A single laser stroke: an ordered list of timestamped world points. Purely
|
|
11
|
+
* ephemeral — never enters the scene or history. The overlay ramps each point's
|
|
12
|
+
* opacity from 1 → 0 over {@link LASER_TRAIL_TTL_MS}; the editor prunes points
|
|
13
|
+
* past that age so the trail vanishes shortly after the pointer stops.
|
|
14
|
+
*/
|
|
15
|
+
export interface LaserStroke {
|
|
16
|
+
readonly points: LaserPoint[];
|
|
17
|
+
}
|
|
18
|
+
export declare const beginLaserStroke: (world: Vec2, now: number) => LaserStroke;
|
|
19
|
+
export declare const extendLaserStroke: (stroke: LaserStroke, world: Vec2, now: number) => void;
|
|
20
|
+
/**
|
|
21
|
+
* Drop every point older than `ttl` (and any stroke left empty). Returns the
|
|
22
|
+
* surviving strokes plus a `changed` flag; when nothing expired the SAME array
|
|
23
|
+
* reference is returned so the render-overlay memo can skip a rebuild. The
|
|
24
|
+
* returned array is fresh only when a prune actually happened.
|
|
25
|
+
*/
|
|
26
|
+
export declare const pruneLaserStrokes: (strokes: readonly LaserStroke[], now: number, ttl?: number) => {
|
|
27
|
+
readonly strokes: LaserStroke[];
|
|
28
|
+
readonly changed: boolean;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Resample a laser trail into a smooth, dense point list for rendering (via the
|
|
32
|
+
* shared {@link smoothStrokePoints} spline resampler). Each resampled point
|
|
33
|
+
* carries a birth timestamp linearly interpolated between its span endpoints, so
|
|
34
|
+
* the overlay's per-segment TTL fade still melts the trail tail-first exactly as
|
|
35
|
+
* it does for the raw points.
|
|
36
|
+
*/
|
|
37
|
+
export declare const smoothLaserPoints: (points: readonly LaserPoint[], perSegment?: number) => LaserPoint[];
|
|
38
|
+
//# sourceMappingURL=laser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"laser.d.ts","sourceRoot":"","sources":["../../../src/editor/public/laser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAInD,kFAAkF;AAClF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC;CAC/B;AAED,eAAO,MAAM,gBAAgB,GAAI,OAAO,IAAI,EAAE,KAAK,MAAM,KAAG,WAE1D,CAAC;AAEH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,WAAW,EAAE,OAAO,IAAI,EAAE,KAAK,MAAM,KAAG,IAEjF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAC5B,SAAS,SAAS,WAAW,EAAE,EAC/B,KAAK,MAAM,EACX,MAAK,MAA2B,KAC/B;IAAE,QAAQ,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAa9D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,SAAS,UAAU,EAAE,EAC7B,aAAY,MAA8B,KACzC,UAAU,EAKR,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { LASER_SMOOTH_SEGMENTS, LASER_TRAIL_TTL_MS } from "../../constants.js";
|
|
2
|
+
import { smoothStrokePoints } from "./stroke-smoothing.js";
|
|
3
|
+
export const beginLaserStroke = (world, now) => ({
|
|
4
|
+
points: [{ x: world.x, y: world.y, t: now }],
|
|
5
|
+
});
|
|
6
|
+
export const extendLaserStroke = (stroke, world, now) => {
|
|
7
|
+
stroke.points.push({ x: world.x, y: world.y, t: now });
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Drop every point older than `ttl` (and any stroke left empty). Returns the
|
|
11
|
+
* surviving strokes plus a `changed` flag; when nothing expired the SAME array
|
|
12
|
+
* reference is returned so the render-overlay memo can skip a rebuild. The
|
|
13
|
+
* returned array is fresh only when a prune actually happened.
|
|
14
|
+
*/
|
|
15
|
+
export const pruneLaserStrokes = (strokes, now, ttl = LASER_TRAIL_TTL_MS) => {
|
|
16
|
+
let changed = false;
|
|
17
|
+
const next = [];
|
|
18
|
+
for (const stroke of strokes) {
|
|
19
|
+
const kept = stroke.points.filter((p) => now - p.t < ttl);
|
|
20
|
+
if (kept.length === stroke.points.length) {
|
|
21
|
+
next.push(stroke);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
changed = true;
|
|
25
|
+
if (kept.length > 0)
|
|
26
|
+
next.push({ points: kept });
|
|
27
|
+
}
|
|
28
|
+
return changed ? { strokes: next, changed } : { strokes: strokes, changed };
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Resample a laser trail into a smooth, dense point list for rendering (via the
|
|
32
|
+
* shared {@link smoothStrokePoints} spline resampler). Each resampled point
|
|
33
|
+
* carries a birth timestamp linearly interpolated between its span endpoints, so
|
|
34
|
+
* the overlay's per-segment TTL fade still melts the trail tail-first exactly as
|
|
35
|
+
* it does for the raw points.
|
|
36
|
+
*/
|
|
37
|
+
export const smoothLaserPoints = (points, perSegment = LASER_SMOOTH_SEGMENTS) => smoothStrokePoints(points, perSegment, (a, b, pos, u) => ({
|
|
38
|
+
x: pos.x,
|
|
39
|
+
y: pos.y,
|
|
40
|
+
t: a.t + (b.t - a.t) * u,
|
|
41
|
+
}));
|
|
42
|
+
//# sourceMappingURL=laser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"laser.js","sourceRoot":"","sources":["../../../src/editor/public/laser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAoB3D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAW,EAAE,GAAW,EAAe,EAAE,CAAC,CAAC;IAC1E,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;CAC7C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAmB,EAAE,KAAW,EAAE,GAAW,EAAQ,EAAE;IACvF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;AACzD,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,OAA+B,EAC/B,GAAW,EACX,MAAc,kBAAkB,EACgC,EAAE;IAClE,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,IAAI,GAAkB,EAAE,CAAC;IAC/B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QAC1D,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACzC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAClB,SAAS;QACX,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;QACf,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAwB,EAAE,OAAO,EAAE,CAAC;AAC/F,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,MAA6B,EAC7B,aAAqB,qBAAqB,EAC5B,EAAE,CAChB,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IACxD,CAAC,EAAE,GAAG,CAAC,CAAC;IACR,CAAC,EAAE,GAAG,CAAC,CAAC;IACR,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;CACzB,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../../../src/editor/public/layers.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../../../src/editor/public/layers.ts"],"names":[],"mappings":"AAAA,OAAO,EAWL,KAAK,KAAK,EACV,KAAK,KAAK,EACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEtD,OAAO,KAAK,KAAK,SAAS,MAAM,oBAAoB,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAC7B,OAAO,KAAK,EACZ,MAAM,MAAM,EACZ,YAAY,OAAO,KAClB;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAK3E,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAC7B,OAAO,KAAK,EACZ,IAAI,OAAO,EACX,eAAe,OAAO,KACrB;IACD,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,KAAK,EAAE,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;CAC5B,GAAG,IA6BH,CAAC;AAEF,oEAAoE;AACpE,eAAO,MAAM,kBAAkB,GAC7B,OAAO,KAAK,EACZ,IAAI,OAAO,EACX,MAAM,MAAM,KACX;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG,IAKrD,CAAC;AAEF,+BAA+B;AAC/B,eAAO,MAAM,4BAA4B,GACvC,OAAO,KAAK,EACZ,IAAI,OAAO,KACV;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG,IAIrD,CAAC;AAEF,8BAA8B;AAC9B,eAAO,MAAM,sBAAsB,GACjC,OAAO,KAAK,EACZ,IAAI,OAAO,KACV;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG,IAIrD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,GACtC,OAAO,KAAK,EACZ,WAAW,SAAS,CAAC,SAAS,EAC9B,aAAa,OAAO,KACnB;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAA;CAAE,GAAG,IAazD,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,KAAG,OACe,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { addLayer, getElement, orderForTop, removeLink, removeLayer, removeElement, updateLayer, updateElement, } from "@oh-just-another/scene";
|
|
1
|
+
import { addLayer, byOrderDesc, getElement, orderForTop, removeLink, removeLayer, removeElement, updateLayer, updateElement, } from "@oh-just-another/scene";
|
|
2
2
|
import { layerId as castLayerId } from "@oh-just-another/types";
|
|
3
3
|
/**
|
|
4
4
|
* Build a fresh top-of-stack layer + the patch that adds it. Caller
|
|
@@ -46,7 +46,7 @@ export const computeRemoveLayer = (scene, id, currentActive) => {
|
|
|
46
46
|
patches.push(r.patch);
|
|
47
47
|
let nextActive = currentActive;
|
|
48
48
|
if (currentActive === id) {
|
|
49
|
-
const top = [...s.layers.values()].sort(
|
|
49
|
+
const top = [...s.layers.values()].sort(byOrderDesc)[0];
|
|
50
50
|
if (top)
|
|
51
51
|
nextActive = top.id;
|
|
52
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layers.js","sourceRoot":"","sources":["../../../src/editor/public/layers.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,aAAa,GAId,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGhE;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,KAAY,EACZ,IAAY,EACZ,UAAmB,EAC0D,EAAE;IAC/E,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAU,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAC7F,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACtC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;AAC3E,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,KAAY,EACZ,EAAW,EACX,aAAsB,EAKf,EAAE;IACT,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,OAAO,GAAY,EAAE,CAAC;IAC5B,IAAI,CAAC,GAAG,KAAK,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;QAC7C,IAAI,KAAK,CAAC,OAAO,KAAK,EAAE;YAAE,SAAS;QACnC,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QACrC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;QACzC,IAAI,IAAI,CAAC,OAAO,KAAK,EAAE;YAAE,SAAS;QAClC,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QACjC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IACD,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7B,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;IACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAEtB,IAAI,UAAU,GAAG,aAAa,CAAC;IAC/B,IAAI,aAAa,KAAK,EAAE,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"layers.js","sourceRoot":"","sources":["../../../src/editor/public/layers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type Scene, type Patch } from "@oh-just-another/scene";
|
|
2
|
-
import type { ElementId } from "@oh-just-another/types";
|
|
1
|
+
import { type Scene, type Patch, type SnapEngine, type LinkEndpoint } from "@oh-just-another/scene";
|
|
2
|
+
import type { ElementId, Vec2 } from "@oh-just-another/types";
|
|
3
3
|
/**
|
|
4
4
|
* Normalise user-entered link text into a safe, storable href, or
|
|
5
5
|
* `null` to clear / reject. Adds `https://` to a scheme-less URL,
|
|
@@ -22,4 +22,13 @@ export declare const computeSetLink: (scene: Scene, ids: Iterable<ElementId>, hr
|
|
|
22
22
|
readonly scene: Scene;
|
|
23
23
|
readonly patch: Patch;
|
|
24
24
|
} | null;
|
|
25
|
+
/**
|
|
26
|
+
* Resolve where a link endpoint should attach when dropped at `worldPoint`.
|
|
27
|
+
* Attach contract: a port dot → *fixed* anchor; near an EDGE (not a dot) →
|
|
28
|
+
* *fixed* outline point (a perimeter ratio — survives move/resize); the body
|
|
29
|
+
* interior → *floating* against the whole shape (re-aims as shapes move); empty
|
|
30
|
+
* canvas → a free point. `pressTargetElement` biases the pick toward the pressed
|
|
31
|
+
* shape, but a dot drawn outside the body still binds even when it's null.
|
|
32
|
+
*/
|
|
33
|
+
export declare const snapLinkEndpoint: (scene: Scene, snapEngine: SnapEngine, threshold: number, pressTargetElement: ElementId | null, worldPoint: Vec2) => LinkEndpoint;
|
|
25
34
|
//# sourceMappingURL=link.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../src/editor/public/link.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../src/editor/public/link.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,KAAK,EACV,KAAK,KAAK,EACV,KAAK,UAAU,EAEf,KAAK,YAAY,EAGlB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAa9D;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,MAAM,GAAG,IAQtD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,GAAG,SAAS,GAAG,IAAI,KAAG,MAAM,GAAG,IAGnE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,GACzB,OAAO,KAAK,EACZ,KAAK,QAAQ,CAAC,SAAS,CAAC,EACxB,MAAM,MAAM,GAAG,IAAI,KAClB;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG,IAyBrD,CAAC;AAwBF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAC3B,OAAO,KAAK,EACZ,YAAY,UAAU,EACtB,WAAW,MAAM,EACjB,oBAAoB,SAAS,GAAG,IAAI,EACpC,YAAY,IAAI,KACf,YAyCF,CAAC"}
|