@fieldnotes/core 0.38.1 → 0.38.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +320 -252
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -9
- package/dist/index.d.ts +5 -9
- package/dist/index.js +320 -252
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4055,17 +4055,43 @@ var ContextMenu = class {
|
|
|
4055
4055
|
}
|
|
4056
4056
|
};
|
|
4057
4057
|
|
|
4058
|
-
// src/
|
|
4059
|
-
function
|
|
4060
|
-
const
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4058
|
+
// src/canvas/viewport-dom.ts
|
|
4059
|
+
function createWrapper() {
|
|
4060
|
+
const el = document.createElement("div");
|
|
4061
|
+
Object.assign(el.style, {
|
|
4062
|
+
position: "relative",
|
|
4063
|
+
width: "100%",
|
|
4064
|
+
height: "100%",
|
|
4065
|
+
overflow: "hidden",
|
|
4066
|
+
overscrollBehavior: "none",
|
|
4067
|
+
userSelect: "none",
|
|
4068
|
+
webkitUserSelect: "none"
|
|
4069
|
+
});
|
|
4070
|
+
return el;
|
|
4071
|
+
}
|
|
4072
|
+
function createCanvas() {
|
|
4073
|
+
const el = document.createElement("canvas");
|
|
4074
|
+
Object.assign(el.style, {
|
|
4075
|
+
position: "absolute",
|
|
4076
|
+
top: "0",
|
|
4077
|
+
left: "0",
|
|
4078
|
+
width: "100%",
|
|
4079
|
+
height: "100%"
|
|
4080
|
+
});
|
|
4081
|
+
return el;
|
|
4082
|
+
}
|
|
4083
|
+
function createDomLayer() {
|
|
4084
|
+
const el = document.createElement("div");
|
|
4085
|
+
Object.assign(el.style, {
|
|
4086
|
+
position: "absolute",
|
|
4087
|
+
top: "0",
|
|
4088
|
+
left: "0",
|
|
4089
|
+
width: "100%",
|
|
4090
|
+
height: "100%",
|
|
4091
|
+
pointerEvents: "none",
|
|
4092
|
+
transformOrigin: "0 0"
|
|
4093
|
+
});
|
|
4094
|
+
return el;
|
|
4069
4095
|
}
|
|
4070
4096
|
|
|
4071
4097
|
// src/elements/arrow-label-editor.ts
|
|
@@ -5689,6 +5715,19 @@ var MarginViewport = class {
|
|
|
5689
5715
|
}
|
|
5690
5716
|
};
|
|
5691
5717
|
|
|
5718
|
+
// src/elements/translate.ts
|
|
5719
|
+
function translateElementPatch(el, dx, dy) {
|
|
5720
|
+
const position = { x: el.position.x + dx, y: el.position.y + dy };
|
|
5721
|
+
if (el.type === "arrow") {
|
|
5722
|
+
return {
|
|
5723
|
+
position,
|
|
5724
|
+
from: { x: el.from.x + dx, y: el.from.y + dy },
|
|
5725
|
+
to: { x: el.to.x + dx, y: el.to.y + dy }
|
|
5726
|
+
};
|
|
5727
|
+
}
|
|
5728
|
+
return { position };
|
|
5729
|
+
}
|
|
5730
|
+
|
|
5692
5731
|
// src/elements/element-style.ts
|
|
5693
5732
|
function styleToPatch(element, style) {
|
|
5694
5733
|
const { color, fillColor, strokeWidth, opacity, fontSize } = style;
|
|
@@ -5776,7 +5815,7 @@ function getElementStyle(element) {
|
|
|
5776
5815
|
}
|
|
5777
5816
|
}
|
|
5778
5817
|
|
|
5779
|
-
// src/canvas/
|
|
5818
|
+
// src/canvas/selection-ops.ts
|
|
5780
5819
|
function unionBounds(list) {
|
|
5781
5820
|
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
5782
5821
|
for (const b of list) {
|
|
@@ -5787,16 +5826,244 @@ function unionBounds(list) {
|
|
|
5787
5826
|
}
|
|
5788
5827
|
return { x: minX, y: minY, w: maxX - minX, h: maxY - minY };
|
|
5789
5828
|
}
|
|
5790
|
-
var EMPTY_IDS = [];
|
|
5791
|
-
var ARROW_HIT_THRESHOLD = 10;
|
|
5792
|
-
function noop() {
|
|
5793
|
-
}
|
|
5794
5829
|
function sharedValue(values) {
|
|
5795
5830
|
const present = values.filter((v) => v !== void 0);
|
|
5796
5831
|
if (present.length === 0) return void 0;
|
|
5797
5832
|
const first = present[0];
|
|
5798
5833
|
return present.every((v) => v === first) ? first : void 0;
|
|
5799
5834
|
}
|
|
5835
|
+
var SelectionOps = class {
|
|
5836
|
+
constructor(deps) {
|
|
5837
|
+
this.deps = deps;
|
|
5838
|
+
}
|
|
5839
|
+
getStyle() {
|
|
5840
|
+
const ids = this.deps.getSelectedIds();
|
|
5841
|
+
if (ids.length === 0) return null;
|
|
5842
|
+
const styles = [];
|
|
5843
|
+
for (const id of ids) {
|
|
5844
|
+
const el = this.deps.store.getById(id);
|
|
5845
|
+
if (el) styles.push(getElementStyle(el));
|
|
5846
|
+
}
|
|
5847
|
+
if (styles.length === 0) return null;
|
|
5848
|
+
const result = {};
|
|
5849
|
+
const color = sharedValue(styles.map((s) => s.color));
|
|
5850
|
+
if (color !== void 0) result.color = color;
|
|
5851
|
+
const fillColor = sharedValue(styles.map((s) => s.fillColor));
|
|
5852
|
+
if (fillColor !== void 0) result.fillColor = fillColor;
|
|
5853
|
+
const strokeWidth = sharedValue(styles.map((s) => s.strokeWidth));
|
|
5854
|
+
if (strokeWidth !== void 0) result.strokeWidth = strokeWidth;
|
|
5855
|
+
const opacity = sharedValue(styles.map((s) => s.opacity));
|
|
5856
|
+
if (opacity !== void 0) result.opacity = opacity;
|
|
5857
|
+
const fontSize = sharedValue(styles.map((s) => s.fontSize));
|
|
5858
|
+
if (fontSize !== void 0) result.fontSize = fontSize;
|
|
5859
|
+
return result;
|
|
5860
|
+
}
|
|
5861
|
+
applyStyle(style) {
|
|
5862
|
+
const ids = this.deps.getSelectedIds();
|
|
5863
|
+
if (ids.length === 0) return;
|
|
5864
|
+
this.deps.recorder.begin();
|
|
5865
|
+
for (const id of ids) {
|
|
5866
|
+
const el = this.deps.store.getById(id);
|
|
5867
|
+
if (!el) continue;
|
|
5868
|
+
const patch = styleToPatch(el, style);
|
|
5869
|
+
if (Object.keys(patch).length > 0) {
|
|
5870
|
+
this.deps.store.update(id, patch);
|
|
5871
|
+
}
|
|
5872
|
+
}
|
|
5873
|
+
this.deps.recorder.commit();
|
|
5874
|
+
}
|
|
5875
|
+
group() {
|
|
5876
|
+
const ids = this.deps.getSelectedIds();
|
|
5877
|
+
if (ids.length < 2) return;
|
|
5878
|
+
const groupId = createId("group");
|
|
5879
|
+
this.deps.recorder.begin();
|
|
5880
|
+
for (const id of ids) {
|
|
5881
|
+
if (this.deps.store.getById(id)) this.deps.store.update(id, { groupId });
|
|
5882
|
+
}
|
|
5883
|
+
this.deps.recorder.commit();
|
|
5884
|
+
}
|
|
5885
|
+
ungroup() {
|
|
5886
|
+
const ids = this.deps.getSelectedIds();
|
|
5887
|
+
if (ids.length === 0) return;
|
|
5888
|
+
this.deps.recorder.begin();
|
|
5889
|
+
for (const id of ids) {
|
|
5890
|
+
const el = this.deps.store.getById(id);
|
|
5891
|
+
if (el && el.groupId !== void 0) this.deps.store.update(id, { groupId: void 0 });
|
|
5892
|
+
}
|
|
5893
|
+
this.deps.recorder.commit();
|
|
5894
|
+
}
|
|
5895
|
+
toggleLock() {
|
|
5896
|
+
const ids = this.deps.getSelectedIds();
|
|
5897
|
+
if (ids.length === 0) return;
|
|
5898
|
+
const anyUnlocked = ids.some((id) => {
|
|
5899
|
+
const el = this.deps.store.getById(id);
|
|
5900
|
+
return el ? !el.locked : false;
|
|
5901
|
+
});
|
|
5902
|
+
this.deps.recorder.begin();
|
|
5903
|
+
for (const id of ids) {
|
|
5904
|
+
const el = this.deps.store.getById(id);
|
|
5905
|
+
if (el && el.locked !== anyUnlocked) this.deps.store.update(id, { locked: anyUnlocked });
|
|
5906
|
+
}
|
|
5907
|
+
this.deps.recorder.commit();
|
|
5908
|
+
}
|
|
5909
|
+
align(edge) {
|
|
5910
|
+
const bounded = this.boundedSelection();
|
|
5911
|
+
if (bounded.length < 2) return;
|
|
5912
|
+
const B = unionBounds(bounded.map((e) => e.bounds));
|
|
5913
|
+
this.deps.recorder.begin();
|
|
5914
|
+
const moved = [];
|
|
5915
|
+
for (const { id, el, bounds: b } of bounded) {
|
|
5916
|
+
if (!this.isMovable(el)) continue;
|
|
5917
|
+
let dx = 0;
|
|
5918
|
+
let dy = 0;
|
|
5919
|
+
switch (edge) {
|
|
5920
|
+
case "left":
|
|
5921
|
+
dx = B.x - b.x;
|
|
5922
|
+
break;
|
|
5923
|
+
case "right":
|
|
5924
|
+
dx = B.x + B.w - (b.x + b.w);
|
|
5925
|
+
break;
|
|
5926
|
+
case "center-x":
|
|
5927
|
+
dx = B.x + B.w / 2 - (b.x + b.w / 2);
|
|
5928
|
+
break;
|
|
5929
|
+
case "top":
|
|
5930
|
+
dy = B.y - b.y;
|
|
5931
|
+
break;
|
|
5932
|
+
case "bottom":
|
|
5933
|
+
dy = B.y + B.h - (b.y + b.h);
|
|
5934
|
+
break;
|
|
5935
|
+
case "middle":
|
|
5936
|
+
dy = B.y + B.h / 2 - (b.y + b.h / 2);
|
|
5937
|
+
break;
|
|
5938
|
+
}
|
|
5939
|
+
if (dx === 0 && dy === 0) continue;
|
|
5940
|
+
this.deps.store.update(id, translateElementPatch(el, dx, dy));
|
|
5941
|
+
moved.push(id);
|
|
5942
|
+
}
|
|
5943
|
+
updateArrowsBoundToElements(moved, this.deps.store);
|
|
5944
|
+
this.deps.recorder.commit();
|
|
5945
|
+
this.deps.requestRender();
|
|
5946
|
+
}
|
|
5947
|
+
distribute(axis) {
|
|
5948
|
+
const bounded = this.boundedSelection();
|
|
5949
|
+
if (bounded.length < 3) return;
|
|
5950
|
+
const center2 = (b) => axis === "horizontal" ? b.x + b.w / 2 : b.y + b.h / 2;
|
|
5951
|
+
const sorted = [...bounded].sort((p, q) => center2(p.bounds) - center2(q.bounds));
|
|
5952
|
+
const first = sorted[0];
|
|
5953
|
+
const last = sorted[sorted.length - 1];
|
|
5954
|
+
if (!first || !last) return;
|
|
5955
|
+
const c0 = center2(first.bounds);
|
|
5956
|
+
const cN = center2(last.bounds);
|
|
5957
|
+
const n = sorted.length;
|
|
5958
|
+
this.deps.recorder.begin();
|
|
5959
|
+
const moved = [];
|
|
5960
|
+
for (let i = 1; i < n - 1; i++) {
|
|
5961
|
+
const item = sorted[i];
|
|
5962
|
+
if (!item || !this.isMovable(item.el)) continue;
|
|
5963
|
+
const target = c0 + i * (cN - c0) / (n - 1);
|
|
5964
|
+
const delta = target - center2(item.bounds);
|
|
5965
|
+
if (delta === 0) continue;
|
|
5966
|
+
const [dx, dy] = axis === "horizontal" ? [delta, 0] : [0, delta];
|
|
5967
|
+
this.deps.store.update(item.id, translateElementPatch(item.el, dx, dy));
|
|
5968
|
+
moved.push(item.id);
|
|
5969
|
+
}
|
|
5970
|
+
updateArrowsBoundToElements(moved, this.deps.store);
|
|
5971
|
+
this.deps.recorder.commit();
|
|
5972
|
+
this.deps.requestRender();
|
|
5973
|
+
}
|
|
5974
|
+
boundedSelection() {
|
|
5975
|
+
const out = [];
|
|
5976
|
+
for (const id of this.deps.getSelectedIds()) {
|
|
5977
|
+
const el = this.deps.store.getById(id);
|
|
5978
|
+
if (!el) continue;
|
|
5979
|
+
const bounds = getElementBounds(el);
|
|
5980
|
+
if (bounds) out.push({ id, el, bounds });
|
|
5981
|
+
}
|
|
5982
|
+
return out;
|
|
5983
|
+
}
|
|
5984
|
+
isMovable(el) {
|
|
5985
|
+
if (el.locked) return false;
|
|
5986
|
+
if (el.type === "arrow" && (el.fromBinding ?? el.toBinding)) return false;
|
|
5987
|
+
return true;
|
|
5988
|
+
}
|
|
5989
|
+
};
|
|
5990
|
+
|
|
5991
|
+
// src/canvas/grid-controller.ts
|
|
5992
|
+
var GridController = class {
|
|
5993
|
+
constructor(deps) {
|
|
5994
|
+
this.deps = deps;
|
|
5995
|
+
}
|
|
5996
|
+
listeners = /* @__PURE__ */ new Set();
|
|
5997
|
+
add(input) {
|
|
5998
|
+
const existing = this.deps.store.getElementsByType("grid")[0];
|
|
5999
|
+
this.deps.recorder.begin();
|
|
6000
|
+
if (existing) {
|
|
6001
|
+
this.deps.store.remove(existing.id);
|
|
6002
|
+
}
|
|
6003
|
+
const grid = createGrid({ ...input, layerId: this.deps.getActiveLayerId() });
|
|
6004
|
+
this.deps.store.add(grid);
|
|
6005
|
+
this.deps.recorder.commit();
|
|
6006
|
+
this.deps.requestRender();
|
|
6007
|
+
return grid.id;
|
|
6008
|
+
}
|
|
6009
|
+
update(updates) {
|
|
6010
|
+
const grid = this.deps.store.getElementsByType("grid")[0];
|
|
6011
|
+
if (!grid) return;
|
|
6012
|
+
this.deps.recorder.begin();
|
|
6013
|
+
this.deps.store.update(grid.id, updates);
|
|
6014
|
+
this.deps.recorder.commit();
|
|
6015
|
+
this.deps.requestRender();
|
|
6016
|
+
}
|
|
6017
|
+
remove() {
|
|
6018
|
+
const grid = this.deps.store.getElementsByType("grid")[0];
|
|
6019
|
+
if (!grid) return;
|
|
6020
|
+
this.deps.recorder.begin();
|
|
6021
|
+
this.deps.store.remove(grid.id);
|
|
6022
|
+
this.deps.recorder.commit();
|
|
6023
|
+
this.deps.requestRender();
|
|
6024
|
+
}
|
|
6025
|
+
getInfo() {
|
|
6026
|
+
const grid = this.deps.store.getElementsByType("grid")[0];
|
|
6027
|
+
if (!grid) return null;
|
|
6028
|
+
return {
|
|
6029
|
+
gridType: grid.gridType,
|
|
6030
|
+
hexOrientation: grid.hexOrientation,
|
|
6031
|
+
cellSize: grid.cellSize,
|
|
6032
|
+
cellRadius: grid.gridType === "hex" ? grid.cellSize : grid.cellSize / 2
|
|
6033
|
+
};
|
|
6034
|
+
}
|
|
6035
|
+
onChange(listener) {
|
|
6036
|
+
this.listeners.add(listener);
|
|
6037
|
+
return () => {
|
|
6038
|
+
this.listeners.delete(listener);
|
|
6039
|
+
};
|
|
6040
|
+
}
|
|
6041
|
+
syncContext() {
|
|
6042
|
+
const grid = this.deps.store.getElementsByType("grid")[0];
|
|
6043
|
+
if (grid) {
|
|
6044
|
+
this.deps.toolContext.gridSize = grid.cellSize;
|
|
6045
|
+
this.deps.toolContext.gridType = grid.gridType;
|
|
6046
|
+
this.deps.toolContext.hexOrientation = grid.hexOrientation;
|
|
6047
|
+
} else {
|
|
6048
|
+
this.deps.toolContext.gridSize = this.deps.defaultGridSize;
|
|
6049
|
+
this.deps.toolContext.gridType = void 0;
|
|
6050
|
+
this.deps.toolContext.hexOrientation = void 0;
|
|
6051
|
+
}
|
|
6052
|
+
this.notify();
|
|
6053
|
+
}
|
|
6054
|
+
notify() {
|
|
6055
|
+
const info = this.getInfo();
|
|
6056
|
+
for (const listener of this.listeners) {
|
|
6057
|
+
listener(info);
|
|
6058
|
+
}
|
|
6059
|
+
}
|
|
6060
|
+
};
|
|
6061
|
+
|
|
6062
|
+
// src/canvas/viewport.ts
|
|
6063
|
+
var EMPTY_IDS = [];
|
|
6064
|
+
var ARROW_HIT_THRESHOLD = 10;
|
|
6065
|
+
function noop() {
|
|
6066
|
+
}
|
|
5800
6067
|
var Viewport = class {
|
|
5801
6068
|
constructor(container, options = {}) {
|
|
5802
6069
|
this.container = container;
|
|
@@ -5839,9 +6106,15 @@ var Viewport = class {
|
|
|
5839
6106
|
this.dropHandler = options.onDrop;
|
|
5840
6107
|
this.history = new HistoryStack();
|
|
5841
6108
|
this.historyRecorder = new HistoryRecorder(this.store, this.history, this.layerManager);
|
|
5842
|
-
this.
|
|
5843
|
-
|
|
5844
|
-
|
|
6109
|
+
this.selectionOps = new SelectionOps({
|
|
6110
|
+
store: this.store,
|
|
6111
|
+
recorder: this.historyRecorder,
|
|
6112
|
+
getSelectedIds: () => this.getSelectedIds(),
|
|
6113
|
+
requestRender: () => this.requestRender()
|
|
6114
|
+
});
|
|
6115
|
+
this.wrapper = createWrapper();
|
|
6116
|
+
this.canvasEl = createCanvas();
|
|
6117
|
+
this.domLayer = createDomLayer();
|
|
5845
6118
|
this.wrapper.appendChild(this.canvasEl);
|
|
5846
6119
|
this.wrapper.appendChild(this.domLayer);
|
|
5847
6120
|
this.container.appendChild(this.wrapper);
|
|
@@ -5919,21 +6192,29 @@ var Viewport = class {
|
|
|
5919
6192
|
this.contextMenu?.close();
|
|
5920
6193
|
this.requestRender();
|
|
5921
6194
|
});
|
|
6195
|
+
this.gridController = new GridController({
|
|
6196
|
+
store: this.store,
|
|
6197
|
+
recorder: this.historyRecorder,
|
|
6198
|
+
requestRender: () => this.requestRender(),
|
|
6199
|
+
getActiveLayerId: () => this.layerManager.activeLayerId,
|
|
6200
|
+
toolContext: this.toolContext,
|
|
6201
|
+
defaultGridSize: this._gridSize
|
|
6202
|
+
});
|
|
5922
6203
|
this.unsubStore = [
|
|
5923
6204
|
this.store.on("add", (el) => {
|
|
5924
|
-
if (el.type === "grid") this.
|
|
6205
|
+
if (el.type === "grid") this.gridController.syncContext();
|
|
5925
6206
|
this.renderLoop.markLayerDirty(el.layerId);
|
|
5926
6207
|
this.requestRender();
|
|
5927
6208
|
}),
|
|
5928
6209
|
this.store.on("remove", (el) => {
|
|
5929
|
-
if (el.type === "grid") this.
|
|
6210
|
+
if (el.type === "grid") this.gridController.syncContext();
|
|
5930
6211
|
this.unbindArrowsFrom(el);
|
|
5931
6212
|
this.domNodeManager.removeDomNode(el.id);
|
|
5932
6213
|
this.renderLoop.markLayerDirty(el.layerId);
|
|
5933
6214
|
this.requestRender();
|
|
5934
6215
|
}),
|
|
5935
6216
|
this.store.on("update", ({ previous, current }) => {
|
|
5936
|
-
if (current.type === "grid") this.
|
|
6217
|
+
if (current.type === "grid") this.gridController.syncContext();
|
|
5937
6218
|
this.renderLoop.markLayerDirty(current.layerId);
|
|
5938
6219
|
if (previous.layerId !== current.layerId) {
|
|
5939
6220
|
this.renderLoop.markLayerDirty(previous.layerId);
|
|
@@ -5943,7 +6224,7 @@ var Viewport = class {
|
|
|
5943
6224
|
this.store.on("clear", () => {
|
|
5944
6225
|
this.domNodeManager.clearDomNodes();
|
|
5945
6226
|
this.renderLoop.markAllLayersDirty();
|
|
5946
|
-
this.
|
|
6227
|
+
this.gridController.syncContext();
|
|
5947
6228
|
this.requestRender();
|
|
5948
6229
|
})
|
|
5949
6230
|
];
|
|
@@ -5958,7 +6239,7 @@ var Viewport = class {
|
|
|
5958
6239
|
this.observeResize();
|
|
5959
6240
|
this.syncCanvasSize();
|
|
5960
6241
|
this.renderLoop.start();
|
|
5961
|
-
this.
|
|
6242
|
+
this.gridController.syncContext();
|
|
5962
6243
|
}
|
|
5963
6244
|
camera;
|
|
5964
6245
|
store;
|
|
@@ -5977,6 +6258,7 @@ var Viewport = class {
|
|
|
5977
6258
|
noteEditor;
|
|
5978
6259
|
arrowLabelEditor;
|
|
5979
6260
|
historyRecorder;
|
|
6261
|
+
selectionOps;
|
|
5980
6262
|
toolContext;
|
|
5981
6263
|
marginViewport;
|
|
5982
6264
|
resizeObserver = null;
|
|
@@ -5988,7 +6270,7 @@ var Viewport = class {
|
|
|
5988
6270
|
interactMode;
|
|
5989
6271
|
onHtmlElementMount;
|
|
5990
6272
|
dropHandler;
|
|
5991
|
-
|
|
6273
|
+
gridController;
|
|
5992
6274
|
doubleTapDetector = new DoubleTapDetector();
|
|
5993
6275
|
tapDownX = 0;
|
|
5994
6276
|
tapDownY = 0;
|
|
@@ -6160,48 +6442,19 @@ var Viewport = class {
|
|
|
6160
6442
|
this.requestRender();
|
|
6161
6443
|
}
|
|
6162
6444
|
addGrid(input) {
|
|
6163
|
-
|
|
6164
|
-
this.historyRecorder.begin();
|
|
6165
|
-
if (existing) {
|
|
6166
|
-
this.store.remove(existing.id);
|
|
6167
|
-
}
|
|
6168
|
-
const grid = createGrid({ ...input, layerId: this.layerManager.activeLayerId });
|
|
6169
|
-
this.store.add(grid);
|
|
6170
|
-
this.historyRecorder.commit();
|
|
6171
|
-
this.requestRender();
|
|
6172
|
-
return grid.id;
|
|
6445
|
+
return this.gridController.add(input);
|
|
6173
6446
|
}
|
|
6174
6447
|
updateGrid(updates) {
|
|
6175
|
-
|
|
6176
|
-
if (!grid) return;
|
|
6177
|
-
this.historyRecorder.begin();
|
|
6178
|
-
this.store.update(grid.id, updates);
|
|
6179
|
-
this.historyRecorder.commit();
|
|
6180
|
-
this.requestRender();
|
|
6448
|
+
this.gridController.update(updates);
|
|
6181
6449
|
}
|
|
6182
6450
|
removeGrid() {
|
|
6183
|
-
|
|
6184
|
-
if (!grid) return;
|
|
6185
|
-
this.historyRecorder.begin();
|
|
6186
|
-
this.store.remove(grid.id);
|
|
6187
|
-
this.historyRecorder.commit();
|
|
6188
|
-
this.requestRender();
|
|
6451
|
+
this.gridController.remove();
|
|
6189
6452
|
}
|
|
6190
6453
|
getGridInfo() {
|
|
6191
|
-
|
|
6192
|
-
if (!grid) return null;
|
|
6193
|
-
return {
|
|
6194
|
-
gridType: grid.gridType,
|
|
6195
|
-
hexOrientation: grid.hexOrientation,
|
|
6196
|
-
cellSize: grid.cellSize,
|
|
6197
|
-
cellRadius: grid.gridType === "hex" ? grid.cellSize : grid.cellSize / 2
|
|
6198
|
-
};
|
|
6454
|
+
return this.gridController.getInfo();
|
|
6199
6455
|
}
|
|
6200
6456
|
onGridChange(listener) {
|
|
6201
|
-
this.
|
|
6202
|
-
return () => {
|
|
6203
|
-
this.gridChangeListeners.delete(listener);
|
|
6204
|
-
};
|
|
6457
|
+
return this.gridController.onChange(listener);
|
|
6205
6458
|
}
|
|
6206
6459
|
getSelectTool() {
|
|
6207
6460
|
return this.toolManager.getTool("select");
|
|
@@ -6242,154 +6495,25 @@ var Viewport = class {
|
|
|
6242
6495
|
return tool ? tool.onSelectionChange(listener) : noop;
|
|
6243
6496
|
}
|
|
6244
6497
|
getSelectionStyle() {
|
|
6245
|
-
|
|
6246
|
-
if (ids.length === 0) return null;
|
|
6247
|
-
const styles = [];
|
|
6248
|
-
for (const id of ids) {
|
|
6249
|
-
const el = this.store.getById(id);
|
|
6250
|
-
if (el) styles.push(getElementStyle(el));
|
|
6251
|
-
}
|
|
6252
|
-
if (styles.length === 0) return null;
|
|
6253
|
-
const result = {};
|
|
6254
|
-
const color = sharedValue(styles.map((s) => s.color));
|
|
6255
|
-
if (color !== void 0) result.color = color;
|
|
6256
|
-
const fillColor = sharedValue(styles.map((s) => s.fillColor));
|
|
6257
|
-
if (fillColor !== void 0) result.fillColor = fillColor;
|
|
6258
|
-
const strokeWidth = sharedValue(styles.map((s) => s.strokeWidth));
|
|
6259
|
-
if (strokeWidth !== void 0) result.strokeWidth = strokeWidth;
|
|
6260
|
-
const opacity = sharedValue(styles.map((s) => s.opacity));
|
|
6261
|
-
if (opacity !== void 0) result.opacity = opacity;
|
|
6262
|
-
const fontSize = sharedValue(styles.map((s) => s.fontSize));
|
|
6263
|
-
if (fontSize !== void 0) result.fontSize = fontSize;
|
|
6264
|
-
return result;
|
|
6498
|
+
return this.selectionOps.getStyle();
|
|
6265
6499
|
}
|
|
6266
6500
|
applyStyleToSelection(style) {
|
|
6267
|
-
|
|
6268
|
-
if (ids.length === 0) return;
|
|
6269
|
-
this.historyRecorder.begin();
|
|
6270
|
-
for (const id of ids) {
|
|
6271
|
-
const el = this.store.getById(id);
|
|
6272
|
-
if (!el) continue;
|
|
6273
|
-
const patch = styleToPatch(el, style);
|
|
6274
|
-
if (Object.keys(patch).length > 0) {
|
|
6275
|
-
this.store.update(id, patch);
|
|
6276
|
-
}
|
|
6277
|
-
}
|
|
6278
|
-
this.historyRecorder.commit();
|
|
6501
|
+
this.selectionOps.applyStyle(style);
|
|
6279
6502
|
}
|
|
6280
6503
|
groupSelection() {
|
|
6281
|
-
|
|
6282
|
-
if (ids.length < 2) return;
|
|
6283
|
-
const groupId = createId("group");
|
|
6284
|
-
this.historyRecorder.begin();
|
|
6285
|
-
for (const id of ids) {
|
|
6286
|
-
if (this.store.getById(id)) this.store.update(id, { groupId });
|
|
6287
|
-
}
|
|
6288
|
-
this.historyRecorder.commit();
|
|
6504
|
+
this.selectionOps.group();
|
|
6289
6505
|
}
|
|
6290
6506
|
ungroupSelection() {
|
|
6291
|
-
|
|
6292
|
-
if (ids.length === 0) return;
|
|
6293
|
-
this.historyRecorder.begin();
|
|
6294
|
-
for (const id of ids) {
|
|
6295
|
-
const el = this.store.getById(id);
|
|
6296
|
-
if (el && el.groupId !== void 0) this.store.update(id, { groupId: void 0 });
|
|
6297
|
-
}
|
|
6298
|
-
this.historyRecorder.commit();
|
|
6507
|
+
this.selectionOps.ungroup();
|
|
6299
6508
|
}
|
|
6300
6509
|
toggleLockSelection() {
|
|
6301
|
-
|
|
6302
|
-
if (ids.length === 0) return;
|
|
6303
|
-
const anyUnlocked = ids.some((id) => {
|
|
6304
|
-
const el = this.store.getById(id);
|
|
6305
|
-
return el ? !el.locked : false;
|
|
6306
|
-
});
|
|
6307
|
-
this.historyRecorder.begin();
|
|
6308
|
-
for (const id of ids) {
|
|
6309
|
-
const el = this.store.getById(id);
|
|
6310
|
-
if (el && el.locked !== anyUnlocked) this.store.update(id, { locked: anyUnlocked });
|
|
6311
|
-
}
|
|
6312
|
-
this.historyRecorder.commit();
|
|
6510
|
+
this.selectionOps.toggleLock();
|
|
6313
6511
|
}
|
|
6314
6512
|
alignSelection(edge) {
|
|
6315
|
-
|
|
6316
|
-
if (bounded.length < 2) return;
|
|
6317
|
-
const B = unionBounds(bounded.map((e) => e.bounds));
|
|
6318
|
-
this.historyRecorder.begin();
|
|
6319
|
-
const moved = [];
|
|
6320
|
-
for (const { id, el, bounds: b } of bounded) {
|
|
6321
|
-
if (!this.isMovable(el)) continue;
|
|
6322
|
-
let dx = 0;
|
|
6323
|
-
let dy = 0;
|
|
6324
|
-
switch (edge) {
|
|
6325
|
-
case "left":
|
|
6326
|
-
dx = B.x - b.x;
|
|
6327
|
-
break;
|
|
6328
|
-
case "right":
|
|
6329
|
-
dx = B.x + B.w - (b.x + b.w);
|
|
6330
|
-
break;
|
|
6331
|
-
case "center-x":
|
|
6332
|
-
dx = B.x + B.w / 2 - (b.x + b.w / 2);
|
|
6333
|
-
break;
|
|
6334
|
-
case "top":
|
|
6335
|
-
dy = B.y - b.y;
|
|
6336
|
-
break;
|
|
6337
|
-
case "bottom":
|
|
6338
|
-
dy = B.y + B.h - (b.y + b.h);
|
|
6339
|
-
break;
|
|
6340
|
-
case "middle":
|
|
6341
|
-
dy = B.y + B.h / 2 - (b.y + b.h / 2);
|
|
6342
|
-
break;
|
|
6343
|
-
}
|
|
6344
|
-
if (dx === 0 && dy === 0) continue;
|
|
6345
|
-
this.store.update(id, translateElementPatch(el, dx, dy));
|
|
6346
|
-
moved.push(id);
|
|
6347
|
-
}
|
|
6348
|
-
updateArrowsBoundToElements(moved, this.store);
|
|
6349
|
-
this.historyRecorder.commit();
|
|
6350
|
-
this.requestRender();
|
|
6513
|
+
this.selectionOps.align(edge);
|
|
6351
6514
|
}
|
|
6352
6515
|
distributeSelection(axis) {
|
|
6353
|
-
|
|
6354
|
-
if (bounded.length < 3) return;
|
|
6355
|
-
const center2 = (b) => axis === "horizontal" ? b.x + b.w / 2 : b.y + b.h / 2;
|
|
6356
|
-
const sorted = [...bounded].sort((p, q) => center2(p.bounds) - center2(q.bounds));
|
|
6357
|
-
const first = sorted[0];
|
|
6358
|
-
const last = sorted[sorted.length - 1];
|
|
6359
|
-
if (!first || !last) return;
|
|
6360
|
-
const c0 = center2(first.bounds);
|
|
6361
|
-
const cN = center2(last.bounds);
|
|
6362
|
-
const n = sorted.length;
|
|
6363
|
-
this.historyRecorder.begin();
|
|
6364
|
-
const moved = [];
|
|
6365
|
-
for (let i = 1; i < n - 1; i++) {
|
|
6366
|
-
const item = sorted[i];
|
|
6367
|
-
if (!item || !this.isMovable(item.el)) continue;
|
|
6368
|
-
const target = c0 + i * (cN - c0) / (n - 1);
|
|
6369
|
-
const delta = target - center2(item.bounds);
|
|
6370
|
-
if (delta === 0) continue;
|
|
6371
|
-
const [dx, dy] = axis === "horizontal" ? [delta, 0] : [0, delta];
|
|
6372
|
-
this.store.update(item.id, translateElementPatch(item.el, dx, dy));
|
|
6373
|
-
moved.push(item.id);
|
|
6374
|
-
}
|
|
6375
|
-
updateArrowsBoundToElements(moved, this.store);
|
|
6376
|
-
this.historyRecorder.commit();
|
|
6377
|
-
this.requestRender();
|
|
6378
|
-
}
|
|
6379
|
-
boundedSelection() {
|
|
6380
|
-
const out = [];
|
|
6381
|
-
for (const id of this.getSelectedIds()) {
|
|
6382
|
-
const el = this.store.getById(id);
|
|
6383
|
-
if (!el) continue;
|
|
6384
|
-
const bounds = getElementBounds(el);
|
|
6385
|
-
if (bounds) out.push({ id, el, bounds });
|
|
6386
|
-
}
|
|
6387
|
-
return out;
|
|
6388
|
-
}
|
|
6389
|
-
isMovable(el) {
|
|
6390
|
-
if (el.locked) return false;
|
|
6391
|
-
if (el.type === "arrow" && (el.fromBinding ?? el.toBinding)) return false;
|
|
6392
|
-
return true;
|
|
6516
|
+
this.selectionOps.distribute(axis);
|
|
6393
6517
|
}
|
|
6394
6518
|
getRenderStats() {
|
|
6395
6519
|
return this.renderLoop.getStats();
|
|
@@ -6598,43 +6722,6 @@ var Viewport = class {
|
|
|
6598
6722
|
}
|
|
6599
6723
|
}
|
|
6600
6724
|
}
|
|
6601
|
-
createWrapper() {
|
|
6602
|
-
const el = document.createElement("div");
|
|
6603
|
-
Object.assign(el.style, {
|
|
6604
|
-
position: "relative",
|
|
6605
|
-
width: "100%",
|
|
6606
|
-
height: "100%",
|
|
6607
|
-
overflow: "hidden",
|
|
6608
|
-
overscrollBehavior: "none",
|
|
6609
|
-
userSelect: "none",
|
|
6610
|
-
webkitUserSelect: "none"
|
|
6611
|
-
});
|
|
6612
|
-
return el;
|
|
6613
|
-
}
|
|
6614
|
-
createCanvas() {
|
|
6615
|
-
const el = document.createElement("canvas");
|
|
6616
|
-
Object.assign(el.style, {
|
|
6617
|
-
position: "absolute",
|
|
6618
|
-
top: "0",
|
|
6619
|
-
left: "0",
|
|
6620
|
-
width: "100%",
|
|
6621
|
-
height: "100%"
|
|
6622
|
-
});
|
|
6623
|
-
return el;
|
|
6624
|
-
}
|
|
6625
|
-
createDomLayer() {
|
|
6626
|
-
const el = document.createElement("div");
|
|
6627
|
-
Object.assign(el.style, {
|
|
6628
|
-
position: "absolute",
|
|
6629
|
-
top: "0",
|
|
6630
|
-
left: "0",
|
|
6631
|
-
width: "100%",
|
|
6632
|
-
height: "100%",
|
|
6633
|
-
pointerEvents: "none",
|
|
6634
|
-
transformOrigin: "0 0"
|
|
6635
|
-
});
|
|
6636
|
-
return el;
|
|
6637
|
-
}
|
|
6638
6725
|
applyCameraTransform() {
|
|
6639
6726
|
this.domLayer.style.transform = this.camera.toCSSTransform();
|
|
6640
6727
|
}
|
|
@@ -6644,25 +6731,6 @@ var Viewport = class {
|
|
|
6644
6731
|
this.renderLoop.setCanvasSize(rect.width * dpr, rect.height * dpr);
|
|
6645
6732
|
this.requestRender();
|
|
6646
6733
|
}
|
|
6647
|
-
syncGridContext() {
|
|
6648
|
-
const grid = this.store.getElementsByType("grid")[0];
|
|
6649
|
-
if (grid) {
|
|
6650
|
-
this.toolContext.gridSize = grid.cellSize;
|
|
6651
|
-
this.toolContext.gridType = grid.gridType;
|
|
6652
|
-
this.toolContext.hexOrientation = grid.hexOrientation;
|
|
6653
|
-
} else {
|
|
6654
|
-
this.toolContext.gridSize = this._gridSize;
|
|
6655
|
-
this.toolContext.gridType = void 0;
|
|
6656
|
-
this.toolContext.hexOrientation = void 0;
|
|
6657
|
-
}
|
|
6658
|
-
this.notifyGridChangeListeners();
|
|
6659
|
-
}
|
|
6660
|
-
notifyGridChangeListeners() {
|
|
6661
|
-
const info = this.getGridInfo();
|
|
6662
|
-
for (const listener of this.gridChangeListeners) {
|
|
6663
|
-
listener(info);
|
|
6664
|
-
}
|
|
6665
|
-
}
|
|
6666
6734
|
observeResize() {
|
|
6667
6735
|
if (typeof ResizeObserver === "undefined") return;
|
|
6668
6736
|
this.resizeObserver = new ResizeObserver(() => this.syncCanvasSize());
|
|
@@ -8976,7 +9044,7 @@ var TemplateTool = class {
|
|
|
8976
9044
|
};
|
|
8977
9045
|
|
|
8978
9046
|
// src/index.ts
|
|
8979
|
-
var VERSION = "0.38.
|
|
9047
|
+
var VERSION = "0.38.2";
|
|
8980
9048
|
// Annotate the CommonJS export names for ESM import in node:
|
|
8981
9049
|
0 && (module.exports = {
|
|
8982
9050
|
ArrowTool,
|