@oh-just-another/state 0.57.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 +18 -0
- package/LICENSE +21 -0
- package/README.md +60 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/actions/actionClipboard.d.ts +6 -0
- package/dist/actions/actionClipboard.d.ts.map +1 -0
- package/dist/actions/actionClipboard.js +26 -0
- package/dist/actions/actionClipboard.js.map +1 -0
- package/dist/actions/actionGrouping.d.ts +5 -0
- package/dist/actions/actionGrouping.d.ts.map +1 -0
- package/dist/actions/actionGrouping.js +26 -0
- package/dist/actions/actionGrouping.js.map +1 -0
- package/dist/actions/actionHistory.d.ts +5 -0
- package/dist/actions/actionHistory.d.ts.map +1 -0
- package/dist/actions/actionHistory.js +25 -0
- package/dist/actions/actionHistory.js.map +1 -0
- package/dist/actions/actionKeyboard.d.ts +3 -0
- package/dist/actions/actionKeyboard.d.ts.map +1 -0
- package/dist/actions/actionKeyboard.js +130 -0
- package/dist/actions/actionKeyboard.js.map +1 -0
- package/dist/actions/actionLayout.d.ts +3 -0
- package/dist/actions/actionLayout.d.ts.map +1 -0
- package/dist/actions/actionLayout.js +65 -0
- package/dist/actions/actionLayout.js.map +1 -0
- package/dist/actions/actionMode.d.ts +13 -0
- package/dist/actions/actionMode.d.ts.map +1 -0
- package/dist/actions/actionMode.js +116 -0
- package/dist/actions/actionMode.js.map +1 -0
- package/dist/actions/actionSelection.d.ts +9 -0
- package/dist/actions/actionSelection.d.ts.map +1 -0
- package/dist/actions/actionSelection.js +57 -0
- package/dist/actions/actionSelection.js.map +1 -0
- package/dist/actions/actionView.d.ts +7 -0
- package/dist/actions/actionView.d.ts.map +1 -0
- package/dist/actions/actionView.js +14 -0
- package/dist/actions/actionView.js.map +1 -0
- package/dist/actions/actionZOrder.d.ts +7 -0
- package/dist/actions/actionZOrder.d.ts.map +1 -0
- package/dist/actions/actionZOrder.js +42 -0
- package/dist/actions/actionZOrder.js.map +1 -0
- package/dist/actions/actionZoom.d.ts +8 -0
- package/dist/actions/actionZoom.d.ts.map +1 -0
- package/dist/actions/actionZoom.js +61 -0
- package/dist/actions/actionZoom.js.map +1 -0
- package/dist/actions/index.d.ts +12 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/dist/actions/index.js +11 -0
- package/dist/actions/index.js.map +1 -0
- package/dist/actions/registry.d.ts +68 -0
- package/dist/actions/registry.d.ts.map +1 -0
- package/dist/actions/registry.js +300 -0
- package/dist/actions/registry.js.map +1 -0
- package/dist/actions/types.d.ts +103 -0
- package/dist/actions/types.d.ts.map +1 -0
- package/dist/actions/types.js +10 -0
- package/dist/actions/types.js.map +1 -0
- package/dist/animation-tick.d.ts +28 -0
- package/dist/animation-tick.d.ts.map +1 -0
- package/dist/animation-tick.js +50 -0
- package/dist/animation-tick.js.map +1 -0
- package/dist/auto-compact.d.ts +27 -0
- package/dist/auto-compact.d.ts.map +1 -0
- package/dist/auto-compact.js +46 -0
- package/dist/auto-compact.js.map +1 -0
- package/dist/auto-layout-scheduler.d.ts +50 -0
- package/dist/auto-layout-scheduler.d.ts.map +1 -0
- package/dist/auto-layout-scheduler.js +94 -0
- package/dist/auto-layout-scheduler.js.map +1 -0
- package/dist/built-in-handlers.d.ts +24 -0
- package/dist/built-in-handlers.d.ts.map +1 -0
- package/dist/built-in-handlers.js +210 -0
- package/dist/built-in-handlers.js.map +1 -0
- package/dist/clipboard.d.ts +51 -0
- package/dist/clipboard.d.ts.map +1 -0
- package/dist/clipboard.js +105 -0
- package/dist/clipboard.js.map +1 -0
- package/dist/constants.d.ts +544 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +537 -0
- package/dist/constants.js.map +1 -0
- package/dist/dom-events.d.ts +13 -0
- package/dist/dom-events.d.ts.map +1 -0
- package/dist/dom-events.js +70 -0
- package/dist/dom-events.js.map +1 -0
- package/dist/editor/anchor-points.d.ts +22 -0
- package/dist/editor/anchor-points.d.ts.map +1 -0
- package/dist/editor/anchor-points.js +28 -0
- package/dist/editor/anchor-points.js.map +1 -0
- package/dist/editor/applies/create.d.ts +60 -0
- package/dist/editor/applies/create.d.ts.map +1 -0
- package/dist/editor/applies/create.js +107 -0
- package/dist/editor/applies/create.js.map +1 -0
- package/dist/editor/applies/edge.d.ts +32 -0
- package/dist/editor/applies/edge.d.ts.map +1 -0
- package/dist/editor/applies/edge.js +44 -0
- package/dist/editor/applies/edge.js.map +1 -0
- package/dist/editor/applies/link-move.d.ts +53 -0
- package/dist/editor/applies/link-move.d.ts.map +1 -0
- package/dist/editor/applies/link-move.js +160 -0
- package/dist/editor/applies/link-move.js.map +1 -0
- package/dist/editor/applies/move.d.ts +38 -0
- package/dist/editor/applies/move.d.ts.map +1 -0
- package/dist/editor/applies/move.js +83 -0
- package/dist/editor/applies/move.js.map +1 -0
- package/dist/editor/applies/resize.d.ts +68 -0
- package/dist/editor/applies/resize.d.ts.map +1 -0
- package/dist/editor/applies/resize.js +199 -0
- package/dist/editor/applies/resize.js.map +1 -0
- package/dist/editor/applies/selection.d.ts +34 -0
- package/dist/editor/applies/selection.d.ts.map +1 -0
- package/dist/editor/applies/selection.js +65 -0
- package/dist/editor/applies/selection.js.map +1 -0
- package/dist/editor/applies/snap-grid.d.ts +45 -0
- package/dist/editor/applies/snap-grid.d.ts.map +1 -0
- package/dist/editor/applies/snap-grid.js +90 -0
- package/dist/editor/applies/snap-grid.js.map +1 -0
- package/dist/editor/container-ops.d.ts +74 -0
- package/dist/editor/container-ops.d.ts.map +1 -0
- package/dist/editor/container-ops.js +262 -0
- package/dist/editor/container-ops.js.map +1 -0
- package/dist/editor/event-fanout.d.ts +48 -0
- package/dist/editor/event-fanout.d.ts.map +1 -0
- package/dist/editor/event-fanout.js +53 -0
- package/dist/editor/event-fanout.js.map +1 -0
- package/dist/editor/gesture-tx.d.ts +77 -0
- package/dist/editor/gesture-tx.d.ts.map +1 -0
- package/dist/editor/gesture-tx.js +93 -0
- package/dist/editor/gesture-tx.js.map +1 -0
- package/dist/editor/hit-test.d.ts +178 -0
- package/dist/editor/hit-test.d.ts.map +1 -0
- package/dist/editor/hit-test.js +460 -0
- package/dist/editor/hit-test.js.map +1 -0
- package/dist/editor/long-press.d.ts +34 -0
- package/dist/editor/long-press.d.ts.map +1 -0
- package/dist/editor/long-press.js +58 -0
- package/dist/editor/long-press.js.map +1 -0
- package/dist/editor/pinch.d.ts +37 -0
- package/dist/editor/pinch.d.ts.map +1 -0
- package/dist/editor/pinch.js +90 -0
- package/dist/editor/pinch.js.map +1 -0
- package/dist/editor/pointer-binding.d.ts +18 -0
- package/dist/editor/pointer-binding.d.ts.map +1 -0
- package/dist/editor/pointer-binding.js +1087 -0
- package/dist/editor/pointer-binding.js.map +1 -0
- package/dist/editor/public/annotations.d.ts +54 -0
- package/dist/editor/public/annotations.d.ts.map +1 -0
- package/dist/editor/public/annotations.js +106 -0
- package/dist/editor/public/annotations.js.map +1 -0
- package/dist/editor/public/arrange-group.d.ts +81 -0
- package/dist/editor/public/arrange-group.d.ts.map +1 -0
- package/dist/editor/public/arrange-group.js +193 -0
- package/dist/editor/public/arrange-group.js.map +1 -0
- package/dist/editor/public/brush.d.ts +33 -0
- package/dist/editor/public/brush.d.ts.map +1 -0
- package/dist/editor/public/brush.js +54 -0
- package/dist/editor/public/brush.js.map +1 -0
- package/dist/editor/public/clipboard.d.ts +31 -0
- package/dist/editor/public/clipboard.d.ts.map +1 -0
- package/dist/editor/public/clipboard.js +35 -0
- package/dist/editor/public/clipboard.js.map +1 -0
- package/dist/editor/public/image-insert.d.ts +30 -0
- package/dist/editor/public/image-insert.d.ts.map +1 -0
- package/dist/editor/public/image-insert.js +57 -0
- package/dist/editor/public/image-insert.js.map +1 -0
- package/dist/editor/public/layers.d.ts +56 -0
- package/dist/editor/public/layers.d.ts.map +1 -0
- package/dist/editor/public/layers.js +104 -0
- package/dist/editor/public/layers.js.map +1 -0
- package/dist/editor/public/link.d.ts +25 -0
- package/dist/editor/public/link.d.ts.map +1 -0
- package/dist/editor/public/link.js +74 -0
- package/dist/editor/public/link.js.map +1 -0
- package/dist/editor/public/placement.d.ts +60 -0
- package/dist/editor/public/placement.d.ts.map +1 -0
- package/dist/editor/public/placement.js +111 -0
- package/dist/editor/public/placement.js.map +1 -0
- package/dist/editor/public/selection-ops.d.ts +78 -0
- package/dist/editor/public/selection-ops.d.ts.map +1 -0
- package/dist/editor/public/selection-ops.js +226 -0
- package/dist/editor/public/selection-ops.js.map +1 -0
- package/dist/editor/public/text-edit.d.ts +17 -0
- package/dist/editor/public/text-edit.d.ts.map +1 -0
- package/dist/editor/public/text-edit.js +28 -0
- package/dist/editor/public/text-edit.js.map +1 -0
- package/dist/editor/public/z-order.d.ts +47 -0
- package/dist/editor/public/z-order.d.ts.map +1 -0
- package/dist/editor/public/z-order.js +151 -0
- package/dist/editor/public/z-order.js.map +1 -0
- package/dist/editor/public/zoom-pan.d.ts +44 -0
- package/dist/editor/public/zoom-pan.d.ts.map +1 -0
- package/dist/editor/public/zoom-pan.js +116 -0
- package/dist/editor/public/zoom-pan.js.map +1 -0
- package/dist/editor/render-orchestrator.d.ts +11 -0
- package/dist/editor/render-orchestrator.d.ts.map +1 -0
- package/dist/editor/render-orchestrator.js +473 -0
- package/dist/editor/render-orchestrator.js.map +1 -0
- package/dist/editor/resize-helpers.d.ts +30 -0
- package/dist/editor/resize-helpers.d.ts.map +1 -0
- package/dist/editor/resize-helpers.js +121 -0
- package/dist/editor/resize-helpers.js.map +1 -0
- package/dist/editor/shape-filters.d.ts +11 -0
- package/dist/editor/shape-filters.d.ts.map +1 -0
- package/dist/editor/shape-filters.js +19 -0
- package/dist/editor/shape-filters.js.map +1 -0
- package/dist/editor/shape-traits.d.ts +16 -0
- package/dist/editor/shape-traits.d.ts.map +1 -0
- package/dist/editor/shape-traits.js +29 -0
- package/dist/editor/shape-traits.js.map +1 -0
- package/dist/editor/viewport-helpers.d.ts +24 -0
- package/dist/editor/viewport-helpers.d.ts.map +1 -0
- package/dist/editor/viewport-helpers.js +63 -0
- package/dist/editor/viewport-helpers.js.map +1 -0
- package/dist/editor-events.d.ts +33 -0
- package/dist/editor-events.d.ts.map +1 -0
- package/dist/editor-events.js +2 -0
- package/dist/editor-events.js.map +1 -0
- package/dist/editor.d.ts +1841 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +4803 -0
- package/dist/editor.js.map +1 -0
- package/dist/file-drop.d.ts +99 -0
- package/dist/file-drop.d.ts.map +1 -0
- package/dist/file-drop.js +198 -0
- package/dist/file-drop.js.map +1 -0
- package/dist/frame-helpers.d.ts +30 -0
- package/dist/frame-helpers.d.ts.map +1 -0
- package/dist/frame-helpers.js +105 -0
- package/dist/frame-helpers.js.map +1 -0
- package/dist/group-helpers.d.ts +39 -0
- package/dist/group-helpers.d.ts.map +1 -0
- package/dist/group-helpers.js +116 -0
- package/dist/group-helpers.js.map +1 -0
- package/dist/handle.d.ts +73 -0
- package/dist/handle.d.ts.map +1 -0
- package/dist/handle.js +184 -0
- package/dist/handle.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive.d.ts +21 -0
- package/dist/interactive.d.ts.map +1 -0
- package/dist/interactive.js +11 -0
- package/dist/interactive.js.map +1 -0
- package/dist/link-selection.d.ts +21 -0
- package/dist/link-selection.d.ts.map +1 -0
- package/dist/link-selection.js +37 -0
- package/dist/link-selection.js.map +1 -0
- package/dist/machine.d.ts +322 -0
- package/dist/machine.d.ts.map +1 -0
- package/dist/machine.js +568 -0
- package/dist/machine.js.map +1 -0
- package/dist/modes.d.ts +24 -0
- package/dist/modes.d.ts.map +1 -0
- package/dist/modes.js +2 -0
- package/dist/modes.js.map +1 -0
- package/dist/overlay.d.ts +262 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +673 -0
- package/dist/overlay.js.map +1 -0
- package/dist/platform.d.ts +70 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +115 -0
- package/dist/platform.js.map +1 -0
- package/dist/selection.d.ts +18 -0
- package/dist/selection.d.ts.map +1 -0
- package/dist/selection.js +31 -0
- package/dist/selection.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { getElement, getElementWorldBounds, updateAnnotation, } from "@oh-just-another/scene";
|
|
2
|
+
/**
|
|
3
|
+
* Pure: compute the patch that moves shape `id` by `delta` from
|
|
4
|
+
* the press-down state captured in `originalBounds`. Returns
|
|
5
|
+
* `null` when the shape no longer exists (deleted mid-drag, etc.).
|
|
6
|
+
*
|
|
7
|
+
* `originalBounds` is in world space at press time; `localBounds`
|
|
8
|
+
* (current) compensates for parent-rooted layouts where the shape's
|
|
9
|
+
* own position has already moved relative to its parent. The
|
|
10
|
+
* offset is added so the cursor stays at the press anchor through
|
|
11
|
+
* the drag.
|
|
12
|
+
*
|
|
13
|
+
* Editor's wrapper applies the patch, runs `recordGesturePatch`,
|
|
14
|
+
* and fires notify.
|
|
15
|
+
*/
|
|
16
|
+
export const computeElementMovePatch = (scene, id, delta, originalBounds) => {
|
|
17
|
+
const shape = getElement(scene, id);
|
|
18
|
+
if (!shape)
|
|
19
|
+
return null;
|
|
20
|
+
const localBounds = getElementWorldBounds(shape);
|
|
21
|
+
const offsetX = originalBounds.x - localBounds.x;
|
|
22
|
+
const offsetY = originalBounds.y - localBounds.y;
|
|
23
|
+
const next = {
|
|
24
|
+
...shape,
|
|
25
|
+
position: {
|
|
26
|
+
x: shape.position.x + delta.x + offsetX,
|
|
27
|
+
y: shape.position.y + delta.y + offsetY,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
return { kind: "element", id, before: shape, after: next };
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Pure: compute one patch per shape in the active group-drag
|
|
34
|
+
* snapshot. `delta` is the cumulative cursor displacement since
|
|
35
|
+
* press-down, so each shape lands at `origin + delta` every frame
|
|
36
|
+
* — no accumulator state inside the loop. Skips no-op moves
|
|
37
|
+
* (delta after rounding lands the shape back at its current pos).
|
|
38
|
+
*/
|
|
39
|
+
export const computeGroupMovePatches = (scene, groupMoveOrigin, delta) => {
|
|
40
|
+
const out = [];
|
|
41
|
+
for (const [id, origin] of groupMoveOrigin) {
|
|
42
|
+
const shape = getElement(scene, id);
|
|
43
|
+
if (!shape)
|
|
44
|
+
continue;
|
|
45
|
+
const next = {
|
|
46
|
+
...shape,
|
|
47
|
+
position: { x: origin.x + delta.x, y: origin.y + delta.y },
|
|
48
|
+
};
|
|
49
|
+
if (next.position.x === shape.position.x && next.position.y === shape.position.y)
|
|
50
|
+
continue;
|
|
51
|
+
out.push({ kind: "element", id, before: shape, after: next });
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Pure: compute the scene + patch resulting from an annotation
|
|
57
|
+
* drag. For shape-anchored annotations the stored position is the
|
|
58
|
+
* offset from the host shape's world position, so we translate
|
|
59
|
+
* the requested world target back into local space. Returns
|
|
60
|
+
* `null` when the annotation no longer exists or the move is a
|
|
61
|
+
* pixel-perfect no-op.
|
|
62
|
+
*/
|
|
63
|
+
export const computeAnnotationMovePatch = (scene, id, delta, origin) => {
|
|
64
|
+
const ann = scene.annotations.get(id);
|
|
65
|
+
if (!ann)
|
|
66
|
+
return null;
|
|
67
|
+
const targetWorld = { x: origin.x + delta.x, y: origin.y + delta.y };
|
|
68
|
+
let storedPosition = targetWorld;
|
|
69
|
+
if (ann.elementId) {
|
|
70
|
+
const shape = getElement(scene, ann.elementId);
|
|
71
|
+
if (shape) {
|
|
72
|
+
storedPosition = {
|
|
73
|
+
x: targetWorld.x - shape.position.x,
|
|
74
|
+
y: targetWorld.y - shape.position.y,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (storedPosition.x === ann.position.x && storedPosition.y === ann.position.y)
|
|
79
|
+
return null;
|
|
80
|
+
const r = updateAnnotation(scene, id, (a) => ({ ...a, position: storedPosition }));
|
|
81
|
+
return { scene: r.scene, patch: r.patch };
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=move.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move.js","sourceRoot":"","sources":["../../../src/editor/applies/move.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type Scene, type Element, type Link, type Patch, type TextElement } from "@oh-just-another/scene";
|
|
2
|
+
import type { Bounds, ElementId, LinkId, Vec2 } from "@oh-just-another/types";
|
|
3
|
+
import type { HandleId } from "../../handle.js";
|
|
4
|
+
/**
|
|
5
|
+
* Pure: compute the patch + new scene for a single-shape resize.
|
|
6
|
+
*
|
|
7
|
+
* Only shapes with explicit `width` / `height` fields qualify
|
|
8
|
+
* (`hasWidthHeight`) — others must ride the `scale` multiplier
|
|
9
|
+
* instead (group resize). The container-aware clamp callback is
|
|
10
|
+
* injected by the caller so this module doesn't depend on
|
|
11
|
+
* container-ops.
|
|
12
|
+
*
|
|
13
|
+
* Returns `null` when the shape no longer exists or doesn't
|
|
14
|
+
* qualify for in-place resize.
|
|
15
|
+
*/
|
|
16
|
+
export declare const computeElementResize: (scene: Scene, id: ElementId, handle: HandleId, delta: Vec2, originalBounds: Bounds, clampContainer: (shape: Element, raw: Bounds, handle: HandleId) => Bounds) => {
|
|
17
|
+
readonly scene: Scene;
|
|
18
|
+
readonly patch: Patch;
|
|
19
|
+
} | null;
|
|
20
|
+
/**
|
|
21
|
+
* Pure: resize a single text shape.
|
|
22
|
+
*
|
|
23
|
+
* `original` is the pristine shape snapshotted at the start of the
|
|
24
|
+
* gesture (so font scaling is computed from a stable base, never
|
|
25
|
+
* compounding tick-to-tick).
|
|
26
|
+
*
|
|
27
|
+
* - **Corners** (`nw/ne/se/sw`) and **top/bottom edges** (`n/s`) scale
|
|
28
|
+
* `fontSize` (and `maxWidth`, if set) uniformly — the box never
|
|
29
|
+
* distorts. There's no arbitrary height; a vertical drag scales the
|
|
30
|
+
* whole element.
|
|
31
|
+
* - **Left/right edges** (`e/w`) change only the wrap width: the text
|
|
32
|
+
* reflows onto new lines (sets `maxWidth`, no font change).
|
|
33
|
+
*/
|
|
34
|
+
export declare const computeTextResize: (scene: Scene, original: TextElement, handle: HandleId, delta: Vec2, originalBounds: Bounds) => {
|
|
35
|
+
readonly scene: Scene;
|
|
36
|
+
readonly patch: Patch;
|
|
37
|
+
} | null;
|
|
38
|
+
/**
|
|
39
|
+
* Pure: compute one patch per shape in the group-resize snapshot.
|
|
40
|
+
*
|
|
41
|
+
* Each member's *position offset* inside the original combined box
|
|
42
|
+
* scales by the same factor; each member's `scale.{x,y}` is
|
|
43
|
+
* multiplied so the visible size tracks the gesture. Mirroring
|
|
44
|
+
* (flip) is allowed when the user drags past the opposite edge.
|
|
45
|
+
*
|
|
46
|
+
* `originSnapshot` is a per-shape press-down snapshot: position,
|
|
47
|
+
* scale, bounds. Caller (Editor) collects it at press time and
|
|
48
|
+
* threads it back every frame.
|
|
49
|
+
*/
|
|
50
|
+
export interface GroupResizeOrigin {
|
|
51
|
+
readonly elements: ReadonlyMap<ElementId, {
|
|
52
|
+
readonly position: Vec2;
|
|
53
|
+
readonly scale: Vec2;
|
|
54
|
+
readonly bounds: Bounds;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Press-time snapshot of links that scale with the box: selected links
|
|
58
|
+
* (whole, incl. free endpoints) ∪ connectors bound on both ends to resized
|
|
59
|
+
* elements (geometry follows). Optional for back-compat with callers that
|
|
60
|
+
* don't resize links.
|
|
61
|
+
*/
|
|
62
|
+
readonly links?: ReadonlyMap<LinkId, Link>;
|
|
63
|
+
}
|
|
64
|
+
export declare const computeGroupResizePatches: (scene: Scene, origin: GroupResizeOrigin, handle: HandleId, delta: Vec2, originalBounds: Bounds, isAspectLocked: boolean) => {
|
|
65
|
+
scene: Scene;
|
|
66
|
+
patches: Patch[];
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=resize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize.d.ts","sourceRoot":"","sources":["../../../src/editor/applies/resize.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,KAAK,EACV,KAAK,OAAO,EACZ,KAAK,IAAI,EACT,KAAK,KAAK,EACV,KAAK,WAAW,EACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAMhD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,KAAK,EACZ,IAAI,SAAS,EACb,QAAQ,QAAQ,EAChB,OAAO,IAAI,EACX,gBAAgB,MAAM,EACtB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,KAAK,MAAM,KACxE;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG,IA8BrD,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,GAC5B,OAAO,KAAK,EACZ,UAAU,WAAW,EACrB,QAAQ,QAAQ,EAChB,OAAO,IAAI,EACX,gBAAgB,MAAM,KACrB;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG,IA8CrD,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAC5B,SAAS,EACT;QACE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;QACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,CACF,CAAC;IACF;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;CAC5C;AAED,eAAO,MAAM,yBAAyB,GACpC,OAAO,KAAK,EACZ,QAAQ,iBAAiB,EACzB,QAAQ,QAAQ,EAChB,OAAO,IAAI,EACX,gBAAgB,MAAM,EACtB,gBAAgB,OAAO,KACtB;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,KAAK,EAAE,CAAA;CA0FlC,CAAC"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { apply, getAutoLayoutSpec, getElement, getLink, } from "@oh-just-another/scene";
|
|
2
|
+
import { applyResizeConstraints, resizeFromHandle } from "../resize-helpers.js";
|
|
3
|
+
import { hasWidthHeight } from "../shape-traits.js";
|
|
4
|
+
import { scaleLinkAround } from "./link-move.js";
|
|
5
|
+
import { TEXT_RESIZE_MIN_FONT_SIZE } from "../../constants.js";
|
|
6
|
+
/**
|
|
7
|
+
* Pure: compute the patch + new scene for a single-shape resize.
|
|
8
|
+
*
|
|
9
|
+
* Only shapes with explicit `width` / `height` fields qualify
|
|
10
|
+
* (`hasWidthHeight`) — others must ride the `scale` multiplier
|
|
11
|
+
* instead (group resize). The container-aware clamp callback is
|
|
12
|
+
* injected by the caller so this module doesn't depend on
|
|
13
|
+
* container-ops.
|
|
14
|
+
*
|
|
15
|
+
* Returns `null` when the shape no longer exists or doesn't
|
|
16
|
+
* qualify for in-place resize.
|
|
17
|
+
*/
|
|
18
|
+
export const computeElementResize = (scene, id, handle, delta, originalBounds, clampContainer) => {
|
|
19
|
+
const shape = getElement(scene, id);
|
|
20
|
+
if (!shape)
|
|
21
|
+
return null;
|
|
22
|
+
if (!hasWidthHeight(shape))
|
|
23
|
+
return null;
|
|
24
|
+
const raw = resizeFromHandle(originalBounds, handle, delta);
|
|
25
|
+
// An auto-layout container (a box holding laid-out children) must NEVER
|
|
26
|
+
// mirror through its own body: dragging an edge inward past the opposite
|
|
27
|
+
// edge would otherwise hand control to that opposite edge ("flip through
|
|
28
|
+
// the face"). Force `noFlip` regardless of the element's stored flag so
|
|
29
|
+
// instances that lack it behave the same.
|
|
30
|
+
const noFlip = shape.noFlip === true || getAutoLayoutSpec(shape) !== null;
|
|
31
|
+
const constraints = noFlip ? ({ ...shape, noFlip: true }) : shape;
|
|
32
|
+
const intermediate = applyResizeConstraints(originalBounds, raw, handle, constraints);
|
|
33
|
+
const constrained = clampContainer(shape, intermediate, handle);
|
|
34
|
+
// `constrained` is in world units (originalBounds was world AABB).
|
|
35
|
+
// For shapes with a width/height field, persist that directly and
|
|
36
|
+
// pin `scale` to 1 — otherwise a non-1 scale carried over from a
|
|
37
|
+
// previous group resize would multiply the new width and the
|
|
38
|
+
// shape would jump out from under the cursor on the next gesture.
|
|
39
|
+
const next = {
|
|
40
|
+
...shape,
|
|
41
|
+
position: { x: constrained.x, y: constrained.y },
|
|
42
|
+
scale: { x: 1, y: 1 },
|
|
43
|
+
width: constrained.width,
|
|
44
|
+
height: constrained.height,
|
|
45
|
+
};
|
|
46
|
+
const patch = { kind: "element", id, before: shape, after: next };
|
|
47
|
+
return { scene: apply(scene, patch), patch };
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Pure: resize a single text shape.
|
|
51
|
+
*
|
|
52
|
+
* `original` is the pristine shape snapshotted at the start of the
|
|
53
|
+
* gesture (so font scaling is computed from a stable base, never
|
|
54
|
+
* compounding tick-to-tick).
|
|
55
|
+
*
|
|
56
|
+
* - **Corners** (`nw/ne/se/sw`) and **top/bottom edges** (`n/s`) scale
|
|
57
|
+
* `fontSize` (and `maxWidth`, if set) uniformly — the box never
|
|
58
|
+
* distorts. There's no arbitrary height; a vertical drag scales the
|
|
59
|
+
* whole element.
|
|
60
|
+
* - **Left/right edges** (`e/w`) change only the wrap width: the text
|
|
61
|
+
* reflows onto new lines (sets `maxWidth`, no font change).
|
|
62
|
+
*/
|
|
63
|
+
export const computeTextResize = (scene, original, handle, delta, originalBounds) => {
|
|
64
|
+
const current = getElement(scene, original.id);
|
|
65
|
+
if (!current)
|
|
66
|
+
return null;
|
|
67
|
+
const raw = resizeFromHandle(originalBounds, handle, delta);
|
|
68
|
+
// Left / right edges → wrap-width only (no scale).
|
|
69
|
+
if (handle === "e" || handle === "w") {
|
|
70
|
+
const newMaxWidth = Math.max(original.fontSize, Math.abs(raw.width));
|
|
71
|
+
const anchorX = handle === "w" ? originalBounds.x + originalBounds.width : originalBounds.x;
|
|
72
|
+
const nx = handle === "w" ? anchorX - newMaxWidth : anchorX;
|
|
73
|
+
const next = {
|
|
74
|
+
...original,
|
|
75
|
+
position: { x: nx, y: originalBounds.y },
|
|
76
|
+
scale: { x: 1, y: 1 },
|
|
77
|
+
maxWidth: newMaxWidth,
|
|
78
|
+
};
|
|
79
|
+
const patch = { kind: "element", id: original.id, before: current, after: next };
|
|
80
|
+
return { scene: apply(scene, patch), patch };
|
|
81
|
+
}
|
|
82
|
+
// Corners + top/bottom edges → uniform font scale. Top/bottom take the
|
|
83
|
+
// vertical ratio (only height changed); corners take the larger axis
|
|
84
|
+
// so the dragged corner tracks the cursor along the diagonal.
|
|
85
|
+
const horizontalEdge = handle === "n" || handle === "s";
|
|
86
|
+
const sx = originalBounds.width > 0 ? Math.abs(raw.width / originalBounds.width) : 1;
|
|
87
|
+
const sy = originalBounds.height > 0 ? Math.abs(raw.height / originalBounds.height) : 1;
|
|
88
|
+
const s = horizontalEdge ? sy : Math.max(sx, sy);
|
|
89
|
+
const newFont = Math.max(TEXT_RESIZE_MIN_FONT_SIZE, original.fontSize * s);
|
|
90
|
+
const factor = newFont / original.fontSize; // applied scale (post-clamp)
|
|
91
|
+
const newW = originalBounds.width * factor;
|
|
92
|
+
const newH = originalBounds.height * factor;
|
|
93
|
+
// Anchor = the edge/corner opposite the dragged handle stays put. For
|
|
94
|
+
// n/s the horizontal position pins to the left edge.
|
|
95
|
+
const ax = handle.includes("w") ? originalBounds.x + originalBounds.width : originalBounds.x;
|
|
96
|
+
const ay = handle.includes("n") ? originalBounds.y + originalBounds.height : originalBounds.y;
|
|
97
|
+
const nx = handle.includes("w") ? ax - newW : ax;
|
|
98
|
+
const ny = handle.includes("n") ? ay - newH : ay;
|
|
99
|
+
const next = {
|
|
100
|
+
...original,
|
|
101
|
+
position: { x: nx, y: ny },
|
|
102
|
+
scale: { x: 1, y: 1 },
|
|
103
|
+
fontSize: newFont,
|
|
104
|
+
...(original.maxWidth !== undefined ? { maxWidth: original.maxWidth * factor } : {}),
|
|
105
|
+
};
|
|
106
|
+
const patch = { kind: "element", id: original.id, before: current, after: next };
|
|
107
|
+
return { scene: apply(scene, patch), patch };
|
|
108
|
+
};
|
|
109
|
+
export const computeGroupResizePatches = (scene, origin, handle, delta, originalBounds, isAspectLocked) => {
|
|
110
|
+
const next = resizeFromHandle(originalBounds, handle, delta);
|
|
111
|
+
const minDim = 1;
|
|
112
|
+
let sx = originalBounds.width > 0 ? next.width / originalBounds.width : 1;
|
|
113
|
+
let sy = originalBounds.height > 0 ? next.height / originalBounds.height : 1;
|
|
114
|
+
// Aspect-lock: groups can only scale uniformly. Use the larger
|
|
115
|
+
// magnitude so the dragged corner moves along the diagonal toward
|
|
116
|
+
// the cursor; sign is preserved per-axis so a drag past the anchor
|
|
117
|
+
// still mirrors the group uniformly.
|
|
118
|
+
if (isAspectLocked) {
|
|
119
|
+
const locked = Math.max(Math.abs(sx), Math.abs(sy));
|
|
120
|
+
sx = locked * (sx >= 0 ? 1 : -1);
|
|
121
|
+
sy = locked * (sy >= 0 ? 1 : -1);
|
|
122
|
+
}
|
|
123
|
+
// Uniform factor for aspect-locked members (images) inside a mixed
|
|
124
|
+
// selection: an image must only *scale*, never distort, even while
|
|
125
|
+
// its neighbours follow the box's independent sx/sy (images are
|
|
126
|
+
// SCALE-only). Use the dominant drag axis (larger relative change) so
|
|
127
|
+
// dragging the width edge scales the image by the width ratio, the
|
|
128
|
+
// height edge by the height ratio, and a corner by the dominant of the
|
|
129
|
+
// two. Position still tracks the box via (sx, sy) below, so the image
|
|
130
|
+
// stays put in the group's layout — only its size stays proportional.
|
|
131
|
+
const imgScale = Math.abs(sx - 1) >= Math.abs(sy - 1) ? sx : sy;
|
|
132
|
+
// Anchor for the scale = the unchanging corner / edge midpoint
|
|
133
|
+
// of the original bounds (opposite to the dragged handle).
|
|
134
|
+
const ax = handle.includes("w") ? originalBounds.x + originalBounds.width : originalBounds.x;
|
|
135
|
+
const ay = handle.includes("n") ? originalBounds.y + originalBounds.height : originalBounds.y;
|
|
136
|
+
let runningScene = scene;
|
|
137
|
+
const patches = [];
|
|
138
|
+
for (const [id, snap] of origin.elements) {
|
|
139
|
+
const shape = getElement(runningScene, id);
|
|
140
|
+
if (!shape)
|
|
141
|
+
continue;
|
|
142
|
+
const newPx = ax + (snap.position.x - ax) * sx;
|
|
143
|
+
const newPy = ay + (snap.position.y - ay) * sy;
|
|
144
|
+
if (hasWidthHeight(shape)) {
|
|
145
|
+
// Images scale uniformly (aspect-locked); everything else follows
|
|
146
|
+
// the box's per-axis scale.
|
|
147
|
+
const isImage = shape.type === "image";
|
|
148
|
+
const wScale = isImage ? imgScale : sx;
|
|
149
|
+
const hScale = isImage ? imgScale : sy;
|
|
150
|
+
const newWidth = snap.bounds.width * wScale;
|
|
151
|
+
const newHeight = snap.bounds.height * hScale;
|
|
152
|
+
if (Math.abs(newWidth) < minDim || Math.abs(newHeight) < minDim)
|
|
153
|
+
continue;
|
|
154
|
+
const nextElement = {
|
|
155
|
+
...shape,
|
|
156
|
+
position: { x: newPx, y: newPy },
|
|
157
|
+
scale: {
|
|
158
|
+
x: newWidth >= 0 ? 1 : -1,
|
|
159
|
+
y: newHeight >= 0 ? 1 : -1,
|
|
160
|
+
},
|
|
161
|
+
width: Math.abs(newWidth),
|
|
162
|
+
height: Math.abs(newHeight),
|
|
163
|
+
};
|
|
164
|
+
const patch = { kind: "element", id, before: shape, after: nextElement };
|
|
165
|
+
runningScene = apply(runningScene, patch);
|
|
166
|
+
patches.push(patch);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
const newScaleX = snap.scale.x * sx;
|
|
170
|
+
const newScaleY = snap.scale.y * sy;
|
|
171
|
+
if (Math.abs(newScaleX) < minDim / Math.max(1, snap.bounds.width))
|
|
172
|
+
continue;
|
|
173
|
+
if (Math.abs(newScaleY) < minDim / Math.max(1, snap.bounds.height))
|
|
174
|
+
continue;
|
|
175
|
+
const nextElement = {
|
|
176
|
+
...shape,
|
|
177
|
+
position: { x: newPx, y: newPy },
|
|
178
|
+
scale: { x: newScaleX, y: newScaleY },
|
|
179
|
+
};
|
|
180
|
+
const patch = { kind: "element", id, before: shape, after: nextElement };
|
|
181
|
+
runningScene = apply(runningScene, patch);
|
|
182
|
+
patches.push(patch);
|
|
183
|
+
}
|
|
184
|
+
// Scale the links that ride with the box (selected ∪ bound-both) about the
|
|
185
|
+
// same anchor by the same (sx, sy) — geometry + free point endpoints.
|
|
186
|
+
for (const [id, linkOrigin] of origin.links ?? []) {
|
|
187
|
+
const current = getLink(runningScene, id);
|
|
188
|
+
if (!current)
|
|
189
|
+
continue;
|
|
190
|
+
const scaled = scaleLinkAround(linkOrigin, ax, ay, sx, sy);
|
|
191
|
+
if (!scaled)
|
|
192
|
+
continue;
|
|
193
|
+
const patch = { kind: "link", id, before: current, after: { ...current, ...scaled } };
|
|
194
|
+
runningScene = apply(runningScene, patch);
|
|
195
|
+
patches.push(patch);
|
|
196
|
+
}
|
|
197
|
+
return { scene: runningScene, patches };
|
|
198
|
+
};
|
|
199
|
+
//# sourceMappingURL=resize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize.js","sourceRoot":"","sources":["../../../src/editor/applies/resize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type Scene } from "@oh-just-another/scene";
|
|
2
|
+
import type { Bounds, LayerId } from "@oh-just-another/types";
|
|
3
|
+
import * as Selection from "../../selection.js";
|
|
4
|
+
import * as LinkSelection from "../../link-selection.js";
|
|
5
|
+
/**
|
|
6
|
+
* Compute the selection that results from a lasso rectangle.
|
|
7
|
+
*
|
|
8
|
+
* `mode: "replace"` swaps the selection wholesale; `"add"` extends
|
|
9
|
+
* `current` (Shift / Cmd lasso). Locked-layer shapes are skipped
|
|
10
|
+
* via the host-supplied `isLayerLocked` predicate.
|
|
11
|
+
*
|
|
12
|
+
* Pure — returns the new selection without touching anything. The
|
|
13
|
+
* caller (Editor) writes it back, clears `_selectedLink`, and
|
|
14
|
+
* fires `notify()`.
|
|
15
|
+
*/
|
|
16
|
+
export declare const selectByBounds: (scene: Scene, current: Selection.Selection, isLayerLocked: (id: LayerId) => boolean, bounds: Bounds, mode: "replace" | "add") => Selection.Selection;
|
|
17
|
+
/**
|
|
18
|
+
* Live-preview variant — bases the next selection on the captured
|
|
19
|
+
* `lassoBaseSelection` snapshot so `"replace"` mode shrinks back to
|
|
20
|
+
* whatever the box currently covers (instead of accumulating
|
|
21
|
+
* since press-down), and `"add"` mode keeps the user's pre-existing
|
|
22
|
+
* picks intact. Caller still owns the equality short-circuit and
|
|
23
|
+
* the `_selectedLink` clearing.
|
|
24
|
+
*/
|
|
25
|
+
export declare const selectByBoundsLive: (scene: Scene, base: Selection.Selection, isLayerLocked: (id: LayerId) => boolean, bounds: Bounds, mode: "replace" | "add") => Selection.Selection;
|
|
26
|
+
/**
|
|
27
|
+
* Link half of the marquee. A connector is captured when its ENTIRE drawn
|
|
28
|
+
* path lies inside `bounds` (fully-enclosed rule), so dragging a box across
|
|
29
|
+
* the canvas grabs only the links that are wholly within it. `"replace"`
|
|
30
|
+
* rebuilds from the box each frame; `"add"` keeps the pre-lasso link picks
|
|
31
|
+
* (`base`).
|
|
32
|
+
*/
|
|
33
|
+
export declare const selectLinksByBoundsLive: (scene: Scene, base: LinkSelection.LinkSelection, isLayerLocked: (id: LayerId) => boolean, bounds: Bounds, mode: "replace" | "add") => LinkSelection.LinkSelection;
|
|
34
|
+
//# sourceMappingURL=selection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/editor/applies/selection.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2C,KAAK,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAQ,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,aAAa,MAAM,yBAAyB,CAAC;AAGzD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,GACzB,OAAO,KAAK,EACZ,SAAS,SAAS,CAAC,SAAS,EAC5B,eAAe,CAAC,EAAE,EAAE,OAAO,KAAK,OAAO,EACvC,QAAQ,MAAM,EACd,MAAM,SAAS,GAAG,KAAK,KACtB,SAAS,CAAC,SAQZ,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAC7B,OAAO,KAAK,EACZ,MAAM,SAAS,CAAC,SAAS,EACzB,eAAe,CAAC,EAAE,EAAE,OAAO,KAAK,OAAO,EACvC,QAAQ,MAAM,EACd,MAAM,SAAS,GAAG,KAAK,KACtB,SAAS,CAAC,SAQZ,CAAC;AAKF;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,GAClC,OAAO,KAAK,EACZ,MAAM,aAAa,CAAC,aAAa,EACjC,eAAe,CAAC,EAAE,EAAE,OAAO,KAAK,OAAO,EACvC,QAAQ,MAAM,EACd,MAAM,SAAS,GAAG,KAAK,KACtB,aAAa,CAAC,aAShB,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { getElementsCoveredByBounds, getLinkPath } from "@oh-just-another/scene";
|
|
2
|
+
import * as Selection from "../../selection.js";
|
|
3
|
+
import * as LinkSelection from "../../link-selection.js";
|
|
4
|
+
import { LASSO_COVERAGE_THRESHOLD } from "../../constants.js";
|
|
5
|
+
/**
|
|
6
|
+
* Compute the selection that results from a lasso rectangle.
|
|
7
|
+
*
|
|
8
|
+
* `mode: "replace"` swaps the selection wholesale; `"add"` extends
|
|
9
|
+
* `current` (Shift / Cmd lasso). Locked-layer shapes are skipped
|
|
10
|
+
* via the host-supplied `isLayerLocked` predicate.
|
|
11
|
+
*
|
|
12
|
+
* Pure — returns the new selection without touching anything. The
|
|
13
|
+
* caller (Editor) writes it back, clears `_selectedLink`, and
|
|
14
|
+
* fires `notify()`.
|
|
15
|
+
*/
|
|
16
|
+
export const selectByBounds = (scene, current, isLayerLocked, bounds, mode) => {
|
|
17
|
+
const hits = getElementsCoveredByBounds(scene, bounds, LASSO_COVERAGE_THRESHOLD);
|
|
18
|
+
let next = mode === "replace" ? Selection.EMPTY : current;
|
|
19
|
+
for (const shape of hits) {
|
|
20
|
+
if (isLayerLocked(shape.layerId))
|
|
21
|
+
continue;
|
|
22
|
+
next = Selection.add(next, shape.id);
|
|
23
|
+
}
|
|
24
|
+
return next;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Live-preview variant — bases the next selection on the captured
|
|
28
|
+
* `lassoBaseSelection` snapshot so `"replace"` mode shrinks back to
|
|
29
|
+
* whatever the box currently covers (instead of accumulating
|
|
30
|
+
* since press-down), and `"add"` mode keeps the user's pre-existing
|
|
31
|
+
* picks intact. Caller still owns the equality short-circuit and
|
|
32
|
+
* the `_selectedLink` clearing.
|
|
33
|
+
*/
|
|
34
|
+
export const selectByBoundsLive = (scene, base, isLayerLocked, bounds, mode) => {
|
|
35
|
+
let next = mode === "replace" ? Selection.EMPTY : base;
|
|
36
|
+
const hits = getElementsCoveredByBounds(scene, bounds, LASSO_COVERAGE_THRESHOLD);
|
|
37
|
+
for (const shape of hits) {
|
|
38
|
+
if (isLayerLocked(shape.layerId))
|
|
39
|
+
continue;
|
|
40
|
+
next = Selection.add(next, shape.id);
|
|
41
|
+
}
|
|
42
|
+
return next;
|
|
43
|
+
};
|
|
44
|
+
const inside = (p, b) => p.x >= b.x && p.x <= b.x + b.width && p.y >= b.y && p.y <= b.y + b.height;
|
|
45
|
+
/**
|
|
46
|
+
* Link half of the marquee. A connector is captured when its ENTIRE drawn
|
|
47
|
+
* path lies inside `bounds` (fully-enclosed rule), so dragging a box across
|
|
48
|
+
* the canvas grabs only the links that are wholly within it. `"replace"`
|
|
49
|
+
* rebuilds from the box each frame; `"add"` keeps the pre-lasso link picks
|
|
50
|
+
* (`base`).
|
|
51
|
+
*/
|
|
52
|
+
export const selectLinksByBoundsLive = (scene, base, isLayerLocked, bounds, mode) => {
|
|
53
|
+
let next = mode === "replace" ? LinkSelection.EMPTY : base;
|
|
54
|
+
for (const edge of scene.links.values()) {
|
|
55
|
+
if (isLayerLocked(edge.layerId))
|
|
56
|
+
continue;
|
|
57
|
+
const path = getLinkPath(scene, edge);
|
|
58
|
+
if (!path || path.length < 2)
|
|
59
|
+
continue;
|
|
60
|
+
if (path.every((p) => inside(p, bounds)))
|
|
61
|
+
next = LinkSelection.add(next, edge.id);
|
|
62
|
+
}
|
|
63
|
+
return next;
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../../src/editor/applies/selection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Bounds, Vec2 } from "@oh-just-another/types";
|
|
2
|
+
import type { ElementId } from "@oh-just-another/types";
|
|
3
|
+
import type { HandleId } from "../../handle.js";
|
|
4
|
+
/**
|
|
5
|
+
* Snap-to-grid math. Pure functions that round gesture deltas / bounds
|
|
6
|
+
* onto a grid of `spacing` world units. The editor wrappers call these
|
|
7
|
+
* before handing the (adjusted) delta to the move / resize / create
|
|
8
|
+
* compute functions, so the snapping logic lives in one tested place
|
|
9
|
+
* and the compute functions stay grid-agnostic.
|
|
10
|
+
*
|
|
11
|
+
* Spacing resolution and the on/off gate live in scene
|
|
12
|
+
* (`resolveSnapSpacing` / `isSnapToGridEnabled`); these helpers assume
|
|
13
|
+
* snapping is on and `spacing > 0`.
|
|
14
|
+
*/
|
|
15
|
+
/** Round a world point to the nearest grid intersection. */
|
|
16
|
+
export declare const snapPointToGrid: (p: Vec2, spacing: number) => Vec2;
|
|
17
|
+
/**
|
|
18
|
+
* Adjust a single-shape move delta so the shape's press-time top-left
|
|
19
|
+
* (`originalBounds` origin) lands on the grid. Keeps the drag anchored
|
|
20
|
+
* to the grid regardless of where the shape started.
|
|
21
|
+
*/
|
|
22
|
+
export declare const snapMoveDelta: (originalBounds: Bounds, delta: Vec2, spacing: number) => Vec2;
|
|
23
|
+
/**
|
|
24
|
+
* Adjust a group-move delta so the group's top-most-left reference
|
|
25
|
+
* point snaps to the grid while every member keeps its relative
|
|
26
|
+
* position. The reference is the min corner across the press-time
|
|
27
|
+
* origins (each origin is an element's world position). Returns the
|
|
28
|
+
* delta unchanged when the snapshot is empty.
|
|
29
|
+
*/
|
|
30
|
+
export declare const snapGroupDelta: (origins: ReadonlyMap<ElementId, Vec2>, delta: Vec2, spacing: number) => Vec2;
|
|
31
|
+
/**
|
|
32
|
+
* Adjust a resize delta so the edge(s) the handle drags land on the
|
|
33
|
+
* grid. Only the axes the handle actually controls are snapped: edge
|
|
34
|
+
* handles (`n`/`s`/`e`/`w`) snap one axis, corners snap both. The
|
|
35
|
+
* stationary edges are untouched.
|
|
36
|
+
*/
|
|
37
|
+
export declare const snapResizeDelta: (originalBounds: Bounds, handle: HandleId, delta: Vec2, spacing: number) => Vec2;
|
|
38
|
+
/**
|
|
39
|
+
* Snap a freshly-drawn shape's bounds so both corners land on the grid.
|
|
40
|
+
* Width / height stay non-negative (the bounds are already normalised
|
|
41
|
+
* by the machine, but rounding can never make them negative since both
|
|
42
|
+
* corners round independently).
|
|
43
|
+
*/
|
|
44
|
+
export declare const snapCreateBounds: (bounds: Bounds, spacing: number) => Bounds;
|
|
45
|
+
//# sourceMappingURL=snap-grid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snap-grid.d.ts","sourceRoot":"","sources":["../../../src/editor/applies/snap-grid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;;;;;;;;GAUG;AAEH,4DAA4D;AAC5D,eAAO,MAAM,eAAe,GAAI,GAAG,IAAI,EAAE,SAAS,MAAM,KAAG,IAGzD,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,gBAAgB,MAAM,EAAE,OAAO,IAAI,EAAE,SAAS,MAAM,KAAG,IAMpF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GACzB,SAAS,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,EACrC,OAAO,IAAI,EACX,SAAS,MAAM,KACd,IAUF,CAAC;AAOF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAC1B,gBAAgB,MAAM,EACtB,QAAQ,QAAQ,EAChB,OAAO,IAAI,EACX,SAAS,MAAM,KACd,IAgBF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAI,QAAQ,MAAM,EAAE,SAAS,MAAM,KAAG,MAYlE,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snap-to-grid math. Pure functions that round gesture deltas / bounds
|
|
3
|
+
* onto a grid of `spacing` world units. The editor wrappers call these
|
|
4
|
+
* before handing the (adjusted) delta to the move / resize / create
|
|
5
|
+
* compute functions, so the snapping logic lives in one tested place
|
|
6
|
+
* and the compute functions stay grid-agnostic.
|
|
7
|
+
*
|
|
8
|
+
* Spacing resolution and the on/off gate live in scene
|
|
9
|
+
* (`resolveSnapSpacing` / `isSnapToGridEnabled`); these helpers assume
|
|
10
|
+
* snapping is on and `spacing > 0`.
|
|
11
|
+
*/
|
|
12
|
+
/** Round a world point to the nearest grid intersection. */
|
|
13
|
+
export const snapPointToGrid = (p, spacing) => ({
|
|
14
|
+
x: Math.round(p.x / spacing) * spacing,
|
|
15
|
+
y: Math.round(p.y / spacing) * spacing,
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* Adjust a single-shape move delta so the shape's press-time top-left
|
|
19
|
+
* (`originalBounds` origin) lands on the grid. Keeps the drag anchored
|
|
20
|
+
* to the grid regardless of where the shape started.
|
|
21
|
+
*/
|
|
22
|
+
export const snapMoveDelta = (originalBounds, delta, spacing) => {
|
|
23
|
+
const target = snapPointToGrid({ x: originalBounds.x + delta.x, y: originalBounds.y + delta.y }, spacing);
|
|
24
|
+
return { x: target.x - originalBounds.x, y: target.y - originalBounds.y };
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Adjust a group-move delta so the group's top-most-left reference
|
|
28
|
+
* point snaps to the grid while every member keeps its relative
|
|
29
|
+
* position. The reference is the min corner across the press-time
|
|
30
|
+
* origins (each origin is an element's world position). Returns the
|
|
31
|
+
* delta unchanged when the snapshot is empty.
|
|
32
|
+
*/
|
|
33
|
+
export const snapGroupDelta = (origins, delta, spacing) => {
|
|
34
|
+
let refX = Infinity;
|
|
35
|
+
let refY = Infinity;
|
|
36
|
+
for (const o of origins.values()) {
|
|
37
|
+
if (o.x < refX)
|
|
38
|
+
refX = o.x;
|
|
39
|
+
if (o.y < refY)
|
|
40
|
+
refY = o.y;
|
|
41
|
+
}
|
|
42
|
+
if (!Number.isFinite(refX))
|
|
43
|
+
return delta;
|
|
44
|
+
const target = snapPointToGrid({ x: refX + delta.x, y: refY + delta.y }, spacing);
|
|
45
|
+
return { x: target.x - refX, y: target.y - refY };
|
|
46
|
+
};
|
|
47
|
+
const HANDLE_MOVES_WEST = new Set(["nw", "w", "sw"]);
|
|
48
|
+
const HANDLE_MOVES_EAST = new Set(["ne", "e", "se"]);
|
|
49
|
+
const HANDLE_MOVES_NORTH = new Set(["nw", "n", "ne"]);
|
|
50
|
+
const HANDLE_MOVES_SOUTH = new Set(["sw", "s", "se"]);
|
|
51
|
+
/**
|
|
52
|
+
* Adjust a resize delta so the edge(s) the handle drags land on the
|
|
53
|
+
* grid. Only the axes the handle actually controls are snapped: edge
|
|
54
|
+
* handles (`n`/`s`/`e`/`w`) snap one axis, corners snap both. The
|
|
55
|
+
* stationary edges are untouched.
|
|
56
|
+
*/
|
|
57
|
+
export const snapResizeDelta = (originalBounds, handle, delta, spacing) => {
|
|
58
|
+
let dx = delta.x;
|
|
59
|
+
let dy = delta.y;
|
|
60
|
+
if (HANDLE_MOVES_WEST.has(handle) || HANDLE_MOVES_EAST.has(handle)) {
|
|
61
|
+
const edgeX = HANDLE_MOVES_WEST.has(handle)
|
|
62
|
+
? originalBounds.x
|
|
63
|
+
: originalBounds.x + originalBounds.width;
|
|
64
|
+
dx = Math.round((edgeX + delta.x) / spacing) * spacing - edgeX;
|
|
65
|
+
}
|
|
66
|
+
if (HANDLE_MOVES_NORTH.has(handle) || HANDLE_MOVES_SOUTH.has(handle)) {
|
|
67
|
+
const edgeY = HANDLE_MOVES_NORTH.has(handle)
|
|
68
|
+
? originalBounds.y
|
|
69
|
+
: originalBounds.y + originalBounds.height;
|
|
70
|
+
dy = Math.round((edgeY + delta.y) / spacing) * spacing - edgeY;
|
|
71
|
+
}
|
|
72
|
+
return { x: dx, y: dy };
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Snap a freshly-drawn shape's bounds so both corners land on the grid.
|
|
76
|
+
* Width / height stay non-negative (the bounds are already normalised
|
|
77
|
+
* by the machine, but rounding can never make them negative since both
|
|
78
|
+
* corners round independently).
|
|
79
|
+
*/
|
|
80
|
+
export const snapCreateBounds = (bounds, spacing) => {
|
|
81
|
+
const tl = snapPointToGrid({ x: bounds.x, y: bounds.y }, spacing);
|
|
82
|
+
const br = snapPointToGrid({ x: bounds.x + bounds.width, y: bounds.y + bounds.height }, spacing);
|
|
83
|
+
return {
|
|
84
|
+
x: tl.x,
|
|
85
|
+
y: tl.y,
|
|
86
|
+
width: Math.max(0, br.x - tl.x),
|
|
87
|
+
height: Math.max(0, br.y - tl.y),
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=snap-grid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snap-grid.js","sourceRoot":"","sources":["../../../src/editor/applies/snap-grid.ts"],"names":[],"mappings":"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"}
|