@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.js
CHANGED
|
@@ -3974,17 +3974,43 @@ var ContextMenu = class {
|
|
|
3974
3974
|
}
|
|
3975
3975
|
};
|
|
3976
3976
|
|
|
3977
|
-
// src/
|
|
3978
|
-
function
|
|
3979
|
-
const
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3977
|
+
// src/canvas/viewport-dom.ts
|
|
3978
|
+
function createWrapper() {
|
|
3979
|
+
const el = document.createElement("div");
|
|
3980
|
+
Object.assign(el.style, {
|
|
3981
|
+
position: "relative",
|
|
3982
|
+
width: "100%",
|
|
3983
|
+
height: "100%",
|
|
3984
|
+
overflow: "hidden",
|
|
3985
|
+
overscrollBehavior: "none",
|
|
3986
|
+
userSelect: "none",
|
|
3987
|
+
webkitUserSelect: "none"
|
|
3988
|
+
});
|
|
3989
|
+
return el;
|
|
3990
|
+
}
|
|
3991
|
+
function createCanvas() {
|
|
3992
|
+
const el = document.createElement("canvas");
|
|
3993
|
+
Object.assign(el.style, {
|
|
3994
|
+
position: "absolute",
|
|
3995
|
+
top: "0",
|
|
3996
|
+
left: "0",
|
|
3997
|
+
width: "100%",
|
|
3998
|
+
height: "100%"
|
|
3999
|
+
});
|
|
4000
|
+
return el;
|
|
4001
|
+
}
|
|
4002
|
+
function createDomLayer() {
|
|
4003
|
+
const el = document.createElement("div");
|
|
4004
|
+
Object.assign(el.style, {
|
|
4005
|
+
position: "absolute",
|
|
4006
|
+
top: "0",
|
|
4007
|
+
left: "0",
|
|
4008
|
+
width: "100%",
|
|
4009
|
+
height: "100%",
|
|
4010
|
+
pointerEvents: "none",
|
|
4011
|
+
transformOrigin: "0 0"
|
|
4012
|
+
});
|
|
4013
|
+
return el;
|
|
3988
4014
|
}
|
|
3989
4015
|
|
|
3990
4016
|
// src/elements/arrow-label-editor.ts
|
|
@@ -5608,6 +5634,19 @@ var MarginViewport = class {
|
|
|
5608
5634
|
}
|
|
5609
5635
|
};
|
|
5610
5636
|
|
|
5637
|
+
// src/elements/translate.ts
|
|
5638
|
+
function translateElementPatch(el, dx, dy) {
|
|
5639
|
+
const position = { x: el.position.x + dx, y: el.position.y + dy };
|
|
5640
|
+
if (el.type === "arrow") {
|
|
5641
|
+
return {
|
|
5642
|
+
position,
|
|
5643
|
+
from: { x: el.from.x + dx, y: el.from.y + dy },
|
|
5644
|
+
to: { x: el.to.x + dx, y: el.to.y + dy }
|
|
5645
|
+
};
|
|
5646
|
+
}
|
|
5647
|
+
return { position };
|
|
5648
|
+
}
|
|
5649
|
+
|
|
5611
5650
|
// src/elements/element-style.ts
|
|
5612
5651
|
function styleToPatch(element, style) {
|
|
5613
5652
|
const { color, fillColor, strokeWidth, opacity, fontSize } = style;
|
|
@@ -5695,7 +5734,7 @@ function getElementStyle(element) {
|
|
|
5695
5734
|
}
|
|
5696
5735
|
}
|
|
5697
5736
|
|
|
5698
|
-
// src/canvas/
|
|
5737
|
+
// src/canvas/selection-ops.ts
|
|
5699
5738
|
function unionBounds(list) {
|
|
5700
5739
|
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
5701
5740
|
for (const b of list) {
|
|
@@ -5706,16 +5745,244 @@ function unionBounds(list) {
|
|
|
5706
5745
|
}
|
|
5707
5746
|
return { x: minX, y: minY, w: maxX - minX, h: maxY - minY };
|
|
5708
5747
|
}
|
|
5709
|
-
var EMPTY_IDS = [];
|
|
5710
|
-
var ARROW_HIT_THRESHOLD = 10;
|
|
5711
|
-
function noop() {
|
|
5712
|
-
}
|
|
5713
5748
|
function sharedValue(values) {
|
|
5714
5749
|
const present = values.filter((v) => v !== void 0);
|
|
5715
5750
|
if (present.length === 0) return void 0;
|
|
5716
5751
|
const first = present[0];
|
|
5717
5752
|
return present.every((v) => v === first) ? first : void 0;
|
|
5718
5753
|
}
|
|
5754
|
+
var SelectionOps = class {
|
|
5755
|
+
constructor(deps) {
|
|
5756
|
+
this.deps = deps;
|
|
5757
|
+
}
|
|
5758
|
+
getStyle() {
|
|
5759
|
+
const ids = this.deps.getSelectedIds();
|
|
5760
|
+
if (ids.length === 0) return null;
|
|
5761
|
+
const styles = [];
|
|
5762
|
+
for (const id of ids) {
|
|
5763
|
+
const el = this.deps.store.getById(id);
|
|
5764
|
+
if (el) styles.push(getElementStyle(el));
|
|
5765
|
+
}
|
|
5766
|
+
if (styles.length === 0) return null;
|
|
5767
|
+
const result = {};
|
|
5768
|
+
const color = sharedValue(styles.map((s) => s.color));
|
|
5769
|
+
if (color !== void 0) result.color = color;
|
|
5770
|
+
const fillColor = sharedValue(styles.map((s) => s.fillColor));
|
|
5771
|
+
if (fillColor !== void 0) result.fillColor = fillColor;
|
|
5772
|
+
const strokeWidth = sharedValue(styles.map((s) => s.strokeWidth));
|
|
5773
|
+
if (strokeWidth !== void 0) result.strokeWidth = strokeWidth;
|
|
5774
|
+
const opacity = sharedValue(styles.map((s) => s.opacity));
|
|
5775
|
+
if (opacity !== void 0) result.opacity = opacity;
|
|
5776
|
+
const fontSize = sharedValue(styles.map((s) => s.fontSize));
|
|
5777
|
+
if (fontSize !== void 0) result.fontSize = fontSize;
|
|
5778
|
+
return result;
|
|
5779
|
+
}
|
|
5780
|
+
applyStyle(style) {
|
|
5781
|
+
const ids = this.deps.getSelectedIds();
|
|
5782
|
+
if (ids.length === 0) return;
|
|
5783
|
+
this.deps.recorder.begin();
|
|
5784
|
+
for (const id of ids) {
|
|
5785
|
+
const el = this.deps.store.getById(id);
|
|
5786
|
+
if (!el) continue;
|
|
5787
|
+
const patch = styleToPatch(el, style);
|
|
5788
|
+
if (Object.keys(patch).length > 0) {
|
|
5789
|
+
this.deps.store.update(id, patch);
|
|
5790
|
+
}
|
|
5791
|
+
}
|
|
5792
|
+
this.deps.recorder.commit();
|
|
5793
|
+
}
|
|
5794
|
+
group() {
|
|
5795
|
+
const ids = this.deps.getSelectedIds();
|
|
5796
|
+
if (ids.length < 2) return;
|
|
5797
|
+
const groupId = createId("group");
|
|
5798
|
+
this.deps.recorder.begin();
|
|
5799
|
+
for (const id of ids) {
|
|
5800
|
+
if (this.deps.store.getById(id)) this.deps.store.update(id, { groupId });
|
|
5801
|
+
}
|
|
5802
|
+
this.deps.recorder.commit();
|
|
5803
|
+
}
|
|
5804
|
+
ungroup() {
|
|
5805
|
+
const ids = this.deps.getSelectedIds();
|
|
5806
|
+
if (ids.length === 0) return;
|
|
5807
|
+
this.deps.recorder.begin();
|
|
5808
|
+
for (const id of ids) {
|
|
5809
|
+
const el = this.deps.store.getById(id);
|
|
5810
|
+
if (el && el.groupId !== void 0) this.deps.store.update(id, { groupId: void 0 });
|
|
5811
|
+
}
|
|
5812
|
+
this.deps.recorder.commit();
|
|
5813
|
+
}
|
|
5814
|
+
toggleLock() {
|
|
5815
|
+
const ids = this.deps.getSelectedIds();
|
|
5816
|
+
if (ids.length === 0) return;
|
|
5817
|
+
const anyUnlocked = ids.some((id) => {
|
|
5818
|
+
const el = this.deps.store.getById(id);
|
|
5819
|
+
return el ? !el.locked : false;
|
|
5820
|
+
});
|
|
5821
|
+
this.deps.recorder.begin();
|
|
5822
|
+
for (const id of ids) {
|
|
5823
|
+
const el = this.deps.store.getById(id);
|
|
5824
|
+
if (el && el.locked !== anyUnlocked) this.deps.store.update(id, { locked: anyUnlocked });
|
|
5825
|
+
}
|
|
5826
|
+
this.deps.recorder.commit();
|
|
5827
|
+
}
|
|
5828
|
+
align(edge) {
|
|
5829
|
+
const bounded = this.boundedSelection();
|
|
5830
|
+
if (bounded.length < 2) return;
|
|
5831
|
+
const B = unionBounds(bounded.map((e) => e.bounds));
|
|
5832
|
+
this.deps.recorder.begin();
|
|
5833
|
+
const moved = [];
|
|
5834
|
+
for (const { id, el, bounds: b } of bounded) {
|
|
5835
|
+
if (!this.isMovable(el)) continue;
|
|
5836
|
+
let dx = 0;
|
|
5837
|
+
let dy = 0;
|
|
5838
|
+
switch (edge) {
|
|
5839
|
+
case "left":
|
|
5840
|
+
dx = B.x - b.x;
|
|
5841
|
+
break;
|
|
5842
|
+
case "right":
|
|
5843
|
+
dx = B.x + B.w - (b.x + b.w);
|
|
5844
|
+
break;
|
|
5845
|
+
case "center-x":
|
|
5846
|
+
dx = B.x + B.w / 2 - (b.x + b.w / 2);
|
|
5847
|
+
break;
|
|
5848
|
+
case "top":
|
|
5849
|
+
dy = B.y - b.y;
|
|
5850
|
+
break;
|
|
5851
|
+
case "bottom":
|
|
5852
|
+
dy = B.y + B.h - (b.y + b.h);
|
|
5853
|
+
break;
|
|
5854
|
+
case "middle":
|
|
5855
|
+
dy = B.y + B.h / 2 - (b.y + b.h / 2);
|
|
5856
|
+
break;
|
|
5857
|
+
}
|
|
5858
|
+
if (dx === 0 && dy === 0) continue;
|
|
5859
|
+
this.deps.store.update(id, translateElementPatch(el, dx, dy));
|
|
5860
|
+
moved.push(id);
|
|
5861
|
+
}
|
|
5862
|
+
updateArrowsBoundToElements(moved, this.deps.store);
|
|
5863
|
+
this.deps.recorder.commit();
|
|
5864
|
+
this.deps.requestRender();
|
|
5865
|
+
}
|
|
5866
|
+
distribute(axis) {
|
|
5867
|
+
const bounded = this.boundedSelection();
|
|
5868
|
+
if (bounded.length < 3) return;
|
|
5869
|
+
const center2 = (b) => axis === "horizontal" ? b.x + b.w / 2 : b.y + b.h / 2;
|
|
5870
|
+
const sorted = [...bounded].sort((p, q) => center2(p.bounds) - center2(q.bounds));
|
|
5871
|
+
const first = sorted[0];
|
|
5872
|
+
const last = sorted[sorted.length - 1];
|
|
5873
|
+
if (!first || !last) return;
|
|
5874
|
+
const c0 = center2(first.bounds);
|
|
5875
|
+
const cN = center2(last.bounds);
|
|
5876
|
+
const n = sorted.length;
|
|
5877
|
+
this.deps.recorder.begin();
|
|
5878
|
+
const moved = [];
|
|
5879
|
+
for (let i = 1; i < n - 1; i++) {
|
|
5880
|
+
const item = sorted[i];
|
|
5881
|
+
if (!item || !this.isMovable(item.el)) continue;
|
|
5882
|
+
const target = c0 + i * (cN - c0) / (n - 1);
|
|
5883
|
+
const delta = target - center2(item.bounds);
|
|
5884
|
+
if (delta === 0) continue;
|
|
5885
|
+
const [dx, dy] = axis === "horizontal" ? [delta, 0] : [0, delta];
|
|
5886
|
+
this.deps.store.update(item.id, translateElementPatch(item.el, dx, dy));
|
|
5887
|
+
moved.push(item.id);
|
|
5888
|
+
}
|
|
5889
|
+
updateArrowsBoundToElements(moved, this.deps.store);
|
|
5890
|
+
this.deps.recorder.commit();
|
|
5891
|
+
this.deps.requestRender();
|
|
5892
|
+
}
|
|
5893
|
+
boundedSelection() {
|
|
5894
|
+
const out = [];
|
|
5895
|
+
for (const id of this.deps.getSelectedIds()) {
|
|
5896
|
+
const el = this.deps.store.getById(id);
|
|
5897
|
+
if (!el) continue;
|
|
5898
|
+
const bounds = getElementBounds(el);
|
|
5899
|
+
if (bounds) out.push({ id, el, bounds });
|
|
5900
|
+
}
|
|
5901
|
+
return out;
|
|
5902
|
+
}
|
|
5903
|
+
isMovable(el) {
|
|
5904
|
+
if (el.locked) return false;
|
|
5905
|
+
if (el.type === "arrow" && (el.fromBinding ?? el.toBinding)) return false;
|
|
5906
|
+
return true;
|
|
5907
|
+
}
|
|
5908
|
+
};
|
|
5909
|
+
|
|
5910
|
+
// src/canvas/grid-controller.ts
|
|
5911
|
+
var GridController = class {
|
|
5912
|
+
constructor(deps) {
|
|
5913
|
+
this.deps = deps;
|
|
5914
|
+
}
|
|
5915
|
+
listeners = /* @__PURE__ */ new Set();
|
|
5916
|
+
add(input) {
|
|
5917
|
+
const existing = this.deps.store.getElementsByType("grid")[0];
|
|
5918
|
+
this.deps.recorder.begin();
|
|
5919
|
+
if (existing) {
|
|
5920
|
+
this.deps.store.remove(existing.id);
|
|
5921
|
+
}
|
|
5922
|
+
const grid = createGrid({ ...input, layerId: this.deps.getActiveLayerId() });
|
|
5923
|
+
this.deps.store.add(grid);
|
|
5924
|
+
this.deps.recorder.commit();
|
|
5925
|
+
this.deps.requestRender();
|
|
5926
|
+
return grid.id;
|
|
5927
|
+
}
|
|
5928
|
+
update(updates) {
|
|
5929
|
+
const grid = this.deps.store.getElementsByType("grid")[0];
|
|
5930
|
+
if (!grid) return;
|
|
5931
|
+
this.deps.recorder.begin();
|
|
5932
|
+
this.deps.store.update(grid.id, updates);
|
|
5933
|
+
this.deps.recorder.commit();
|
|
5934
|
+
this.deps.requestRender();
|
|
5935
|
+
}
|
|
5936
|
+
remove() {
|
|
5937
|
+
const grid = this.deps.store.getElementsByType("grid")[0];
|
|
5938
|
+
if (!grid) return;
|
|
5939
|
+
this.deps.recorder.begin();
|
|
5940
|
+
this.deps.store.remove(grid.id);
|
|
5941
|
+
this.deps.recorder.commit();
|
|
5942
|
+
this.deps.requestRender();
|
|
5943
|
+
}
|
|
5944
|
+
getInfo() {
|
|
5945
|
+
const grid = this.deps.store.getElementsByType("grid")[0];
|
|
5946
|
+
if (!grid) return null;
|
|
5947
|
+
return {
|
|
5948
|
+
gridType: grid.gridType,
|
|
5949
|
+
hexOrientation: grid.hexOrientation,
|
|
5950
|
+
cellSize: grid.cellSize,
|
|
5951
|
+
cellRadius: grid.gridType === "hex" ? grid.cellSize : grid.cellSize / 2
|
|
5952
|
+
};
|
|
5953
|
+
}
|
|
5954
|
+
onChange(listener) {
|
|
5955
|
+
this.listeners.add(listener);
|
|
5956
|
+
return () => {
|
|
5957
|
+
this.listeners.delete(listener);
|
|
5958
|
+
};
|
|
5959
|
+
}
|
|
5960
|
+
syncContext() {
|
|
5961
|
+
const grid = this.deps.store.getElementsByType("grid")[0];
|
|
5962
|
+
if (grid) {
|
|
5963
|
+
this.deps.toolContext.gridSize = grid.cellSize;
|
|
5964
|
+
this.deps.toolContext.gridType = grid.gridType;
|
|
5965
|
+
this.deps.toolContext.hexOrientation = grid.hexOrientation;
|
|
5966
|
+
} else {
|
|
5967
|
+
this.deps.toolContext.gridSize = this.deps.defaultGridSize;
|
|
5968
|
+
this.deps.toolContext.gridType = void 0;
|
|
5969
|
+
this.deps.toolContext.hexOrientation = void 0;
|
|
5970
|
+
}
|
|
5971
|
+
this.notify();
|
|
5972
|
+
}
|
|
5973
|
+
notify() {
|
|
5974
|
+
const info = this.getInfo();
|
|
5975
|
+
for (const listener of this.listeners) {
|
|
5976
|
+
listener(info);
|
|
5977
|
+
}
|
|
5978
|
+
}
|
|
5979
|
+
};
|
|
5980
|
+
|
|
5981
|
+
// src/canvas/viewport.ts
|
|
5982
|
+
var EMPTY_IDS = [];
|
|
5983
|
+
var ARROW_HIT_THRESHOLD = 10;
|
|
5984
|
+
function noop() {
|
|
5985
|
+
}
|
|
5719
5986
|
var Viewport = class {
|
|
5720
5987
|
constructor(container, options = {}) {
|
|
5721
5988
|
this.container = container;
|
|
@@ -5758,9 +6025,15 @@ var Viewport = class {
|
|
|
5758
6025
|
this.dropHandler = options.onDrop;
|
|
5759
6026
|
this.history = new HistoryStack();
|
|
5760
6027
|
this.historyRecorder = new HistoryRecorder(this.store, this.history, this.layerManager);
|
|
5761
|
-
this.
|
|
5762
|
-
|
|
5763
|
-
|
|
6028
|
+
this.selectionOps = new SelectionOps({
|
|
6029
|
+
store: this.store,
|
|
6030
|
+
recorder: this.historyRecorder,
|
|
6031
|
+
getSelectedIds: () => this.getSelectedIds(),
|
|
6032
|
+
requestRender: () => this.requestRender()
|
|
6033
|
+
});
|
|
6034
|
+
this.wrapper = createWrapper();
|
|
6035
|
+
this.canvasEl = createCanvas();
|
|
6036
|
+
this.domLayer = createDomLayer();
|
|
5764
6037
|
this.wrapper.appendChild(this.canvasEl);
|
|
5765
6038
|
this.wrapper.appendChild(this.domLayer);
|
|
5766
6039
|
this.container.appendChild(this.wrapper);
|
|
@@ -5838,21 +6111,29 @@ var Viewport = class {
|
|
|
5838
6111
|
this.contextMenu?.close();
|
|
5839
6112
|
this.requestRender();
|
|
5840
6113
|
});
|
|
6114
|
+
this.gridController = new GridController({
|
|
6115
|
+
store: this.store,
|
|
6116
|
+
recorder: this.historyRecorder,
|
|
6117
|
+
requestRender: () => this.requestRender(),
|
|
6118
|
+
getActiveLayerId: () => this.layerManager.activeLayerId,
|
|
6119
|
+
toolContext: this.toolContext,
|
|
6120
|
+
defaultGridSize: this._gridSize
|
|
6121
|
+
});
|
|
5841
6122
|
this.unsubStore = [
|
|
5842
6123
|
this.store.on("add", (el) => {
|
|
5843
|
-
if (el.type === "grid") this.
|
|
6124
|
+
if (el.type === "grid") this.gridController.syncContext();
|
|
5844
6125
|
this.renderLoop.markLayerDirty(el.layerId);
|
|
5845
6126
|
this.requestRender();
|
|
5846
6127
|
}),
|
|
5847
6128
|
this.store.on("remove", (el) => {
|
|
5848
|
-
if (el.type === "grid") this.
|
|
6129
|
+
if (el.type === "grid") this.gridController.syncContext();
|
|
5849
6130
|
this.unbindArrowsFrom(el);
|
|
5850
6131
|
this.domNodeManager.removeDomNode(el.id);
|
|
5851
6132
|
this.renderLoop.markLayerDirty(el.layerId);
|
|
5852
6133
|
this.requestRender();
|
|
5853
6134
|
}),
|
|
5854
6135
|
this.store.on("update", ({ previous, current }) => {
|
|
5855
|
-
if (current.type === "grid") this.
|
|
6136
|
+
if (current.type === "grid") this.gridController.syncContext();
|
|
5856
6137
|
this.renderLoop.markLayerDirty(current.layerId);
|
|
5857
6138
|
if (previous.layerId !== current.layerId) {
|
|
5858
6139
|
this.renderLoop.markLayerDirty(previous.layerId);
|
|
@@ -5862,7 +6143,7 @@ var Viewport = class {
|
|
|
5862
6143
|
this.store.on("clear", () => {
|
|
5863
6144
|
this.domNodeManager.clearDomNodes();
|
|
5864
6145
|
this.renderLoop.markAllLayersDirty();
|
|
5865
|
-
this.
|
|
6146
|
+
this.gridController.syncContext();
|
|
5866
6147
|
this.requestRender();
|
|
5867
6148
|
})
|
|
5868
6149
|
];
|
|
@@ -5877,7 +6158,7 @@ var Viewport = class {
|
|
|
5877
6158
|
this.observeResize();
|
|
5878
6159
|
this.syncCanvasSize();
|
|
5879
6160
|
this.renderLoop.start();
|
|
5880
|
-
this.
|
|
6161
|
+
this.gridController.syncContext();
|
|
5881
6162
|
}
|
|
5882
6163
|
camera;
|
|
5883
6164
|
store;
|
|
@@ -5896,6 +6177,7 @@ var Viewport = class {
|
|
|
5896
6177
|
noteEditor;
|
|
5897
6178
|
arrowLabelEditor;
|
|
5898
6179
|
historyRecorder;
|
|
6180
|
+
selectionOps;
|
|
5899
6181
|
toolContext;
|
|
5900
6182
|
marginViewport;
|
|
5901
6183
|
resizeObserver = null;
|
|
@@ -5907,7 +6189,7 @@ var Viewport = class {
|
|
|
5907
6189
|
interactMode;
|
|
5908
6190
|
onHtmlElementMount;
|
|
5909
6191
|
dropHandler;
|
|
5910
|
-
|
|
6192
|
+
gridController;
|
|
5911
6193
|
doubleTapDetector = new DoubleTapDetector();
|
|
5912
6194
|
tapDownX = 0;
|
|
5913
6195
|
tapDownY = 0;
|
|
@@ -6079,48 +6361,19 @@ var Viewport = class {
|
|
|
6079
6361
|
this.requestRender();
|
|
6080
6362
|
}
|
|
6081
6363
|
addGrid(input) {
|
|
6082
|
-
|
|
6083
|
-
this.historyRecorder.begin();
|
|
6084
|
-
if (existing) {
|
|
6085
|
-
this.store.remove(existing.id);
|
|
6086
|
-
}
|
|
6087
|
-
const grid = createGrid({ ...input, layerId: this.layerManager.activeLayerId });
|
|
6088
|
-
this.store.add(grid);
|
|
6089
|
-
this.historyRecorder.commit();
|
|
6090
|
-
this.requestRender();
|
|
6091
|
-
return grid.id;
|
|
6364
|
+
return this.gridController.add(input);
|
|
6092
6365
|
}
|
|
6093
6366
|
updateGrid(updates) {
|
|
6094
|
-
|
|
6095
|
-
if (!grid) return;
|
|
6096
|
-
this.historyRecorder.begin();
|
|
6097
|
-
this.store.update(grid.id, updates);
|
|
6098
|
-
this.historyRecorder.commit();
|
|
6099
|
-
this.requestRender();
|
|
6367
|
+
this.gridController.update(updates);
|
|
6100
6368
|
}
|
|
6101
6369
|
removeGrid() {
|
|
6102
|
-
|
|
6103
|
-
if (!grid) return;
|
|
6104
|
-
this.historyRecorder.begin();
|
|
6105
|
-
this.store.remove(grid.id);
|
|
6106
|
-
this.historyRecorder.commit();
|
|
6107
|
-
this.requestRender();
|
|
6370
|
+
this.gridController.remove();
|
|
6108
6371
|
}
|
|
6109
6372
|
getGridInfo() {
|
|
6110
|
-
|
|
6111
|
-
if (!grid) return null;
|
|
6112
|
-
return {
|
|
6113
|
-
gridType: grid.gridType,
|
|
6114
|
-
hexOrientation: grid.hexOrientation,
|
|
6115
|
-
cellSize: grid.cellSize,
|
|
6116
|
-
cellRadius: grid.gridType === "hex" ? grid.cellSize : grid.cellSize / 2
|
|
6117
|
-
};
|
|
6373
|
+
return this.gridController.getInfo();
|
|
6118
6374
|
}
|
|
6119
6375
|
onGridChange(listener) {
|
|
6120
|
-
this.
|
|
6121
|
-
return () => {
|
|
6122
|
-
this.gridChangeListeners.delete(listener);
|
|
6123
|
-
};
|
|
6376
|
+
return this.gridController.onChange(listener);
|
|
6124
6377
|
}
|
|
6125
6378
|
getSelectTool() {
|
|
6126
6379
|
return this.toolManager.getTool("select");
|
|
@@ -6161,154 +6414,25 @@ var Viewport = class {
|
|
|
6161
6414
|
return tool ? tool.onSelectionChange(listener) : noop;
|
|
6162
6415
|
}
|
|
6163
6416
|
getSelectionStyle() {
|
|
6164
|
-
|
|
6165
|
-
if (ids.length === 0) return null;
|
|
6166
|
-
const styles = [];
|
|
6167
|
-
for (const id of ids) {
|
|
6168
|
-
const el = this.store.getById(id);
|
|
6169
|
-
if (el) styles.push(getElementStyle(el));
|
|
6170
|
-
}
|
|
6171
|
-
if (styles.length === 0) return null;
|
|
6172
|
-
const result = {};
|
|
6173
|
-
const color = sharedValue(styles.map((s) => s.color));
|
|
6174
|
-
if (color !== void 0) result.color = color;
|
|
6175
|
-
const fillColor = sharedValue(styles.map((s) => s.fillColor));
|
|
6176
|
-
if (fillColor !== void 0) result.fillColor = fillColor;
|
|
6177
|
-
const strokeWidth = sharedValue(styles.map((s) => s.strokeWidth));
|
|
6178
|
-
if (strokeWidth !== void 0) result.strokeWidth = strokeWidth;
|
|
6179
|
-
const opacity = sharedValue(styles.map((s) => s.opacity));
|
|
6180
|
-
if (opacity !== void 0) result.opacity = opacity;
|
|
6181
|
-
const fontSize = sharedValue(styles.map((s) => s.fontSize));
|
|
6182
|
-
if (fontSize !== void 0) result.fontSize = fontSize;
|
|
6183
|
-
return result;
|
|
6417
|
+
return this.selectionOps.getStyle();
|
|
6184
6418
|
}
|
|
6185
6419
|
applyStyleToSelection(style) {
|
|
6186
|
-
|
|
6187
|
-
if (ids.length === 0) return;
|
|
6188
|
-
this.historyRecorder.begin();
|
|
6189
|
-
for (const id of ids) {
|
|
6190
|
-
const el = this.store.getById(id);
|
|
6191
|
-
if (!el) continue;
|
|
6192
|
-
const patch = styleToPatch(el, style);
|
|
6193
|
-
if (Object.keys(patch).length > 0) {
|
|
6194
|
-
this.store.update(id, patch);
|
|
6195
|
-
}
|
|
6196
|
-
}
|
|
6197
|
-
this.historyRecorder.commit();
|
|
6420
|
+
this.selectionOps.applyStyle(style);
|
|
6198
6421
|
}
|
|
6199
6422
|
groupSelection() {
|
|
6200
|
-
|
|
6201
|
-
if (ids.length < 2) return;
|
|
6202
|
-
const groupId = createId("group");
|
|
6203
|
-
this.historyRecorder.begin();
|
|
6204
|
-
for (const id of ids) {
|
|
6205
|
-
if (this.store.getById(id)) this.store.update(id, { groupId });
|
|
6206
|
-
}
|
|
6207
|
-
this.historyRecorder.commit();
|
|
6423
|
+
this.selectionOps.group();
|
|
6208
6424
|
}
|
|
6209
6425
|
ungroupSelection() {
|
|
6210
|
-
|
|
6211
|
-
if (ids.length === 0) return;
|
|
6212
|
-
this.historyRecorder.begin();
|
|
6213
|
-
for (const id of ids) {
|
|
6214
|
-
const el = this.store.getById(id);
|
|
6215
|
-
if (el && el.groupId !== void 0) this.store.update(id, { groupId: void 0 });
|
|
6216
|
-
}
|
|
6217
|
-
this.historyRecorder.commit();
|
|
6426
|
+
this.selectionOps.ungroup();
|
|
6218
6427
|
}
|
|
6219
6428
|
toggleLockSelection() {
|
|
6220
|
-
|
|
6221
|
-
if (ids.length === 0) return;
|
|
6222
|
-
const anyUnlocked = ids.some((id) => {
|
|
6223
|
-
const el = this.store.getById(id);
|
|
6224
|
-
return el ? !el.locked : false;
|
|
6225
|
-
});
|
|
6226
|
-
this.historyRecorder.begin();
|
|
6227
|
-
for (const id of ids) {
|
|
6228
|
-
const el = this.store.getById(id);
|
|
6229
|
-
if (el && el.locked !== anyUnlocked) this.store.update(id, { locked: anyUnlocked });
|
|
6230
|
-
}
|
|
6231
|
-
this.historyRecorder.commit();
|
|
6429
|
+
this.selectionOps.toggleLock();
|
|
6232
6430
|
}
|
|
6233
6431
|
alignSelection(edge) {
|
|
6234
|
-
|
|
6235
|
-
if (bounded.length < 2) return;
|
|
6236
|
-
const B = unionBounds(bounded.map((e) => e.bounds));
|
|
6237
|
-
this.historyRecorder.begin();
|
|
6238
|
-
const moved = [];
|
|
6239
|
-
for (const { id, el, bounds: b } of bounded) {
|
|
6240
|
-
if (!this.isMovable(el)) continue;
|
|
6241
|
-
let dx = 0;
|
|
6242
|
-
let dy = 0;
|
|
6243
|
-
switch (edge) {
|
|
6244
|
-
case "left":
|
|
6245
|
-
dx = B.x - b.x;
|
|
6246
|
-
break;
|
|
6247
|
-
case "right":
|
|
6248
|
-
dx = B.x + B.w - (b.x + b.w);
|
|
6249
|
-
break;
|
|
6250
|
-
case "center-x":
|
|
6251
|
-
dx = B.x + B.w / 2 - (b.x + b.w / 2);
|
|
6252
|
-
break;
|
|
6253
|
-
case "top":
|
|
6254
|
-
dy = B.y - b.y;
|
|
6255
|
-
break;
|
|
6256
|
-
case "bottom":
|
|
6257
|
-
dy = B.y + B.h - (b.y + b.h);
|
|
6258
|
-
break;
|
|
6259
|
-
case "middle":
|
|
6260
|
-
dy = B.y + B.h / 2 - (b.y + b.h / 2);
|
|
6261
|
-
break;
|
|
6262
|
-
}
|
|
6263
|
-
if (dx === 0 && dy === 0) continue;
|
|
6264
|
-
this.store.update(id, translateElementPatch(el, dx, dy));
|
|
6265
|
-
moved.push(id);
|
|
6266
|
-
}
|
|
6267
|
-
updateArrowsBoundToElements(moved, this.store);
|
|
6268
|
-
this.historyRecorder.commit();
|
|
6269
|
-
this.requestRender();
|
|
6432
|
+
this.selectionOps.align(edge);
|
|
6270
6433
|
}
|
|
6271
6434
|
distributeSelection(axis) {
|
|
6272
|
-
|
|
6273
|
-
if (bounded.length < 3) return;
|
|
6274
|
-
const center2 = (b) => axis === "horizontal" ? b.x + b.w / 2 : b.y + b.h / 2;
|
|
6275
|
-
const sorted = [...bounded].sort((p, q) => center2(p.bounds) - center2(q.bounds));
|
|
6276
|
-
const first = sorted[0];
|
|
6277
|
-
const last = sorted[sorted.length - 1];
|
|
6278
|
-
if (!first || !last) return;
|
|
6279
|
-
const c0 = center2(first.bounds);
|
|
6280
|
-
const cN = center2(last.bounds);
|
|
6281
|
-
const n = sorted.length;
|
|
6282
|
-
this.historyRecorder.begin();
|
|
6283
|
-
const moved = [];
|
|
6284
|
-
for (let i = 1; i < n - 1; i++) {
|
|
6285
|
-
const item = sorted[i];
|
|
6286
|
-
if (!item || !this.isMovable(item.el)) continue;
|
|
6287
|
-
const target = c0 + i * (cN - c0) / (n - 1);
|
|
6288
|
-
const delta = target - center2(item.bounds);
|
|
6289
|
-
if (delta === 0) continue;
|
|
6290
|
-
const [dx, dy] = axis === "horizontal" ? [delta, 0] : [0, delta];
|
|
6291
|
-
this.store.update(item.id, translateElementPatch(item.el, dx, dy));
|
|
6292
|
-
moved.push(item.id);
|
|
6293
|
-
}
|
|
6294
|
-
updateArrowsBoundToElements(moved, this.store);
|
|
6295
|
-
this.historyRecorder.commit();
|
|
6296
|
-
this.requestRender();
|
|
6297
|
-
}
|
|
6298
|
-
boundedSelection() {
|
|
6299
|
-
const out = [];
|
|
6300
|
-
for (const id of this.getSelectedIds()) {
|
|
6301
|
-
const el = this.store.getById(id);
|
|
6302
|
-
if (!el) continue;
|
|
6303
|
-
const bounds = getElementBounds(el);
|
|
6304
|
-
if (bounds) out.push({ id, el, bounds });
|
|
6305
|
-
}
|
|
6306
|
-
return out;
|
|
6307
|
-
}
|
|
6308
|
-
isMovable(el) {
|
|
6309
|
-
if (el.locked) return false;
|
|
6310
|
-
if (el.type === "arrow" && (el.fromBinding ?? el.toBinding)) return false;
|
|
6311
|
-
return true;
|
|
6435
|
+
this.selectionOps.distribute(axis);
|
|
6312
6436
|
}
|
|
6313
6437
|
getRenderStats() {
|
|
6314
6438
|
return this.renderLoop.getStats();
|
|
@@ -6517,43 +6641,6 @@ var Viewport = class {
|
|
|
6517
6641
|
}
|
|
6518
6642
|
}
|
|
6519
6643
|
}
|
|
6520
|
-
createWrapper() {
|
|
6521
|
-
const el = document.createElement("div");
|
|
6522
|
-
Object.assign(el.style, {
|
|
6523
|
-
position: "relative",
|
|
6524
|
-
width: "100%",
|
|
6525
|
-
height: "100%",
|
|
6526
|
-
overflow: "hidden",
|
|
6527
|
-
overscrollBehavior: "none",
|
|
6528
|
-
userSelect: "none",
|
|
6529
|
-
webkitUserSelect: "none"
|
|
6530
|
-
});
|
|
6531
|
-
return el;
|
|
6532
|
-
}
|
|
6533
|
-
createCanvas() {
|
|
6534
|
-
const el = document.createElement("canvas");
|
|
6535
|
-
Object.assign(el.style, {
|
|
6536
|
-
position: "absolute",
|
|
6537
|
-
top: "0",
|
|
6538
|
-
left: "0",
|
|
6539
|
-
width: "100%",
|
|
6540
|
-
height: "100%"
|
|
6541
|
-
});
|
|
6542
|
-
return el;
|
|
6543
|
-
}
|
|
6544
|
-
createDomLayer() {
|
|
6545
|
-
const el = document.createElement("div");
|
|
6546
|
-
Object.assign(el.style, {
|
|
6547
|
-
position: "absolute",
|
|
6548
|
-
top: "0",
|
|
6549
|
-
left: "0",
|
|
6550
|
-
width: "100%",
|
|
6551
|
-
height: "100%",
|
|
6552
|
-
pointerEvents: "none",
|
|
6553
|
-
transformOrigin: "0 0"
|
|
6554
|
-
});
|
|
6555
|
-
return el;
|
|
6556
|
-
}
|
|
6557
6644
|
applyCameraTransform() {
|
|
6558
6645
|
this.domLayer.style.transform = this.camera.toCSSTransform();
|
|
6559
6646
|
}
|
|
@@ -6563,25 +6650,6 @@ var Viewport = class {
|
|
|
6563
6650
|
this.renderLoop.setCanvasSize(rect.width * dpr, rect.height * dpr);
|
|
6564
6651
|
this.requestRender();
|
|
6565
6652
|
}
|
|
6566
|
-
syncGridContext() {
|
|
6567
|
-
const grid = this.store.getElementsByType("grid")[0];
|
|
6568
|
-
if (grid) {
|
|
6569
|
-
this.toolContext.gridSize = grid.cellSize;
|
|
6570
|
-
this.toolContext.gridType = grid.gridType;
|
|
6571
|
-
this.toolContext.hexOrientation = grid.hexOrientation;
|
|
6572
|
-
} else {
|
|
6573
|
-
this.toolContext.gridSize = this._gridSize;
|
|
6574
|
-
this.toolContext.gridType = void 0;
|
|
6575
|
-
this.toolContext.hexOrientation = void 0;
|
|
6576
|
-
}
|
|
6577
|
-
this.notifyGridChangeListeners();
|
|
6578
|
-
}
|
|
6579
|
-
notifyGridChangeListeners() {
|
|
6580
|
-
const info = this.getGridInfo();
|
|
6581
|
-
for (const listener of this.gridChangeListeners) {
|
|
6582
|
-
listener(info);
|
|
6583
|
-
}
|
|
6584
|
-
}
|
|
6585
6653
|
observeResize() {
|
|
6586
6654
|
if (typeof ResizeObserver === "undefined") return;
|
|
6587
6655
|
this.resizeObserver = new ResizeObserver(() => this.syncCanvasSize());
|
|
@@ -8895,7 +8963,7 @@ var TemplateTool = class {
|
|
|
8895
8963
|
};
|
|
8896
8964
|
|
|
8897
8965
|
// src/index.ts
|
|
8898
|
-
var VERSION = "0.38.
|
|
8966
|
+
var VERSION = "0.38.2";
|
|
8899
8967
|
export {
|
|
8900
8968
|
ArrowTool,
|
|
8901
8969
|
AutoSave,
|