@fieldnotes/core 0.57.0 → 0.58.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/dist/index.cjs +294 -94
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +81 -2
- package/dist/index.d.ts +81 -2
- package/dist/index.js +293 -94
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -37,6 +37,7 @@ __export(index_exports, {
|
|
|
37
37
|
MEASURE_PRESENCE_KIND: () => MEASURE_PRESENCE_KIND,
|
|
38
38
|
MeasureTool: () => MeasureTool,
|
|
39
39
|
MemoryAdapter: () => MemoryAdapter,
|
|
40
|
+
MinimapController: () => MinimapController,
|
|
40
41
|
NoteTool: () => NoteTool,
|
|
41
42
|
PING_PRESENCE_KIND: () => PING_PRESENCE_KIND,
|
|
42
43
|
PencilTool: () => PencilTool,
|
|
@@ -4796,88 +4797,247 @@ function miniToWorld(t, p) {
|
|
|
4796
4797
|
return { x: (p.x - t.offsetX) / t.scale, y: (p.y - t.offsetY) / t.scale };
|
|
4797
4798
|
}
|
|
4798
4799
|
|
|
4799
|
-
// src/canvas/minimap.ts
|
|
4800
|
-
var
|
|
4801
|
-
var
|
|
4802
|
-
var
|
|
4803
|
-
var
|
|
4800
|
+
// src/canvas/minimap-controller.ts
|
|
4801
|
+
var DEFAULT_WIDTH = 200;
|
|
4802
|
+
var DEFAULT_HEIGHT = 140;
|
|
4803
|
+
var DEFAULT_PADDING = 8;
|
|
4804
|
+
var DEFAULT_DEBOUNCE_MS2 = 200;
|
|
4805
|
+
var DEFAULT_VIEWPORT_STROKE = "#3b82f6";
|
|
4804
4806
|
var NEUTRAL = "rgba(100,116,139,0.6)";
|
|
4805
|
-
var
|
|
4807
|
+
var DOM_FALLBACK_TYPES = /* @__PURE__ */ new Set(["note", "text", "html"]);
|
|
4806
4808
|
function elementColor(el) {
|
|
4807
4809
|
return "color" in el && typeof el.color === "string" ? el.color : NEUTRAL;
|
|
4808
4810
|
}
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
Object.assign(canvas.style, {
|
|
4816
|
-
position: "absolute",
|
|
4817
|
-
right: `${MARGIN}px`,
|
|
4818
|
-
bottom: `${MARGIN}px`,
|
|
4819
|
-
width: `${WIDTH}px`,
|
|
4820
|
-
height: `${HEIGHT}px`,
|
|
4821
|
-
background: "rgba(255,255,255,0.85)",
|
|
4822
|
-
border: "1px solid rgba(0,0,0,0.15)",
|
|
4823
|
-
borderRadius: "4px",
|
|
4824
|
-
touchAction: "none",
|
|
4825
|
-
cursor: "pointer",
|
|
4826
|
-
zIndex: "10"
|
|
4827
|
-
});
|
|
4828
|
-
canvas.addEventListener("pointerdown", this.onPointerDown);
|
|
4829
|
-
canvas.addEventListener("pointermove", this.onPointerMove);
|
|
4830
|
-
canvas.addEventListener("pointerup", this.onPointerUp);
|
|
4831
|
-
this.deps.container.appendChild(canvas);
|
|
4811
|
+
function sameBounds(a, b) {
|
|
4812
|
+
return a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;
|
|
4813
|
+
}
|
|
4814
|
+
var MinimapController = class {
|
|
4815
|
+
constructor(viewport, canvas, options = {}) {
|
|
4816
|
+
this.viewport = viewport;
|
|
4832
4817
|
this.canvas = canvas;
|
|
4818
|
+
this.width = options.width ?? DEFAULT_WIDTH;
|
|
4819
|
+
this.height = options.height ?? DEFAULT_HEIGHT;
|
|
4820
|
+
this.padding = options.padding ?? DEFAULT_PADDING;
|
|
4821
|
+
this.background = options.background ?? null;
|
|
4822
|
+
this.viewportStroke = options.viewportStroke ?? DEFAULT_VIEWPORT_STROKE;
|
|
4823
|
+
this.debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS2;
|
|
4824
|
+
this.interactive = options.interactive !== false;
|
|
4825
|
+
this.requestFrame = options.requestFrame ?? ((cb) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(cb) : 0);
|
|
4826
|
+
this.cancelFrame = options.cancelFrame ?? ((id) => {
|
|
4827
|
+
if (typeof cancelAnimationFrame !== "undefined") cancelAnimationFrame(id);
|
|
4828
|
+
});
|
|
4829
|
+
this.renderer.setStore(viewport.store);
|
|
4830
|
+
this.renderer.setOnImageLoad(() => this.markSceneDirty());
|
|
4831
|
+
this.applyCanvasSize();
|
|
4832
|
+
const onScene = () => this.markSceneDirty();
|
|
4833
|
+
this.unsubs.push(
|
|
4834
|
+
viewport.store.on("add", onScene),
|
|
4835
|
+
viewport.store.on("remove", onScene),
|
|
4836
|
+
viewport.store.on("update", onScene),
|
|
4837
|
+
viewport.store.on("clear", onScene),
|
|
4838
|
+
viewport.layerManager.on("change", onScene),
|
|
4839
|
+
viewport.camera.onChange(() => this.onViewChanged()),
|
|
4840
|
+
viewport.onResize(() => this.onViewChanged())
|
|
4841
|
+
);
|
|
4842
|
+
if (this.interactive) {
|
|
4843
|
+
canvas.style.touchAction = "none";
|
|
4844
|
+
canvas.style.cursor = "pointer";
|
|
4845
|
+
canvas.addEventListener("pointerdown", this.onPointerDown);
|
|
4846
|
+
canvas.addEventListener("pointermove", this.onPointerMove);
|
|
4847
|
+
canvas.addEventListener("pointerup", this.onPointerUp);
|
|
4848
|
+
canvas.addEventListener("pointercancel", this.onPointerEnd);
|
|
4849
|
+
canvas.addEventListener("lostpointercapture", this.onPointerEnd);
|
|
4850
|
+
}
|
|
4851
|
+
this.renderScene();
|
|
4852
|
+
this.requestDraw();
|
|
4833
4853
|
}
|
|
4834
|
-
|
|
4835
|
-
|
|
4854
|
+
width;
|
|
4855
|
+
height;
|
|
4856
|
+
padding;
|
|
4857
|
+
background;
|
|
4858
|
+
viewportStroke;
|
|
4859
|
+
debounceMs;
|
|
4860
|
+
interactive;
|
|
4861
|
+
requestFrame;
|
|
4862
|
+
cancelFrame;
|
|
4863
|
+
renderer = new ElementRenderer();
|
|
4864
|
+
scene = null;
|
|
4865
|
+
frameId = null;
|
|
4866
|
+
debounceTimer = null;
|
|
4836
4867
|
dragging = false;
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4868
|
+
disposed = false;
|
|
4869
|
+
unsubs = [];
|
|
4870
|
+
setSize(width, height) {
|
|
4871
|
+
if (this.disposed) return;
|
|
4872
|
+
this.width = width;
|
|
4873
|
+
this.height = height;
|
|
4874
|
+
this.applyCanvasSize();
|
|
4875
|
+
this.clearDebounce();
|
|
4876
|
+
this.renderScene();
|
|
4877
|
+
this.requestDraw();
|
|
4840
4878
|
}
|
|
4841
|
-
|
|
4842
|
-
if (this.
|
|
4843
|
-
|
|
4844
|
-
|
|
4879
|
+
requestDraw() {
|
|
4880
|
+
if (this.disposed || this.frameId !== null) return;
|
|
4881
|
+
this.frameId = this.requestFrame(this.draw);
|
|
4882
|
+
}
|
|
4883
|
+
dispose() {
|
|
4884
|
+
if (this.disposed) return;
|
|
4885
|
+
this.disposed = true;
|
|
4886
|
+
this.clearDebounce();
|
|
4887
|
+
if (this.frameId !== null) {
|
|
4888
|
+
this.cancelFrame(this.frameId);
|
|
4889
|
+
this.frameId = null;
|
|
4890
|
+
}
|
|
4891
|
+
for (const unsub of this.unsubs.splice(0)) unsub();
|
|
4892
|
+
if (this.interactive) {
|
|
4893
|
+
this.canvas.removeEventListener("pointerdown", this.onPointerDown);
|
|
4894
|
+
this.canvas.removeEventListener("pointermove", this.onPointerMove);
|
|
4895
|
+
this.canvas.removeEventListener("pointerup", this.onPointerUp);
|
|
4896
|
+
this.canvas.removeEventListener("pointercancel", this.onPointerEnd);
|
|
4897
|
+
this.canvas.removeEventListener("lostpointercapture", this.onPointerEnd);
|
|
4898
|
+
}
|
|
4899
|
+
}
|
|
4900
|
+
clearDebounce() {
|
|
4901
|
+
if (this.debounceTimer !== null) {
|
|
4902
|
+
clearTimeout(this.debounceTimer);
|
|
4903
|
+
this.debounceTimer = null;
|
|
4904
|
+
}
|
|
4905
|
+
}
|
|
4906
|
+
dpr() {
|
|
4907
|
+
return typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1;
|
|
4908
|
+
}
|
|
4909
|
+
applyCanvasSize() {
|
|
4910
|
+
const dpr = this.dpr();
|
|
4911
|
+
this.canvas.width = Math.max(1, Math.round(this.width * dpr));
|
|
4912
|
+
this.canvas.height = Math.max(1, Math.round(this.height * dpr));
|
|
4913
|
+
}
|
|
4914
|
+
// Single source for both mapping bounds and rendering: layer-visible,
|
|
4915
|
+
// grids excluded. (getElementBounds already returns null for grids, so they
|
|
4916
|
+
// cannot extend the bounding box today — this filter makes the invariant
|
|
4917
|
+
// structural instead of relying on that special case.)
|
|
4918
|
+
sceneElements() {
|
|
4919
|
+
return this.viewport.store.getAll().filter((el) => el.type !== "grid" && this.viewport.layerManager.isLayerVisible(el.layerId));
|
|
4920
|
+
}
|
|
4921
|
+
currentMapping() {
|
|
4922
|
+
const viewportRect = this.viewport.getVisibleRect();
|
|
4923
|
+
const content = getElementsBoundingBox(this.sceneElements());
|
|
4924
|
+
return content ? unionBounds(content, viewportRect) : viewportRect;
|
|
4925
|
+
}
|
|
4926
|
+
onViewChanged() {
|
|
4927
|
+
if (this.disposed) return;
|
|
4928
|
+
const mapping = this.currentMapping();
|
|
4929
|
+
if (!this.scene || !sameBounds(mapping, this.scene.mapping)) {
|
|
4930
|
+
this.markSceneDirty();
|
|
4845
4931
|
}
|
|
4846
|
-
this.
|
|
4847
|
-
this.canvas.removeEventListener("pointermove", this.onPointerMove);
|
|
4848
|
-
this.canvas.removeEventListener("pointerup", this.onPointerUp);
|
|
4849
|
-
this.canvas.remove();
|
|
4932
|
+
this.requestDraw();
|
|
4850
4933
|
}
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4934
|
+
markSceneDirty() {
|
|
4935
|
+
if (this.disposed) return;
|
|
4936
|
+
this.clearDebounce();
|
|
4937
|
+
this.debounceTimer = setTimeout(() => {
|
|
4938
|
+
this.debounceTimer = null;
|
|
4939
|
+
this.renderScene();
|
|
4940
|
+
this.requestDraw();
|
|
4941
|
+
}, this.debounceMs);
|
|
4942
|
+
}
|
|
4943
|
+
renderScene() {
|
|
4944
|
+
if (this.disposed) return;
|
|
4945
|
+
const dpr = this.dpr();
|
|
4946
|
+
const mapping = this.currentMapping();
|
|
4947
|
+
const transform = computeMinimapTransform(mapping, this.width, this.height, this.padding);
|
|
4948
|
+
const sceneCanvas = document.createElement("canvas");
|
|
4949
|
+
sceneCanvas.width = Math.max(1, Math.round(this.width * dpr));
|
|
4950
|
+
sceneCanvas.height = Math.max(1, Math.round(this.height * dpr));
|
|
4951
|
+
const ctx = sceneCanvas.getContext("2d");
|
|
4952
|
+
if (!ctx) return;
|
|
4953
|
+
const byLayer = /* @__PURE__ */ new Map();
|
|
4954
|
+
for (const el of this.sceneElements()) {
|
|
4955
|
+
let list = byLayer.get(el.layerId);
|
|
4956
|
+
if (!list) {
|
|
4957
|
+
list = [];
|
|
4958
|
+
byLayer.set(el.layerId, list);
|
|
4959
|
+
}
|
|
4960
|
+
list.push(el);
|
|
4961
|
+
}
|
|
4962
|
+
for (const layer of this.viewport.layerManager.getLayers()) {
|
|
4963
|
+
const els = byLayer.get(layer.id);
|
|
4964
|
+
if (!els || els.length === 0) continue;
|
|
4965
|
+
const opacity = layer.opacity;
|
|
4966
|
+
if (opacity >= 1) {
|
|
4967
|
+
this.renderLayerElements(ctx, els, transform, dpr);
|
|
4968
|
+
continue;
|
|
4969
|
+
}
|
|
4970
|
+
const layerCanvas = document.createElement("canvas");
|
|
4971
|
+
layerCanvas.width = sceneCanvas.width;
|
|
4972
|
+
layerCanvas.height = sceneCanvas.height;
|
|
4973
|
+
const layerCtx = layerCanvas.getContext("2d");
|
|
4974
|
+
if (!layerCtx) continue;
|
|
4975
|
+
this.renderLayerElements(layerCtx, els, transform, dpr);
|
|
4976
|
+
ctx.save();
|
|
4977
|
+
ctx.globalAlpha = opacity;
|
|
4978
|
+
ctx.drawImage(layerCanvas, 0, 0);
|
|
4979
|
+
ctx.restore();
|
|
4980
|
+
}
|
|
4981
|
+
this.scene = { canvas: sceneCanvas, transform, mapping };
|
|
4982
|
+
}
|
|
4983
|
+
renderLayerElements(ctx, elements, t, dpr) {
|
|
4984
|
+
for (const el of elements) {
|
|
4985
|
+
if (DOM_FALLBACK_TYPES.has(el.type)) {
|
|
4986
|
+
const b = getElementBounds(el);
|
|
4987
|
+
if (!b) continue;
|
|
4988
|
+
const tl = worldToMini(t, { x: b.x, y: b.y });
|
|
4989
|
+
ctx.save();
|
|
4990
|
+
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
4991
|
+
ctx.fillStyle = elementColor(el);
|
|
4992
|
+
ctx.fillRect(tl.x, tl.y, Math.max(1, b.w * t.scale), Math.max(1, b.h * t.scale));
|
|
4993
|
+
ctx.restore();
|
|
4994
|
+
continue;
|
|
4995
|
+
}
|
|
4996
|
+
ctx.save();
|
|
4997
|
+
ctx.setTransform(dpr * t.scale, 0, 0, dpr * t.scale, dpr * t.offsetX, dpr * t.offsetY);
|
|
4998
|
+
this.renderer.renderCanvasElement(ctx, el);
|
|
4999
|
+
ctx.restore();
|
|
5000
|
+
}
|
|
4856
5001
|
}
|
|
4857
5002
|
draw = () => {
|
|
4858
|
-
this.
|
|
5003
|
+
this.frameId = null;
|
|
5004
|
+
if (this.disposed) return;
|
|
4859
5005
|
const ctx = this.canvas.getContext("2d");
|
|
4860
5006
|
if (!ctx) return;
|
|
4861
|
-
const
|
|
4862
|
-
|
|
4863
|
-
ctx.clearRect(0, 0,
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
const
|
|
4872
|
-
|
|
5007
|
+
const dpr = this.dpr();
|
|
5008
|
+
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
5009
|
+
ctx.clearRect(0, 0, this.width, this.height);
|
|
5010
|
+
if (this.background) {
|
|
5011
|
+
ctx.fillStyle = this.background;
|
|
5012
|
+
ctx.fillRect(0, 0, this.width, this.height);
|
|
5013
|
+
}
|
|
5014
|
+
const scene = this.scene;
|
|
5015
|
+
if (!scene) return;
|
|
5016
|
+
ctx.drawImage(scene.canvas, 0, 0, this.width, this.height);
|
|
5017
|
+
const viewportRect = this.viewport.getVisibleRect();
|
|
5018
|
+
const tl = worldToMini(scene.transform, { x: viewportRect.x, y: viewportRect.y });
|
|
5019
|
+
ctx.strokeStyle = this.viewportStroke;
|
|
4873
5020
|
ctx.lineWidth = 1.5;
|
|
4874
|
-
ctx.strokeRect(
|
|
5021
|
+
ctx.strokeRect(
|
|
5022
|
+
tl.x,
|
|
5023
|
+
tl.y,
|
|
5024
|
+
viewportRect.w * scene.transform.scale,
|
|
5025
|
+
viewportRect.h * scene.transform.scale
|
|
5026
|
+
);
|
|
4875
5027
|
};
|
|
5028
|
+
navTransform() {
|
|
5029
|
+
return this.scene?.transform ?? computeMinimapTransform(this.currentMapping(), this.width, this.height, this.padding);
|
|
5030
|
+
}
|
|
4876
5031
|
navigateFromEvent(e) {
|
|
4877
5032
|
const rect = this.canvas.getBoundingClientRect();
|
|
4878
|
-
const
|
|
4879
|
-
const
|
|
4880
|
-
|
|
5033
|
+
const scaleX = rect.width > 0 ? this.width / rect.width : 1;
|
|
5034
|
+
const scaleY = rect.height > 0 ? this.height / rect.height : 1;
|
|
5035
|
+
const point = {
|
|
5036
|
+
x: (e.clientX - rect.left) * scaleX,
|
|
5037
|
+
y: (e.clientY - rect.top) * scaleY
|
|
5038
|
+
};
|
|
5039
|
+
const world = miniToWorld(this.navTransform(), point);
|
|
5040
|
+
this.viewport.centerCameraAt(world);
|
|
4881
5041
|
}
|
|
4882
5042
|
onPointerDown = (e) => {
|
|
4883
5043
|
e.stopPropagation();
|
|
@@ -4898,6 +5058,45 @@ var Minimap = class {
|
|
|
4898
5058
|
} catch {
|
|
4899
5059
|
}
|
|
4900
5060
|
};
|
|
5061
|
+
// pointercancel / lostpointercapture: a browser gesture or interrupted touch
|
|
5062
|
+
// can end the interaction without a pointerup — the drag must not stick.
|
|
5063
|
+
onPointerEnd = () => {
|
|
5064
|
+
this.dragging = false;
|
|
5065
|
+
};
|
|
5066
|
+
};
|
|
5067
|
+
|
|
5068
|
+
// src/canvas/minimap.ts
|
|
5069
|
+
var WIDTH = 200;
|
|
5070
|
+
var HEIGHT = 140;
|
|
5071
|
+
var MARGIN = 16;
|
|
5072
|
+
var Minimap = class {
|
|
5073
|
+
canvas;
|
|
5074
|
+
controller;
|
|
5075
|
+
constructor(container, viewport) {
|
|
5076
|
+
const canvas = document.createElement("canvas");
|
|
5077
|
+
Object.assign(canvas.style, {
|
|
5078
|
+
position: "absolute",
|
|
5079
|
+
right: `${MARGIN}px`,
|
|
5080
|
+
bottom: `${MARGIN}px`,
|
|
5081
|
+
width: `${WIDTH}px`,
|
|
5082
|
+
height: `${HEIGHT}px`,
|
|
5083
|
+
background: "rgba(255,255,255,0.85)",
|
|
5084
|
+
border: "1px solid rgba(0,0,0,0.15)",
|
|
5085
|
+
borderRadius: "4px",
|
|
5086
|
+
zIndex: "10"
|
|
5087
|
+
});
|
|
5088
|
+
canvas.dataset.fieldnotesMinimap = "true";
|
|
5089
|
+
container.appendChild(canvas);
|
|
5090
|
+
this.canvas = canvas;
|
|
5091
|
+
this.controller = new MinimapController(viewport, canvas, { width: WIDTH, height: HEIGHT });
|
|
5092
|
+
}
|
|
5093
|
+
scheduleDraw() {
|
|
5094
|
+
this.controller.requestDraw();
|
|
5095
|
+
}
|
|
5096
|
+
destroy() {
|
|
5097
|
+
this.controller.dispose();
|
|
5098
|
+
this.canvas.remove();
|
|
5099
|
+
}
|
|
4901
5100
|
};
|
|
4902
5101
|
|
|
4903
5102
|
// src/canvas/viewport-dom.ts
|
|
@@ -8079,25 +8278,7 @@ var Viewport = class {
|
|
|
8079
8278
|
}
|
|
8080
8279
|
this.unsubToolChange = this.toolManager.onChange(() => this.contextMenu?.close());
|
|
8081
8280
|
if (options.minimap) {
|
|
8082
|
-
|
|
8083
|
-
this.minimap = new Minimap({
|
|
8084
|
-
container: this.wrapper,
|
|
8085
|
-
getElements: visibleEls,
|
|
8086
|
-
getContentBounds: () => getElementsBoundingBox(visibleEls()),
|
|
8087
|
-
getViewportRect: () => this.camera.getVisibleRect(this.canvasEl.clientWidth, this.canvasEl.clientHeight),
|
|
8088
|
-
navigateTo: (w) => {
|
|
8089
|
-
const z = this.camera.zoom;
|
|
8090
|
-
this.camera.moveTo(
|
|
8091
|
-
this.canvasEl.clientWidth / 2 - w.x * z,
|
|
8092
|
-
this.canvasEl.clientHeight / 2 - w.y * z
|
|
8093
|
-
);
|
|
8094
|
-
},
|
|
8095
|
-
requestFrame: (cb) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(cb) : 0,
|
|
8096
|
-
cancelFrame: (id) => {
|
|
8097
|
-
if (typeof cancelAnimationFrame !== "undefined") cancelAnimationFrame(id);
|
|
8098
|
-
}
|
|
8099
|
-
});
|
|
8100
|
-
this.minimap.scheduleDraw();
|
|
8281
|
+
this.minimap = new Minimap(this.wrapper, this);
|
|
8101
8282
|
}
|
|
8102
8283
|
this.domNodeManager = new DomNodeManager({
|
|
8103
8284
|
domLayer: this.paintStack,
|
|
@@ -8133,7 +8314,6 @@ var Viewport = class {
|
|
|
8133
8314
|
this.applyCameraTransform();
|
|
8134
8315
|
this.noteEditor.updateToolbarPosition();
|
|
8135
8316
|
this.contextMenu?.close();
|
|
8136
|
-
this.minimap?.scheduleDraw();
|
|
8137
8317
|
this.requestRender();
|
|
8138
8318
|
});
|
|
8139
8319
|
this.gridController = new GridController({
|
|
@@ -8148,7 +8328,6 @@ var Viewport = class {
|
|
|
8148
8328
|
this.store.on("add", (el) => {
|
|
8149
8329
|
if (el.type === "grid") this.gridController.syncContext();
|
|
8150
8330
|
this.renderLoop.markLayerDirty(el.layerId);
|
|
8151
|
-
this.minimap?.scheduleDraw();
|
|
8152
8331
|
this.requestRender();
|
|
8153
8332
|
}),
|
|
8154
8333
|
this.store.on("remove", (el) => {
|
|
@@ -8156,7 +8335,6 @@ var Viewport = class {
|
|
|
8156
8335
|
this.unbindArrowsFrom(el);
|
|
8157
8336
|
this.domNodeManager.removeDomNode(el.id);
|
|
8158
8337
|
this.renderLoop.markLayerDirty(el.layerId);
|
|
8159
|
-
this.minimap?.scheduleDraw();
|
|
8160
8338
|
this.requestRender();
|
|
8161
8339
|
}),
|
|
8162
8340
|
this.store.on("update", ({ previous, current }) => {
|
|
@@ -8165,21 +8343,18 @@ var Viewport = class {
|
|
|
8165
8343
|
if (previous.layerId !== current.layerId) {
|
|
8166
8344
|
this.renderLoop.markLayerDirty(previous.layerId);
|
|
8167
8345
|
}
|
|
8168
|
-
this.minimap?.scheduleDraw();
|
|
8169
8346
|
this.requestRender();
|
|
8170
8347
|
}),
|
|
8171
8348
|
this.store.on("clear", () => {
|
|
8172
8349
|
this.domNodeManager.clearDomNodes();
|
|
8173
8350
|
this.renderLoop.markAllLayersDirty();
|
|
8174
8351
|
this.gridController.syncContext();
|
|
8175
|
-
this.minimap?.scheduleDraw();
|
|
8176
8352
|
this.requestRender();
|
|
8177
8353
|
})
|
|
8178
8354
|
];
|
|
8179
8355
|
this.layerManager.on("change", () => {
|
|
8180
8356
|
this.toolContext.activeLayerId = this.layerManager.activeLayerId;
|
|
8181
8357
|
this.renderLoop.markAllLayersDirty();
|
|
8182
|
-
this.minimap?.scheduleDraw();
|
|
8183
8358
|
this.requestRender();
|
|
8184
8359
|
});
|
|
8185
8360
|
this.interactions = new ViewportInteractions({
|
|
@@ -8243,6 +8418,7 @@ var Viewport = class {
|
|
|
8243
8418
|
contextMenu = null;
|
|
8244
8419
|
minimap = null;
|
|
8245
8420
|
htmlRenderers = /* @__PURE__ */ new Map();
|
|
8421
|
+
resizeListeners = /* @__PURE__ */ new Set();
|
|
8246
8422
|
get ctx() {
|
|
8247
8423
|
return this.canvasEl.getContext("2d");
|
|
8248
8424
|
}
|
|
@@ -8267,6 +8443,27 @@ var Viewport = class {
|
|
|
8267
8443
|
if (!bbox) return;
|
|
8268
8444
|
this.camera.fitToContent(bbox, this.wrapper.clientWidth, this.wrapper.clientHeight, padding);
|
|
8269
8445
|
}
|
|
8446
|
+
/** World-space rectangle currently visible through the canvas. */
|
|
8447
|
+
getVisibleRect() {
|
|
8448
|
+
return this.camera.getVisibleRect(this.canvasEl.clientWidth, this.canvasEl.clientHeight);
|
|
8449
|
+
}
|
|
8450
|
+
/** Centers the camera on a world point without changing zoom. */
|
|
8451
|
+
centerCameraAt(world) {
|
|
8452
|
+
const z = this.camera.zoom;
|
|
8453
|
+
this.camera.moveTo(
|
|
8454
|
+
this.canvasEl.clientWidth / 2 - world.x * z,
|
|
8455
|
+
this.canvasEl.clientHeight / 2 - world.y * z
|
|
8456
|
+
);
|
|
8457
|
+
}
|
|
8458
|
+
/**
|
|
8459
|
+
* Notifies after the host container resizes (ResizeObserver-driven). A resize
|
|
8460
|
+
* changes the visible world rect without a camera event; overlays such as the
|
|
8461
|
+
* minimap subscribe to stay current. Returns an idempotent unsubscribe.
|
|
8462
|
+
*/
|
|
8463
|
+
onResize(listener) {
|
|
8464
|
+
this.resizeListeners.add(listener);
|
|
8465
|
+
return () => this.resizeListeners.delete(listener);
|
|
8466
|
+
}
|
|
8270
8467
|
requestRender() {
|
|
8271
8468
|
this.renderLoop.requestRender();
|
|
8272
8469
|
}
|
|
@@ -8571,6 +8768,7 @@ var Viewport = class {
|
|
|
8571
8768
|
this.unsubStore.forEach((fn) => fn());
|
|
8572
8769
|
this.resizeObserver?.disconnect();
|
|
8573
8770
|
this.resizeObserver = null;
|
|
8771
|
+
this.resizeListeners.clear();
|
|
8574
8772
|
this.wrapper.remove();
|
|
8575
8773
|
}
|
|
8576
8774
|
stopInteracting() {
|
|
@@ -8620,6 +8818,7 @@ var Viewport = class {
|
|
|
8620
8818
|
const dpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1;
|
|
8621
8819
|
this.renderLoop.setCanvasSize(rect.width * dpr, rect.height * dpr);
|
|
8622
8820
|
this.requestRender();
|
|
8821
|
+
this.resizeListeners.forEach((fn) => fn());
|
|
8623
8822
|
}
|
|
8624
8823
|
observeResize() {
|
|
8625
8824
|
if (typeof ResizeObserver === "undefined") return;
|
|
@@ -8659,7 +8858,7 @@ function toLaserTrailPresence(emission) {
|
|
|
8659
8858
|
};
|
|
8660
8859
|
}
|
|
8661
8860
|
var DEFAULT_COLOR = "#ff3b30";
|
|
8662
|
-
var
|
|
8861
|
+
var DEFAULT_WIDTH2 = 4;
|
|
8663
8862
|
var DEFAULT_FADE_MS = 1200;
|
|
8664
8863
|
var DEFAULT_MAX_POINTS = 512;
|
|
8665
8864
|
var RemoteLaserOverlay = class {
|
|
@@ -8675,7 +8874,7 @@ var RemoteLaserOverlay = class {
|
|
|
8675
8874
|
constructor(host, options = {}) {
|
|
8676
8875
|
this.host = host;
|
|
8677
8876
|
this.color = options.color ?? DEFAULT_COLOR;
|
|
8678
|
-
this.width = options.width ??
|
|
8877
|
+
this.width = options.width ?? DEFAULT_WIDTH2;
|
|
8679
8878
|
this.fadeMs = options.fadeMs ?? DEFAULT_FADE_MS;
|
|
8680
8879
|
this.maxPointsPerSender = options.maxPointsPerSender ?? DEFAULT_MAX_POINTS;
|
|
8681
8880
|
this.unregister = host.registerOverlay((ctx) => this.renderTrails(ctx));
|
|
@@ -11904,7 +12103,7 @@ var TemplateTool = class {
|
|
|
11904
12103
|
|
|
11905
12104
|
// src/tools/laser-tool.ts
|
|
11906
12105
|
var DEFAULT_COLOR5 = "#ff3b30";
|
|
11907
|
-
var
|
|
12106
|
+
var DEFAULT_WIDTH3 = 4;
|
|
11908
12107
|
var DEFAULT_FADE_MS3 = 1200;
|
|
11909
12108
|
var LaserTool = class {
|
|
11910
12109
|
name;
|
|
@@ -11920,7 +12119,7 @@ var LaserTool = class {
|
|
|
11920
12119
|
constructor(options = {}) {
|
|
11921
12120
|
this.name = options.name ?? "laser";
|
|
11922
12121
|
this.color = options.color ?? DEFAULT_COLOR5;
|
|
11923
|
-
this.width = options.width ??
|
|
12122
|
+
this.width = options.width ?? DEFAULT_WIDTH3;
|
|
11924
12123
|
this.fadeMs = options.fadeMs ?? DEFAULT_FADE_MS3;
|
|
11925
12124
|
}
|
|
11926
12125
|
now() {
|
|
@@ -12167,7 +12366,7 @@ var PingTool = class {
|
|
|
12167
12366
|
};
|
|
12168
12367
|
|
|
12169
12368
|
// src/index.ts
|
|
12170
|
-
var VERSION = "0.
|
|
12369
|
+
var VERSION = "0.58.0";
|
|
12171
12370
|
// Annotate the CommonJS export names for ESM import in node:
|
|
12172
12371
|
0 && (module.exports = {
|
|
12173
12372
|
ArrowTool,
|
|
@@ -12187,6 +12386,7 @@ var VERSION = "0.57.0";
|
|
|
12187
12386
|
MEASURE_PRESENCE_KIND,
|
|
12188
12387
|
MeasureTool,
|
|
12189
12388
|
MemoryAdapter,
|
|
12389
|
+
MinimapController,
|
|
12190
12390
|
NoteTool,
|
|
12191
12391
|
PING_PRESENCE_KIND,
|
|
12192
12392
|
PencilTool,
|