@fieldnotes/core 0.22.0 → 0.23.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 +496 -481
- package/dist/index.cjs +171 -100
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +171 -100
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2780,6 +2780,7 @@ var ElementRenderer = class {
|
|
|
2780
2780
|
canvasSize = null;
|
|
2781
2781
|
hexTileCache = null;
|
|
2782
2782
|
hexTileCacheKey = "";
|
|
2783
|
+
gridBoundsOverride = null;
|
|
2783
2784
|
setStore(store) {
|
|
2784
2785
|
this.store = store;
|
|
2785
2786
|
}
|
|
@@ -2795,6 +2796,9 @@ var ElementRenderer = class {
|
|
|
2795
2796
|
setCanvasSize(w, h) {
|
|
2796
2797
|
this.canvasSize = { w, h };
|
|
2797
2798
|
}
|
|
2799
|
+
setGridBoundsOverride(bounds) {
|
|
2800
|
+
this.gridBoundsOverride = bounds;
|
|
2801
|
+
}
|
|
2798
2802
|
isDomElement(element) {
|
|
2799
2803
|
return DOM_ELEMENT_TYPES.has(element.type);
|
|
2800
2804
|
}
|
|
@@ -2965,20 +2969,20 @@ var ElementRenderer = class {
|
|
|
2965
2969
|
}
|
|
2966
2970
|
}
|
|
2967
2971
|
renderGrid(ctx, grid) {
|
|
2968
|
-
|
|
2972
|
+
const canvasSize = this.canvasSize;
|
|
2973
|
+
if (!canvasSize) return;
|
|
2969
2974
|
const cam = this.camera;
|
|
2970
2975
|
if (!cam) return;
|
|
2971
|
-
const
|
|
2972
|
-
|
|
2973
|
-
x:
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
};
|
|
2976
|
+
const bounds = this.gridBoundsOverride ?? (() => {
|
|
2977
|
+
const topLeft = cam.screenToWorld({ x: 0, y: 0 });
|
|
2978
|
+
const bottomRight = cam.screenToWorld({ x: canvasSize.w, y: canvasSize.h });
|
|
2979
|
+
return {
|
|
2980
|
+
minX: topLeft.x,
|
|
2981
|
+
minY: topLeft.y,
|
|
2982
|
+
maxX: bottomRight.x,
|
|
2983
|
+
maxY: bottomRight.y
|
|
2984
|
+
};
|
|
2985
|
+
})();
|
|
2982
2986
|
if (grid.gridType === "hex") {
|
|
2983
2987
|
const dpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1;
|
|
2984
2988
|
const scale = cam.zoom * dpr;
|
|
@@ -4837,19 +4841,14 @@ var RenderLoop = class {
|
|
|
4837
4841
|
layerManager;
|
|
4838
4842
|
domNodeManager;
|
|
4839
4843
|
layerCache;
|
|
4844
|
+
marginViewport;
|
|
4840
4845
|
activeDrawingLayerId = null;
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
lastCamY;
|
|
4846
|
+
gridCacheDirty = true;
|
|
4847
|
+
// set on recenter/viewport-change; consumed by the grid block
|
|
4844
4848
|
stats = new RenderStats();
|
|
4845
4849
|
layerGroups = /* @__PURE__ */ new Map();
|
|
4846
4850
|
gridCacheCanvas = null;
|
|
4847
4851
|
gridCacheCtx = null;
|
|
4848
|
-
gridCacheZoom = -1;
|
|
4849
|
-
gridCacheCamX = -Infinity;
|
|
4850
|
-
gridCacheCamY = -Infinity;
|
|
4851
|
-
gridCacheWidth = 0;
|
|
4852
|
-
gridCacheHeight = 0;
|
|
4853
4852
|
lastGridRef = null;
|
|
4854
4853
|
constructor(deps) {
|
|
4855
4854
|
this.canvasEl = deps.canvasEl;
|
|
@@ -4861,9 +4860,7 @@ var RenderLoop = class {
|
|
|
4861
4860
|
this.layerManager = deps.layerManager;
|
|
4862
4861
|
this.domNodeManager = deps.domNodeManager;
|
|
4863
4862
|
this.layerCache = deps.layerCache;
|
|
4864
|
-
this.
|
|
4865
|
-
this.lastCamX = deps.camera.position.x;
|
|
4866
|
-
this.lastCamY = deps.camera.position.y;
|
|
4863
|
+
this.marginViewport = deps.marginViewport;
|
|
4867
4864
|
}
|
|
4868
4865
|
requestRender() {
|
|
4869
4866
|
this.needsRender = true;
|
|
@@ -4890,7 +4887,9 @@ var RenderLoop = class {
|
|
|
4890
4887
|
setCanvasSize(width, height) {
|
|
4891
4888
|
this.canvasEl.width = width;
|
|
4892
4889
|
this.canvasEl.height = height;
|
|
4893
|
-
|
|
4890
|
+
const dpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1;
|
|
4891
|
+
this.marginViewport.setViewport(width / dpr, height / dpr, dpr);
|
|
4892
|
+
this.layerCache.resize();
|
|
4894
4893
|
}
|
|
4895
4894
|
setActiveDrawingLayer(layerId) {
|
|
4896
4895
|
this.activeDrawingLayerId = layerId;
|
|
@@ -4904,30 +4903,29 @@ var RenderLoop = class {
|
|
|
4904
4903
|
getStats() {
|
|
4905
4904
|
return this.stats.getSnapshot();
|
|
4906
4905
|
}
|
|
4907
|
-
compositeLayerCache(ctx, layerId
|
|
4906
|
+
compositeLayerCache(ctx, layerId) {
|
|
4908
4907
|
const cached = this.layerCache.getCanvas(layerId);
|
|
4908
|
+
const offset = this.marginViewport.compositeOffset(
|
|
4909
|
+
this.camera.position.x,
|
|
4910
|
+
this.camera.position.y
|
|
4911
|
+
);
|
|
4909
4912
|
ctx.save();
|
|
4910
|
-
ctx.
|
|
4911
|
-
ctx.
|
|
4912
|
-
ctx.scale(1 / dpr, 1 / dpr);
|
|
4913
|
-
ctx.drawImage(cached, 0, 0);
|
|
4913
|
+
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
4914
|
+
ctx.drawImage(cached, offset.x, offset.y);
|
|
4914
4915
|
ctx.restore();
|
|
4915
4916
|
}
|
|
4916
|
-
ensureGridCache(
|
|
4917
|
-
|
|
4917
|
+
ensureGridCache() {
|
|
4918
|
+
const w = this.marginViewport.physicalWidth();
|
|
4919
|
+
const h = this.marginViewport.physicalHeight();
|
|
4920
|
+
if (this.gridCacheCanvas !== null && this.gridCacheCanvas.width === w && this.gridCacheCanvas.height === h) {
|
|
4918
4921
|
return;
|
|
4919
4922
|
}
|
|
4920
|
-
const physWidth = Math.round(cssWidth * dpr);
|
|
4921
|
-
const physHeight = Math.round(cssHeight * dpr);
|
|
4922
4923
|
if (typeof OffscreenCanvas !== "undefined") {
|
|
4923
|
-
this.gridCacheCanvas = new OffscreenCanvas(
|
|
4924
|
-
physWidth,
|
|
4925
|
-
physHeight
|
|
4926
|
-
);
|
|
4924
|
+
this.gridCacheCanvas = new OffscreenCanvas(w, h);
|
|
4927
4925
|
} else if (typeof document !== "undefined") {
|
|
4928
4926
|
const el = document.createElement("canvas");
|
|
4929
|
-
el.width =
|
|
4930
|
-
el.height =
|
|
4927
|
+
el.width = w;
|
|
4928
|
+
el.height = h;
|
|
4931
4929
|
this.gridCacheCanvas = el;
|
|
4932
4930
|
} else {
|
|
4933
4931
|
this.gridCacheCanvas = null;
|
|
@@ -4946,14 +4944,14 @@ var RenderLoop = class {
|
|
|
4946
4944
|
const dpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1;
|
|
4947
4945
|
const cssWidth = this.canvasEl.clientWidth;
|
|
4948
4946
|
const cssHeight = this.canvasEl.clientHeight;
|
|
4947
|
+
this.marginViewport.setViewport(cssWidth, cssHeight, dpr);
|
|
4949
4948
|
const currentZoom = this.camera.zoom;
|
|
4950
4949
|
const currentCamX = this.camera.position.x;
|
|
4951
4950
|
const currentCamY = this.camera.position.y;
|
|
4952
|
-
if (
|
|
4951
|
+
if (this.marginViewport.needsRecenter(currentCamX, currentCamY, currentZoom)) {
|
|
4952
|
+
this.marginViewport.recenter(currentCamX, currentCamY, currentZoom);
|
|
4953
4953
|
this.layerCache.markAllDirty();
|
|
4954
|
-
this.
|
|
4955
|
-
this.lastCamX = currentCamX;
|
|
4956
|
-
this.lastCamY = currentCamY;
|
|
4954
|
+
this.gridCacheDirty = true;
|
|
4957
4955
|
}
|
|
4958
4956
|
ctx.save();
|
|
4959
4957
|
ctx.scale(dpr, dpr);
|
|
@@ -4972,13 +4970,13 @@ var RenderLoop = class {
|
|
|
4972
4970
|
ctx.save();
|
|
4973
4971
|
ctx.translate(this.camera.position.x, this.camera.position.y);
|
|
4974
4972
|
ctx.scale(this.camera.zoom, this.camera.zoom);
|
|
4975
|
-
const
|
|
4976
|
-
const
|
|
4973
|
+
const cullBounds = this.marginViewport.cachedWorldBounds();
|
|
4974
|
+
const cullPad = Math.max(cullBounds.w, cullBounds.h) * 0.05;
|
|
4977
4975
|
const cullingRect = {
|
|
4978
|
-
x:
|
|
4979
|
-
y:
|
|
4980
|
-
w:
|
|
4981
|
-
h:
|
|
4976
|
+
x: cullBounds.x - cullPad,
|
|
4977
|
+
y: cullBounds.y - cullPad,
|
|
4978
|
+
w: cullBounds.w + cullPad * 2,
|
|
4979
|
+
h: cullBounds.h + cullPad * 2
|
|
4982
4980
|
};
|
|
4983
4981
|
const allElements = this.store.getAll();
|
|
4984
4982
|
this.layerGroups.clear();
|
|
@@ -5015,13 +5013,13 @@ var RenderLoop = class {
|
|
|
5015
5013
|
const isActiveDrawingLayer = layerId === this.activeDrawingLayerId;
|
|
5016
5014
|
if (!this.layerCache.isDirty(layerId)) {
|
|
5017
5015
|
const compT0 = performance.now();
|
|
5018
|
-
this.compositeLayerCache(ctx, layerId
|
|
5016
|
+
this.compositeLayerCache(ctx, layerId);
|
|
5019
5017
|
compositeMs += performance.now() - compT0;
|
|
5020
5018
|
continue;
|
|
5021
5019
|
}
|
|
5022
5020
|
if (isActiveDrawingLayer) {
|
|
5023
5021
|
const compT0 = performance.now();
|
|
5024
|
-
this.compositeLayerCache(ctx, layerId
|
|
5022
|
+
this.compositeLayerCache(ctx, layerId);
|
|
5025
5023
|
compositeMs += performance.now() - compT0;
|
|
5026
5024
|
continue;
|
|
5027
5025
|
}
|
|
@@ -5031,9 +5029,7 @@ var RenderLoop = class {
|
|
|
5031
5029
|
const offCanvas = this.layerCache.getCanvas(layerId);
|
|
5032
5030
|
offCtx.clearRect(0, 0, offCanvas.width, offCanvas.height);
|
|
5033
5031
|
offCtx.save();
|
|
5034
|
-
|
|
5035
|
-
offCtx.translate(this.camera.position.x, this.camera.position.y);
|
|
5036
|
-
offCtx.scale(this.camera.zoom, this.camera.zoom);
|
|
5032
|
+
this.marginViewport.applyRenderTransform(offCtx);
|
|
5037
5033
|
for (const element of elements) {
|
|
5038
5034
|
const elBounds = getElementBounds(element);
|
|
5039
5035
|
if (elBounds && !boundsIntersect(elBounds, cullingRect)) continue;
|
|
@@ -5043,48 +5039,54 @@ var RenderLoop = class {
|
|
|
5043
5039
|
this.layerCache.markClean(layerId);
|
|
5044
5040
|
layersMs += performance.now() - layerT0;
|
|
5045
5041
|
const compT0 = performance.now();
|
|
5046
|
-
this.compositeLayerCache(ctx, layerId
|
|
5042
|
+
this.compositeLayerCache(ctx, layerId);
|
|
5047
5043
|
compositeMs += performance.now() - compT0;
|
|
5048
5044
|
}
|
|
5049
5045
|
}
|
|
5050
5046
|
if (gridElements.length > 0) {
|
|
5051
5047
|
const gridT0 = performance.now();
|
|
5052
5048
|
const gridRef = gridElements[0];
|
|
5053
|
-
const
|
|
5054
|
-
if (
|
|
5055
|
-
|
|
5056
|
-
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
5057
|
-
ctx.drawImage(this.gridCacheCanvas, 0, 0);
|
|
5058
|
-
ctx.restore();
|
|
5059
|
-
} else {
|
|
5060
|
-
this.ensureGridCache(cssWidth, cssHeight, dpr);
|
|
5049
|
+
const gridDirty = this.gridCacheDirty || gridRef !== this.lastGridRef;
|
|
5050
|
+
if (gridDirty) {
|
|
5051
|
+
this.ensureGridCache();
|
|
5061
5052
|
if (this.gridCacheCtx && this.gridCacheCanvas) {
|
|
5053
|
+
const cb = this.marginViewport.cachedWorldBounds();
|
|
5054
|
+
this.renderer.setGridBoundsOverride({
|
|
5055
|
+
minX: cb.x,
|
|
5056
|
+
minY: cb.y,
|
|
5057
|
+
maxX: cb.x + cb.w,
|
|
5058
|
+
maxY: cb.y + cb.h
|
|
5059
|
+
});
|
|
5062
5060
|
const gc = this.gridCacheCtx;
|
|
5063
5061
|
gc.clearRect(0, 0, this.gridCacheCanvas.width, this.gridCacheCanvas.height);
|
|
5064
5062
|
gc.save();
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
}
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
5074
|
-
ctx.drawImage(this.gridCacheCanvas, 0, 0);
|
|
5075
|
-
ctx.restore();
|
|
5076
|
-
} else {
|
|
5077
|
-
for (const grid of gridElements) {
|
|
5078
|
-
this.renderer.renderCanvasElement(ctx, grid);
|
|
5063
|
+
this.marginViewport.applyRenderTransform(gc);
|
|
5064
|
+
try {
|
|
5065
|
+
for (const grid of gridElements) {
|
|
5066
|
+
this.renderer.renderCanvasElement(gc, grid);
|
|
5067
|
+
}
|
|
5068
|
+
} finally {
|
|
5069
|
+
gc.restore();
|
|
5070
|
+
this.renderer.setGridBoundsOverride(null);
|
|
5079
5071
|
}
|
|
5080
5072
|
}
|
|
5081
|
-
this.
|
|
5082
|
-
this.gridCacheCamX = currentCamX;
|
|
5083
|
-
this.gridCacheCamY = currentCamY;
|
|
5084
|
-
this.gridCacheWidth = cssWidth;
|
|
5085
|
-
this.gridCacheHeight = cssHeight;
|
|
5073
|
+
this.gridCacheDirty = false;
|
|
5086
5074
|
this.lastGridRef = gridRef;
|
|
5087
5075
|
}
|
|
5076
|
+
if (this.gridCacheCanvas) {
|
|
5077
|
+
const offset = this.marginViewport.compositeOffset(
|
|
5078
|
+
this.camera.position.x,
|
|
5079
|
+
this.camera.position.y
|
|
5080
|
+
);
|
|
5081
|
+
ctx.save();
|
|
5082
|
+
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
5083
|
+
ctx.drawImage(this.gridCacheCanvas, offset.x, offset.y);
|
|
5084
|
+
ctx.restore();
|
|
5085
|
+
} else {
|
|
5086
|
+
for (const grid of gridElements) {
|
|
5087
|
+
this.renderer.renderCanvasElement(ctx, grid);
|
|
5088
|
+
}
|
|
5089
|
+
}
|
|
5088
5090
|
gridMs = performance.now() - gridT0;
|
|
5089
5091
|
}
|
|
5090
5092
|
const overlayT0 = performance.now();
|
|
@@ -5116,15 +5118,11 @@ function createOffscreenCanvas(width, height) {
|
|
|
5116
5118
|
return canvas;
|
|
5117
5119
|
}
|
|
5118
5120
|
var LayerCache = class {
|
|
5121
|
+
constructor(viewport) {
|
|
5122
|
+
this.viewport = viewport;
|
|
5123
|
+
}
|
|
5119
5124
|
canvases = /* @__PURE__ */ new Map();
|
|
5120
5125
|
dirtyFlags = /* @__PURE__ */ new Map();
|
|
5121
|
-
width;
|
|
5122
|
-
height;
|
|
5123
|
-
constructor(width, height) {
|
|
5124
|
-
const dpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1;
|
|
5125
|
-
this.width = Math.round(width * dpr);
|
|
5126
|
-
this.height = Math.round(height * dpr);
|
|
5127
|
-
}
|
|
5128
5126
|
isDirty(layerId) {
|
|
5129
5127
|
return this.dirtyFlags.get(layerId) !== false;
|
|
5130
5128
|
}
|
|
@@ -5142,7 +5140,7 @@ var LayerCache = class {
|
|
|
5142
5140
|
getCanvas(layerId) {
|
|
5143
5141
|
let canvas = this.canvases.get(layerId);
|
|
5144
5142
|
if (!canvas) {
|
|
5145
|
-
canvas = createOffscreenCanvas(this.
|
|
5143
|
+
canvas = createOffscreenCanvas(this.viewport.physicalWidth(), this.viewport.physicalHeight());
|
|
5146
5144
|
this.canvases.set(layerId, canvas);
|
|
5147
5145
|
this.dirtyFlags.set(layerId, true);
|
|
5148
5146
|
}
|
|
@@ -5152,13 +5150,12 @@ var LayerCache = class {
|
|
|
5152
5150
|
const canvas = this.getCanvas(layerId);
|
|
5153
5151
|
return canvas.getContext("2d");
|
|
5154
5152
|
}
|
|
5155
|
-
resize(
|
|
5156
|
-
const
|
|
5157
|
-
|
|
5158
|
-
this.height = Math.round(height * dpr);
|
|
5153
|
+
resize() {
|
|
5154
|
+
const w = this.viewport.physicalWidth();
|
|
5155
|
+
const h = this.viewport.physicalHeight();
|
|
5159
5156
|
for (const [id, canvas] of this.canvases) {
|
|
5160
|
-
canvas.width =
|
|
5161
|
-
canvas.height =
|
|
5157
|
+
canvas.width = w;
|
|
5158
|
+
canvas.height = h;
|
|
5162
5159
|
this.dirtyFlags.set(id, true);
|
|
5163
5160
|
}
|
|
5164
5161
|
}
|
|
@@ -5168,6 +5165,75 @@ var LayerCache = class {
|
|
|
5168
5165
|
}
|
|
5169
5166
|
};
|
|
5170
5167
|
|
|
5168
|
+
// src/canvas/margin-viewport.ts
|
|
5169
|
+
var MarginViewport = class {
|
|
5170
|
+
constructor(marginPx) {
|
|
5171
|
+
this.marginPx = marginPx;
|
|
5172
|
+
}
|
|
5173
|
+
cssW = 0;
|
|
5174
|
+
cssH = 0;
|
|
5175
|
+
dpr = 1;
|
|
5176
|
+
anchorCamX = 0;
|
|
5177
|
+
anchorCamY = 0;
|
|
5178
|
+
anchorZoom = Number.NaN;
|
|
5179
|
+
// sentinel → first needsRecenter is true
|
|
5180
|
+
viewportDirty = true;
|
|
5181
|
+
setMargin(marginPx) {
|
|
5182
|
+
if (marginPx !== this.marginPx) {
|
|
5183
|
+
this.marginPx = marginPx;
|
|
5184
|
+
this.viewportDirty = true;
|
|
5185
|
+
}
|
|
5186
|
+
}
|
|
5187
|
+
setViewport(cssW, cssH, dpr) {
|
|
5188
|
+
if (cssW !== this.cssW || cssH !== this.cssH || dpr !== this.dpr) {
|
|
5189
|
+
this.cssW = cssW;
|
|
5190
|
+
this.cssH = cssH;
|
|
5191
|
+
this.dpr = dpr;
|
|
5192
|
+
this.viewportDirty = true;
|
|
5193
|
+
}
|
|
5194
|
+
}
|
|
5195
|
+
physicalWidth() {
|
|
5196
|
+
return Math.round((this.cssW + 2 * this.marginPx) * this.dpr);
|
|
5197
|
+
}
|
|
5198
|
+
physicalHeight() {
|
|
5199
|
+
return Math.round((this.cssH + 2 * this.marginPx) * this.dpr);
|
|
5200
|
+
}
|
|
5201
|
+
needsRecenter(camX, camY, zoom) {
|
|
5202
|
+
return this.viewportDirty || zoom !== this.anchorZoom || Math.abs(camX - this.anchorCamX) > this.marginPx || Math.abs(camY - this.anchorCamY) > this.marginPx;
|
|
5203
|
+
}
|
|
5204
|
+
recenter(camX, camY, zoom) {
|
|
5205
|
+
this.anchorCamX = camX;
|
|
5206
|
+
this.anchorCamY = camY;
|
|
5207
|
+
this.anchorZoom = zoom;
|
|
5208
|
+
this.viewportDirty = false;
|
|
5209
|
+
}
|
|
5210
|
+
/** Applies dpr scale + anchor-relative world transform. setViewport must have been called first. */
|
|
5211
|
+
applyRenderTransform(ctx) {
|
|
5212
|
+
ctx.scale(this.dpr, this.dpr);
|
|
5213
|
+
ctx.translate(this.marginPx + this.anchorCamX, this.marginPx + this.anchorCamY);
|
|
5214
|
+
ctx.scale(this.anchorZoom, this.anchorZoom);
|
|
5215
|
+
}
|
|
5216
|
+
// Device-px destination for drawImage(cache, x, y).
|
|
5217
|
+
// A world point P sits in the cache at CSS x `margin + anchorCamX + P*zoom`; it must land on
|
|
5218
|
+
// screen at `camX + P*zoom`; so the blit offset is `camX - anchorCamX - margin` (CSS) * dpr.
|
|
5219
|
+
compositeOffset(camX, camY) {
|
|
5220
|
+
return {
|
|
5221
|
+
x: (camX - this.anchorCamX - this.marginPx) * this.dpr,
|
|
5222
|
+
y: (camY - this.anchorCamY - this.marginPx) * this.dpr
|
|
5223
|
+
};
|
|
5224
|
+
}
|
|
5225
|
+
// World-space bounds of the whole cached region at the anchor (cull rect for re-renders).
|
|
5226
|
+
cachedWorldBounds() {
|
|
5227
|
+
const z = this.anchorZoom;
|
|
5228
|
+
return {
|
|
5229
|
+
x: (-this.marginPx - this.anchorCamX) / z,
|
|
5230
|
+
y: (-this.marginPx - this.anchorCamY) / z,
|
|
5231
|
+
w: (this.cssW + 2 * this.marginPx) / z,
|
|
5232
|
+
h: (this.cssH + 2 * this.marginPx) / z
|
|
5233
|
+
};
|
|
5234
|
+
}
|
|
5235
|
+
};
|
|
5236
|
+
|
|
5171
5237
|
// src/canvas/viewport.ts
|
|
5172
5238
|
var Viewport = class {
|
|
5173
5239
|
constructor(container, options = {}) {
|
|
@@ -5244,10 +5310,13 @@ var Viewport = class {
|
|
|
5244
5310
|
this.interactMode = new InteractMode({
|
|
5245
5311
|
getNode: (id) => this.domNodeManager.getNode(id)
|
|
5246
5312
|
});
|
|
5247
|
-
|
|
5313
|
+
this.marginViewport = new MarginViewport(options.panBufferMargin ?? 256);
|
|
5314
|
+
this.marginViewport.setViewport(
|
|
5248
5315
|
this.canvasEl.clientWidth || 800,
|
|
5249
|
-
this.canvasEl.clientHeight || 600
|
|
5316
|
+
this.canvasEl.clientHeight || 600,
|
|
5317
|
+
typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1
|
|
5250
5318
|
);
|
|
5319
|
+
const layerCache = new LayerCache(this.marginViewport);
|
|
5251
5320
|
this.renderLoop = new RenderLoop({
|
|
5252
5321
|
canvasEl: this.canvasEl,
|
|
5253
5322
|
camera: this.camera,
|
|
@@ -5257,7 +5326,8 @@ var Viewport = class {
|
|
|
5257
5326
|
toolManager: this.toolManager,
|
|
5258
5327
|
layerManager: this.layerManager,
|
|
5259
5328
|
domNodeManager: this.domNodeManager,
|
|
5260
|
-
layerCache
|
|
5329
|
+
layerCache,
|
|
5330
|
+
marginViewport: this.marginViewport
|
|
5261
5331
|
});
|
|
5262
5332
|
this.unsubCamera = this.camera.onChange(() => {
|
|
5263
5333
|
this.applyCameraTransform();
|
|
@@ -5321,6 +5391,7 @@ var Viewport = class {
|
|
|
5321
5391
|
noteEditor;
|
|
5322
5392
|
historyRecorder;
|
|
5323
5393
|
toolContext;
|
|
5394
|
+
marginViewport;
|
|
5324
5395
|
resizeObserver = null;
|
|
5325
5396
|
_snapToGrid = false;
|
|
5326
5397
|
_gridSize;
|
|
@@ -7511,7 +7582,7 @@ var TemplateTool = class {
|
|
|
7511
7582
|
};
|
|
7512
7583
|
|
|
7513
7584
|
// src/index.ts
|
|
7514
|
-
var VERSION = "0.
|
|
7585
|
+
var VERSION = "0.23.0";
|
|
7515
7586
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7516
7587
|
0 && (module.exports = {
|
|
7517
7588
|
AddElementCommand,
|