@fieldnotes/core 0.32.0 → 0.34.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/README.md +25 -0
- package/dist/index.cjs +204 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +204 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -579,6 +579,31 @@ viewport.distributeSelection('horizontal'); // equal horizontal spacing
|
|
|
579
579
|
|
|
580
580
|
Grids are ignored by both operations.
|
|
581
581
|
|
|
582
|
+
## Smart Alignment Guides
|
|
583
|
+
|
|
584
|
+
Call `viewport.setSmartGuides(true)` to enable drag-time alignment snapping. While dragging a selection, its edges and centers snap to the edges and centers of nearby visible elements (within 6 screen pixels), and guide lines are drawn at each matched alignment. Smart guides replace grid snapping for the duration of the drag; the result is still committed as a single undo step.
|
|
585
|
+
|
|
586
|
+
```typescript
|
|
587
|
+
viewport.setSmartGuides(true); // enable
|
|
588
|
+
viewport.setSmartGuides(false); // disable (default)
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
## Grouping
|
|
592
|
+
|
|
593
|
+
Group elements so they select, move, delete, z-order, and align as a single unit.
|
|
594
|
+
|
|
595
|
+
- **`viewport.groupSelection()`** — groups the current selection under a new id.
|
|
596
|
+
- **`viewport.ungroupSelection()`** — dissolves any groups in the current selection.
|
|
597
|
+
|
|
598
|
+
Each is one undo step. Selecting any member selects its whole group, so to edit a single member individually, ungroup first. Pasting or duplicating a group keeps the copies grouped under a fresh id.
|
|
599
|
+
|
|
600
|
+
```typescript
|
|
601
|
+
viewport.groupSelection(); // Ctrl/Cmd+G
|
|
602
|
+
viewport.ungroupSelection(); // Ctrl/Cmd+Shift+G
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
The shortcuts are rebindable as `group` and `ungroup`.
|
|
606
|
+
|
|
582
607
|
## Built-in Interactions
|
|
583
608
|
|
|
584
609
|
| Input | Action |
|
package/dist/index.cjs
CHANGED
|
@@ -1021,6 +1021,14 @@ var KeyboardActions = class {
|
|
|
1021
1021
|
if (this.deps.isToolActive()) return;
|
|
1022
1022
|
this.deps.fitToContent?.();
|
|
1023
1023
|
}
|
|
1024
|
+
group() {
|
|
1025
|
+
if (this.deps.isToolActive()) return;
|
|
1026
|
+
this.deps.group?.();
|
|
1027
|
+
}
|
|
1028
|
+
ungroup() {
|
|
1029
|
+
if (this.deps.isToolActive()) return;
|
|
1030
|
+
this.deps.ungroup?.();
|
|
1031
|
+
}
|
|
1024
1032
|
zOrder(operation) {
|
|
1025
1033
|
if (this.deps.isToolActive()) return;
|
|
1026
1034
|
this.flushPendingNudge();
|
|
@@ -1054,6 +1062,10 @@ var KeyboardActions = class {
|
|
|
1054
1062
|
for (const el of source) {
|
|
1055
1063
|
idMap.set(el.id, createId(el.type));
|
|
1056
1064
|
}
|
|
1065
|
+
const groupIdMap = /* @__PURE__ */ new Map();
|
|
1066
|
+
for (const el of source) {
|
|
1067
|
+
if (el.groupId && !groupIdMap.has(el.groupId)) groupIdMap.set(el.groupId, createId("group"));
|
|
1068
|
+
}
|
|
1057
1069
|
const newIds = [];
|
|
1058
1070
|
const recorder = this.deps.getHistoryRecorder();
|
|
1059
1071
|
recorder?.begin();
|
|
@@ -1062,6 +1074,7 @@ var KeyboardActions = class {
|
|
|
1062
1074
|
const newId = idMap.get(el.id);
|
|
1063
1075
|
if (!newId) continue;
|
|
1064
1076
|
clone.id = newId;
|
|
1077
|
+
if (clone.groupId) clone.groupId = groupIdMap.get(clone.groupId) ?? clone.groupId;
|
|
1065
1078
|
clone.position = { x: clone.position.x + offset.x, y: clone.position.y + offset.y };
|
|
1066
1079
|
if (clone.type === "arrow") {
|
|
1067
1080
|
const arrow = clone;
|
|
@@ -1115,6 +1128,8 @@ var DEFAULT_BINDINGS = [
|
|
|
1115
1128
|
["zoom-in", ["mod+="]],
|
|
1116
1129
|
["zoom-out", ["mod+-"]],
|
|
1117
1130
|
["zoom-reset", ["mod+0"]],
|
|
1131
|
+
["group", ["mod+g"]],
|
|
1132
|
+
["ungroup", ["mod+shift+g"]],
|
|
1118
1133
|
["nudge-left", ["arrowleft"]],
|
|
1119
1134
|
["nudge-right", ["arrowright"]],
|
|
1120
1135
|
["nudge-up", ["arrowup"]],
|
|
@@ -1274,6 +1289,8 @@ var InputHandler = class {
|
|
|
1274
1289
|
getHistoryStack: () => this.historyStack,
|
|
1275
1290
|
isToolActive: () => this.isToolActive,
|
|
1276
1291
|
fitToContent: options.fitToContent,
|
|
1292
|
+
group: options.group,
|
|
1293
|
+
ungroup: options.ungroup,
|
|
1277
1294
|
getLastPointerWorld: () => this.lastPointerWorld()
|
|
1278
1295
|
});
|
|
1279
1296
|
this.shortcutMap = new ShortcutMap(options.shortcuts?.bindings);
|
|
@@ -1513,6 +1530,14 @@ var InputHandler = class {
|
|
|
1513
1530
|
e.preventDefault();
|
|
1514
1531
|
this.actions.zoomToFit();
|
|
1515
1532
|
return;
|
|
1533
|
+
case "group":
|
|
1534
|
+
e.preventDefault();
|
|
1535
|
+
this.actions.group();
|
|
1536
|
+
return;
|
|
1537
|
+
case "ungroup":
|
|
1538
|
+
e.preventDefault();
|
|
1539
|
+
this.actions.ungroup();
|
|
1540
|
+
return;
|
|
1516
1541
|
case "zoom-in":
|
|
1517
1542
|
e.preventDefault();
|
|
1518
1543
|
this.zoomByFactor(ZOOM_STEP);
|
|
@@ -4018,12 +4043,19 @@ var UpdateElementCommand = class {
|
|
|
4018
4043
|
this.current = current;
|
|
4019
4044
|
}
|
|
4020
4045
|
execute(store) {
|
|
4021
|
-
store.update(this.id,
|
|
4046
|
+
store.update(this.id, diffPatch(this.previous, this.current));
|
|
4022
4047
|
}
|
|
4023
4048
|
undo(store) {
|
|
4024
|
-
store.update(this.id,
|
|
4049
|
+
store.update(this.id, diffPatch(this.current, this.previous));
|
|
4025
4050
|
}
|
|
4026
4051
|
};
|
|
4052
|
+
function diffPatch(from, to) {
|
|
4053
|
+
const patch = { ...to };
|
|
4054
|
+
for (const key of Object.keys(from)) {
|
|
4055
|
+
if (!(key in to)) patch[key] = void 0;
|
|
4056
|
+
}
|
|
4057
|
+
return patch;
|
|
4058
|
+
}
|
|
4027
4059
|
var BatchCommand = class {
|
|
4028
4060
|
commands;
|
|
4029
4061
|
constructor(commands) {
|
|
@@ -5576,7 +5608,9 @@ var Viewport = class {
|
|
|
5576
5608
|
gridSize: this._gridSize,
|
|
5577
5609
|
activeLayerId: this.layerManager.activeLayerId,
|
|
5578
5610
|
isLayerVisible: (id) => this.layerManager.isLayerVisible(id),
|
|
5579
|
-
isLayerLocked: (id) => this.layerManager.isLayerLocked(id)
|
|
5611
|
+
isLayerLocked: (id) => this.layerManager.isLayerLocked(id),
|
|
5612
|
+
smartGuides: false,
|
|
5613
|
+
getVisibleRect: () => this.camera.getVisibleRect(this.canvasEl.clientWidth, this.canvasEl.clientHeight)
|
|
5580
5614
|
};
|
|
5581
5615
|
this.inputHandler = new InputHandler(this.wrapper, this.camera, {
|
|
5582
5616
|
toolManager: this.toolManager,
|
|
@@ -5584,6 +5618,8 @@ var Viewport = class {
|
|
|
5584
5618
|
historyRecorder: this.historyRecorder,
|
|
5585
5619
|
historyStack: this.history,
|
|
5586
5620
|
fitToContent: () => this.fitToContent(),
|
|
5621
|
+
group: () => this.groupSelection(),
|
|
5622
|
+
ungroup: () => this.ungroupSelection(),
|
|
5587
5623
|
shortcuts: options.shortcuts
|
|
5588
5624
|
});
|
|
5589
5625
|
this.domNodeManager = new DomNodeManager({
|
|
@@ -5680,6 +5716,7 @@ var Viewport = class {
|
|
|
5680
5716
|
marginViewport;
|
|
5681
5717
|
resizeObserver = null;
|
|
5682
5718
|
_snapToGrid = false;
|
|
5719
|
+
_smartGuides = false;
|
|
5683
5720
|
_gridSize;
|
|
5684
5721
|
renderLoop;
|
|
5685
5722
|
domNodeManager;
|
|
@@ -5700,6 +5737,13 @@ var Viewport = class {
|
|
|
5700
5737
|
this._snapToGrid = enabled;
|
|
5701
5738
|
this.toolContext.snapToGrid = enabled;
|
|
5702
5739
|
}
|
|
5740
|
+
get smartGuides() {
|
|
5741
|
+
return this._smartGuides;
|
|
5742
|
+
}
|
|
5743
|
+
setSmartGuides(enabled) {
|
|
5744
|
+
this._smartGuides = enabled;
|
|
5745
|
+
this.toolContext.smartGuides = enabled;
|
|
5746
|
+
}
|
|
5703
5747
|
fitToContent(padding = 40) {
|
|
5704
5748
|
if (this.wrapper.clientWidth === 0 || this.wrapper.clientHeight === 0) return;
|
|
5705
5749
|
const visibleElements = this.store.getAll().filter((el) => this.layerManager.isLayerVisible(el.layerId));
|
|
@@ -5913,6 +5957,26 @@ var Viewport = class {
|
|
|
5913
5957
|
}
|
|
5914
5958
|
this.historyRecorder.commit();
|
|
5915
5959
|
}
|
|
5960
|
+
groupSelection() {
|
|
5961
|
+
const ids = this.getSelectedIds();
|
|
5962
|
+
if (ids.length < 2) return;
|
|
5963
|
+
const groupId = createId("group");
|
|
5964
|
+
this.historyRecorder.begin();
|
|
5965
|
+
for (const id of ids) {
|
|
5966
|
+
if (this.store.getById(id)) this.store.update(id, { groupId });
|
|
5967
|
+
}
|
|
5968
|
+
this.historyRecorder.commit();
|
|
5969
|
+
}
|
|
5970
|
+
ungroupSelection() {
|
|
5971
|
+
const ids = this.getSelectedIds();
|
|
5972
|
+
if (ids.length === 0) return;
|
|
5973
|
+
this.historyRecorder.begin();
|
|
5974
|
+
for (const id of ids) {
|
|
5975
|
+
const el = this.store.getById(id);
|
|
5976
|
+
if (el && el.groupId !== void 0) this.store.update(id, { groupId: void 0 });
|
|
5977
|
+
}
|
|
5978
|
+
this.historyRecorder.commit();
|
|
5979
|
+
}
|
|
5916
5980
|
alignSelection(edge) {
|
|
5917
5981
|
const bounded = this.boundedSelection();
|
|
5918
5982
|
if (bounded.length < 2) return;
|
|
@@ -6622,6 +6686,26 @@ var EraserTool = class {
|
|
|
6622
6686
|
}
|
|
6623
6687
|
};
|
|
6624
6688
|
|
|
6689
|
+
// src/elements/group.ts
|
|
6690
|
+
function expandToGroups(ids, elements) {
|
|
6691
|
+
const byId = new Map(elements.map((e) => [e.id, e]));
|
|
6692
|
+
const groupIds = /* @__PURE__ */ new Set();
|
|
6693
|
+
for (const id of ids) {
|
|
6694
|
+
const g = byId.get(id)?.groupId;
|
|
6695
|
+
if (g) groupIds.add(g);
|
|
6696
|
+
}
|
|
6697
|
+
if (groupIds.size === 0) return ids;
|
|
6698
|
+
const idSet = new Set(ids);
|
|
6699
|
+
const result = [...ids];
|
|
6700
|
+
for (const el of elements) {
|
|
6701
|
+
if (el.groupId && groupIds.has(el.groupId) && !idSet.has(el.id)) {
|
|
6702
|
+
result.push(el.id);
|
|
6703
|
+
idSet.add(el.id);
|
|
6704
|
+
}
|
|
6705
|
+
}
|
|
6706
|
+
return result;
|
|
6707
|
+
}
|
|
6708
|
+
|
|
6625
6709
|
// src/tools/arrow-handles.ts
|
|
6626
6710
|
var BIND_THRESHOLD = 20;
|
|
6627
6711
|
var HANDLE_RADIUS = 5;
|
|
@@ -6737,8 +6821,47 @@ function renderArrowHandles(canvasCtx, arrow, zoom) {
|
|
|
6737
6821
|
}
|
|
6738
6822
|
}
|
|
6739
6823
|
|
|
6824
|
+
// src/elements/snap-guides.ts
|
|
6825
|
+
function xAnchors(b) {
|
|
6826
|
+
return { lo: b.x, mid: b.x + b.w / 2, hi: b.x + b.w };
|
|
6827
|
+
}
|
|
6828
|
+
function yAnchors(b) {
|
|
6829
|
+
return { lo: b.y, mid: b.y + b.h / 2, hi: b.y + b.h };
|
|
6830
|
+
}
|
|
6831
|
+
function bestAxisSnap(moving, targets, anchorsFn, threshold) {
|
|
6832
|
+
let best = null;
|
|
6833
|
+
for (const t of targets) {
|
|
6834
|
+
const ta = anchorsFn(t);
|
|
6835
|
+
const pairs = [
|
|
6836
|
+
// colinear alignment: same-type edges/centers line up
|
|
6837
|
+
[ta.lo - moving.lo, ta.lo],
|
|
6838
|
+
[ta.mid - moving.mid, ta.mid],
|
|
6839
|
+
[ta.hi - moving.hi, ta.hi],
|
|
6840
|
+
// abutment: the moving box sits flush against the target's opposite edge
|
|
6841
|
+
[ta.lo - moving.hi, ta.lo],
|
|
6842
|
+
[ta.hi - moving.lo, ta.hi]
|
|
6843
|
+
];
|
|
6844
|
+
for (const [delta, position] of pairs) {
|
|
6845
|
+
const abs = Math.abs(delta);
|
|
6846
|
+
if (abs <= threshold && (best === null || abs < Math.abs(best.delta))) {
|
|
6847
|
+
best = { delta, position };
|
|
6848
|
+
}
|
|
6849
|
+
}
|
|
6850
|
+
}
|
|
6851
|
+
return best;
|
|
6852
|
+
}
|
|
6853
|
+
function computeSnapGuides(moving, targets, threshold) {
|
|
6854
|
+
const xSnap = bestAxisSnap(xAnchors(moving), targets, xAnchors, threshold);
|
|
6855
|
+
const ySnap = bestAxisSnap(yAnchors(moving), targets, yAnchors, threshold);
|
|
6856
|
+
const guides = [];
|
|
6857
|
+
if (xSnap) guides.push({ axis: "x", position: xSnap.position });
|
|
6858
|
+
if (ySnap) guides.push({ axis: "y", position: ySnap.position });
|
|
6859
|
+
return { dx: xSnap?.delta ?? 0, dy: ySnap?.delta ?? 0, guides };
|
|
6860
|
+
}
|
|
6861
|
+
|
|
6740
6862
|
// src/tools/select-tool.ts
|
|
6741
6863
|
var HANDLE_SIZE = 8;
|
|
6864
|
+
var SNAP_PX = 6;
|
|
6742
6865
|
var HANDLE_HIT_PADDING2 = 4;
|
|
6743
6866
|
var SELECTION_PAD = 4;
|
|
6744
6867
|
var MIN_ELEMENT_SIZE = 20;
|
|
@@ -6758,6 +6881,9 @@ var SelectTool = class {
|
|
|
6758
6881
|
ctx = null;
|
|
6759
6882
|
pendingSingleSelectId = null;
|
|
6760
6883
|
hasDragged = false;
|
|
6884
|
+
activeGuides = [];
|
|
6885
|
+
dragSnapTargets = null;
|
|
6886
|
+
dragVisibleRect = null;
|
|
6761
6887
|
resizeAspectRatio = 0;
|
|
6762
6888
|
hoveredId = null;
|
|
6763
6889
|
get selectedIds() {
|
|
@@ -6789,6 +6915,9 @@ var SelectTool = class {
|
|
|
6789
6915
|
this.setSelectedIds([]);
|
|
6790
6916
|
this.mode = { type: "idle" };
|
|
6791
6917
|
this.hoveredId = null;
|
|
6918
|
+
this.activeGuides = [];
|
|
6919
|
+
this.dragSnapTargets = null;
|
|
6920
|
+
this.dragVisibleRect = null;
|
|
6792
6921
|
ctx.setCursor?.("default");
|
|
6793
6922
|
}
|
|
6794
6923
|
snap(point, ctx) {
|
|
@@ -6797,6 +6926,8 @@ var SelectTool = class {
|
|
|
6797
6926
|
onPointerDown(state, ctx) {
|
|
6798
6927
|
this.ctx = ctx;
|
|
6799
6928
|
this.setHovered(null, ctx);
|
|
6929
|
+
this.dragSnapTargets = null;
|
|
6930
|
+
this.dragVisibleRect = null;
|
|
6800
6931
|
const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
6801
6932
|
this.lastWorld = this.snap(world, ctx);
|
|
6802
6933
|
this.currentWorld = world;
|
|
@@ -6840,18 +6971,20 @@ var SelectTool = class {
|
|
|
6840
6971
|
this.hasDragged = false;
|
|
6841
6972
|
const hit = this.hitTest(world, ctx);
|
|
6842
6973
|
if (hit) {
|
|
6974
|
+
const all = ctx.store.getAll();
|
|
6843
6975
|
const alreadySelected = this._selectedIds.includes(hit.id);
|
|
6844
6976
|
if (state.shiftKey) {
|
|
6845
6977
|
if (alreadySelected) {
|
|
6846
|
-
|
|
6978
|
+
const grp = new Set(expandToGroups([hit.id], all));
|
|
6979
|
+
this.setSelectedIds(this._selectedIds.filter((id) => !grp.has(id)));
|
|
6847
6980
|
this.mode = { type: "idle" };
|
|
6848
6981
|
} else {
|
|
6849
|
-
this.setSelectedIds([...this._selectedIds, hit.id]);
|
|
6982
|
+
this.setSelectedIds(expandToGroups([...this._selectedIds, hit.id], all));
|
|
6850
6983
|
this.mode = hit.locked ? { type: "idle" } : { type: "dragging" };
|
|
6851
6984
|
}
|
|
6852
6985
|
} else {
|
|
6853
6986
|
if (!alreadySelected) {
|
|
6854
|
-
this.setSelectedIds([hit.id]);
|
|
6987
|
+
this.setSelectedIds(expandToGroups([hit.id], all));
|
|
6855
6988
|
} else if (this._selectedIds.length > 1) {
|
|
6856
6989
|
this.pendingSingleSelectId = hit.id;
|
|
6857
6990
|
}
|
|
@@ -6897,6 +7030,31 @@ var SelectTool = class {
|
|
|
6897
7030
|
const dx = snapped.x - this.lastWorld.x;
|
|
6898
7031
|
const dy = snapped.y - this.lastWorld.y;
|
|
6899
7032
|
this.lastWorld = snapped;
|
|
7033
|
+
let adjDx = dx;
|
|
7034
|
+
let adjDy = dy;
|
|
7035
|
+
this.activeGuides = [];
|
|
7036
|
+
if (ctx.smartGuides) {
|
|
7037
|
+
if (this.dragSnapTargets === null) {
|
|
7038
|
+
const selSet = new Set(this._selectedIds);
|
|
7039
|
+
this.dragVisibleRect = ctx.getVisibleRect?.() ?? null;
|
|
7040
|
+
const candidates = (this.dragVisibleRect ? ctx.store.queryRect(this.dragVisibleRect) : ctx.store.getAll()).filter((el) => !selSet.has(el.id) && el.type !== "grid");
|
|
7041
|
+
const targets = [];
|
|
7042
|
+
for (const el of candidates) {
|
|
7043
|
+
const b = getElementBounds(el);
|
|
7044
|
+
if (b) targets.push(b);
|
|
7045
|
+
}
|
|
7046
|
+
this.dragSnapTargets = targets;
|
|
7047
|
+
}
|
|
7048
|
+
const selectedEls = this._selectedIds.map((id) => ctx.store.getById(id)).filter((el) => !!el && !el.locked);
|
|
7049
|
+
const base = getElementsBoundingBox(selectedEls);
|
|
7050
|
+
if (base) {
|
|
7051
|
+
const moving = { x: base.x + dx, y: base.y + dy, w: base.w, h: base.h };
|
|
7052
|
+
const res = computeSnapGuides(moving, this.dragSnapTargets, SNAP_PX / ctx.camera.zoom);
|
|
7053
|
+
adjDx = dx + res.dx;
|
|
7054
|
+
adjDy = dy + res.dy;
|
|
7055
|
+
this.activeGuides = res.guides;
|
|
7056
|
+
}
|
|
7057
|
+
}
|
|
6900
7058
|
for (const id of this._selectedIds) {
|
|
6901
7059
|
const el = ctx.store.getById(id);
|
|
6902
7060
|
if (!el || el.locked) continue;
|
|
@@ -6905,13 +7063,13 @@ var SelectTool = class {
|
|
|
6905
7063
|
continue;
|
|
6906
7064
|
}
|
|
6907
7065
|
ctx.store.update(id, {
|
|
6908
|
-
position: { x: el.position.x +
|
|
6909
|
-
from: { x: el.from.x +
|
|
6910
|
-
to: { x: el.to.x +
|
|
7066
|
+
position: { x: el.position.x + adjDx, y: el.position.y + adjDy },
|
|
7067
|
+
from: { x: el.from.x + adjDx, y: el.from.y + adjDy },
|
|
7068
|
+
to: { x: el.to.x + adjDx, y: el.to.y + adjDy }
|
|
6911
7069
|
});
|
|
6912
|
-
} else if (ctx.gridType && "size" in el) {
|
|
6913
|
-
const centerX = el.position.x + el.size.w / 2 +
|
|
6914
|
-
const centerY = el.position.y + el.size.h / 2 +
|
|
7070
|
+
} else if (!ctx.smartGuides && ctx.gridType && "size" in el) {
|
|
7071
|
+
const centerX = el.position.x + el.size.w / 2 + adjDx;
|
|
7072
|
+
const centerY = el.position.y + el.size.h / 2 + adjDy;
|
|
6915
7073
|
const snappedCenter = this.snap({ x: centerX, y: centerY }, ctx);
|
|
6916
7074
|
ctx.store.update(id, {
|
|
6917
7075
|
position: {
|
|
@@ -6921,7 +7079,7 @@ var SelectTool = class {
|
|
|
6921
7079
|
});
|
|
6922
7080
|
} else {
|
|
6923
7081
|
ctx.store.update(id, {
|
|
6924
|
-
position: { x: el.position.x +
|
|
7082
|
+
position: { x: el.position.x + adjDx, y: el.position.y + adjDy }
|
|
6925
7083
|
});
|
|
6926
7084
|
}
|
|
6927
7085
|
}
|
|
@@ -6940,17 +7098,21 @@ var SelectTool = class {
|
|
|
6940
7098
|
if (this.mode.type === "marquee") {
|
|
6941
7099
|
const rect = this.getMarqueeRect();
|
|
6942
7100
|
if (rect) {
|
|
6943
|
-
this.setSelectedIds(this.findElementsInRect(rect, ctx));
|
|
7101
|
+
this.setSelectedIds(expandToGroups(this.findElementsInRect(rect, ctx), ctx.store.getAll()));
|
|
6944
7102
|
}
|
|
6945
7103
|
ctx.requestRender();
|
|
6946
7104
|
}
|
|
6947
7105
|
if (!this.hasDragged && this.pendingSingleSelectId !== null) {
|
|
6948
|
-
this.setSelectedIds([this.pendingSingleSelectId]);
|
|
7106
|
+
this.setSelectedIds(expandToGroups([this.pendingSingleSelectId], ctx.store.getAll()));
|
|
6949
7107
|
}
|
|
6950
7108
|
this.pendingSingleSelectId = null;
|
|
6951
7109
|
this.hasDragged = false;
|
|
6952
7110
|
const resizedNoteId = this.mode.type === "resizing" ? this.mode.elementId : null;
|
|
6953
7111
|
this.mode = { type: "idle" };
|
|
7112
|
+
this.activeGuides = [];
|
|
7113
|
+
this.dragSnapTargets = null;
|
|
7114
|
+
this.dragVisibleRect = null;
|
|
7115
|
+
ctx.requestRender();
|
|
6954
7116
|
ctx.setCursor?.("default");
|
|
6955
7117
|
if (resizedNoteId !== null) {
|
|
6956
7118
|
const el = ctx.store.getById(resizedNoteId);
|
|
@@ -6998,6 +7160,32 @@ var SelectTool = class {
|
|
|
6998
7160
|
}
|
|
6999
7161
|
}
|
|
7000
7162
|
}
|
|
7163
|
+
this.renderGuideLines(canvasCtx);
|
|
7164
|
+
}
|
|
7165
|
+
renderGuideLines(canvasCtx) {
|
|
7166
|
+
if (this.mode.type !== "dragging" || !this.ctx || this.activeGuides.length === 0) return;
|
|
7167
|
+
const zoom = this.ctx.camera.zoom;
|
|
7168
|
+
const rect = this.dragVisibleRect;
|
|
7169
|
+
canvasCtx.save();
|
|
7170
|
+
canvasCtx.strokeStyle = "#FF4081";
|
|
7171
|
+
canvasCtx.lineWidth = 1 / zoom;
|
|
7172
|
+
canvasCtx.setLineDash([]);
|
|
7173
|
+
for (const g of this.activeGuides) {
|
|
7174
|
+
canvasCtx.beginPath();
|
|
7175
|
+
if (g.axis === "x") {
|
|
7176
|
+
const y0 = rect ? rect.y : this.currentWorld.y - 1e5;
|
|
7177
|
+
const y1 = rect ? rect.y + rect.h : this.currentWorld.y + 1e5;
|
|
7178
|
+
canvasCtx.moveTo(g.position, y0);
|
|
7179
|
+
canvasCtx.lineTo(g.position, y1);
|
|
7180
|
+
} else {
|
|
7181
|
+
const x0 = rect ? rect.x : this.currentWorld.x - 1e5;
|
|
7182
|
+
const x1 = rect ? rect.x + rect.w : this.currentWorld.x + 1e5;
|
|
7183
|
+
canvasCtx.moveTo(x0, g.position);
|
|
7184
|
+
canvasCtx.lineTo(x1, g.position);
|
|
7185
|
+
}
|
|
7186
|
+
canvasCtx.stroke();
|
|
7187
|
+
}
|
|
7188
|
+
canvasCtx.restore();
|
|
7001
7189
|
}
|
|
7002
7190
|
updateArrowsBoundTo(ids, ctx) {
|
|
7003
7191
|
updateArrowsBoundToElements(ids, ctx.store);
|
|
@@ -8200,7 +8388,7 @@ var TemplateTool = class {
|
|
|
8200
8388
|
};
|
|
8201
8389
|
|
|
8202
8390
|
// src/index.ts
|
|
8203
|
-
var VERSION = "0.
|
|
8391
|
+
var VERSION = "0.34.0";
|
|
8204
8392
|
// Annotate the CommonJS export names for ESM import in node:
|
|
8205
8393
|
0 && (module.exports = {
|
|
8206
8394
|
ArrowTool,
|