@canvas-harness/core 0.1.19 → 0.1.21
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 +149 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +149 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4754,6 +4754,59 @@ var buildPath = (type, x, y, w, h, radius) => {
|
|
|
4754
4754
|
}
|
|
4755
4755
|
};
|
|
4756
4756
|
|
|
4757
|
+
// src/render/scene-cache-math.ts
|
|
4758
|
+
var computeCacheSourceRect = (cache5, view) => {
|
|
4759
|
+
const ratio = cache5.camZ / view.camZ;
|
|
4760
|
+
const srcX = Math.round(((view.camX - cache5.camX) * cache5.camZ + cache5.marginCssPx) * cache5.dpr);
|
|
4761
|
+
const srcY = Math.round(((view.camY - cache5.camY) * cache5.camZ + cache5.marginCssPx) * cache5.dpr);
|
|
4762
|
+
const srcW = view.widthCssPx * ratio * cache5.dpr;
|
|
4763
|
+
const srcH = view.heightCssPx * ratio * cache5.dpr;
|
|
4764
|
+
return { srcX, srcY, srcW, srcH };
|
|
4765
|
+
};
|
|
4766
|
+
var cacheCoversViewport = (cache5, view) => {
|
|
4767
|
+
const { srcX, srcY, srcW, srcH } = computeCacheSourceRect(cache5, view);
|
|
4768
|
+
return srcX >= 0 && srcY >= 0 && srcX + srcW <= cache5.widthDevicePx && srcY + srcH <= cache5.heightDevicePx;
|
|
4769
|
+
};
|
|
4770
|
+
var scaleRatioInBounds = (cacheCamZ, viewCamZ, maxRatio) => {
|
|
4771
|
+
if (viewCamZ <= 0 || cacheCamZ <= 0 || maxRatio <= 0) return false;
|
|
4772
|
+
const ratio = viewCamZ >= cacheCamZ ? viewCamZ / cacheCamZ : cacheCamZ / viewCamZ;
|
|
4773
|
+
return ratio <= maxRatio;
|
|
4774
|
+
};
|
|
4775
|
+
var cacheReuseLayout = (cache5, view) => {
|
|
4776
|
+
const ratio = view.camZ / cache5.camZ;
|
|
4777
|
+
const cacheW = cache5.widthDevicePx;
|
|
4778
|
+
const cacheH = cache5.heightDevicePx;
|
|
4779
|
+
const marginDev = cache5.marginCssPx * cache5.dpr;
|
|
4780
|
+
const destW = cacheW * ratio;
|
|
4781
|
+
const destH = cacheH * ratio;
|
|
4782
|
+
const destX = (cache5.camX - view.camX) * view.camZ * cache5.dpr + marginDev * (1 - ratio);
|
|
4783
|
+
const destY = (cache5.camY - view.camY) * view.camZ * cache5.dpr + marginDev * (1 - ratio);
|
|
4784
|
+
const dest = { x: destX, y: destY, w: destW, h: destH };
|
|
4785
|
+
const strips = {
|
|
4786
|
+
top: { x: 0, y: 0, w: cacheW, h: Math.max(0, destY) },
|
|
4787
|
+
bottom: {
|
|
4788
|
+
x: 0,
|
|
4789
|
+
y: destY + destH,
|
|
4790
|
+
w: cacheW,
|
|
4791
|
+
h: Math.max(0, cacheH - destY - destH)
|
|
4792
|
+
},
|
|
4793
|
+
left: { x: 0, y: destY, w: Math.max(0, destX), h: destH },
|
|
4794
|
+
right: {
|
|
4795
|
+
x: destX + destW,
|
|
4796
|
+
y: destY,
|
|
4797
|
+
w: Math.max(0, cacheW - destX - destW),
|
|
4798
|
+
h: destH
|
|
4799
|
+
}
|
|
4800
|
+
};
|
|
4801
|
+
const valid = destX >= 0 && destY >= 0 && destX + destW <= cacheW && destY + destH <= cacheH;
|
|
4802
|
+
return { dest, strips, valid };
|
|
4803
|
+
};
|
|
4804
|
+
var zoomExtendRatioInBounds = (cacheCamZ, viewCamZ, minRatio) => {
|
|
4805
|
+
if (viewCamZ <= 0 || cacheCamZ <= 0 || minRatio <= 0 || minRatio >= 1) return false;
|
|
4806
|
+
const ratio = viewCamZ / cacheCamZ;
|
|
4807
|
+
return ratio >= minRatio && ratio < 1;
|
|
4808
|
+
};
|
|
4809
|
+
|
|
4757
4810
|
// src/render/shapes/content-bounds.ts
|
|
4758
4811
|
var SQRT2_INV = 1 / Math.SQRT2;
|
|
4759
4812
|
var contentBounds = (node) => {
|
|
@@ -4838,6 +4891,7 @@ var createRenderer = (opts) => {
|
|
|
4838
4891
|
let interactiveDirty = false;
|
|
4839
4892
|
let overlaySet = /* @__PURE__ */ new Set();
|
|
4840
4893
|
let lastDrawn = 0;
|
|
4894
|
+
let lastDrawPath = "idle";
|
|
4841
4895
|
let cacheSurface = null;
|
|
4842
4896
|
let cacheCamX = 0;
|
|
4843
4897
|
let cacheCamY = 0;
|
|
@@ -4907,9 +4961,8 @@ var createRenderer = (opts) => {
|
|
|
4907
4961
|
theme: (token) => theme ? theme(token) : void 0
|
|
4908
4962
|
};
|
|
4909
4963
|
const editingNodeId = interaction.editingTarget?.kind === "node" ? interaction.editingTarget.id : null;
|
|
4910
|
-
const cameraIsMoving = interaction.mode === "panning" || interaction.mode === "zooming";
|
|
4911
4964
|
const movingNodeCount = excludedNodes?.size ?? 0;
|
|
4912
|
-
const roughEnabled =
|
|
4965
|
+
const roughEnabled = movingNodeCount <= ROUGH_MAX_MOVING_NODES && camera.z >= ROUGH_MIN_ZOOM && visible.length <= ROUGH_MAX_NODES;
|
|
4913
4966
|
if (!hideFrames) {
|
|
4914
4967
|
for (const node of visible) {
|
|
4915
4968
|
if (node.type !== "frame") continue;
|
|
@@ -5005,7 +5058,7 @@ var createRenderer = (opts) => {
|
|
|
5005
5058
|
}
|
|
5006
5059
|
}
|
|
5007
5060
|
const visEdges = visibleEdges(viewport);
|
|
5008
|
-
const edgeRoughEnabled =
|
|
5061
|
+
const edgeRoughEnabled = movingNodeCount <= ROUGH_MAX_MOVING_NODES && camera.z >= ROUGH_MIN_ZOOM && visEdges.length <= ROUGH_MAX_NODES;
|
|
5009
5062
|
for (const edge of visEdges) {
|
|
5010
5063
|
if (excludedEdges?.has(edge.id)) continue;
|
|
5011
5064
|
paintOneEdge(surface.ctx, edge, scale, edgeRoughEnabled, camera.z, isMoving2);
|
|
@@ -5085,6 +5138,44 @@ var createRenderer = (opts) => {
|
|
|
5085
5138
|
if (hw > 0) renderCacheStrip(cache5, newCamX, newCamY, camera.z, hx, 0, hw, cacheH);
|
|
5086
5139
|
if (vh > 0 && vw > 0) renderCacheStrip(cache5, newCamX, newCamY, camera.z, vx, vy, vw, vh);
|
|
5087
5140
|
};
|
|
5141
|
+
let scaledExtendScratch = null;
|
|
5142
|
+
const extendCacheScaled = (camera, layout) => {
|
|
5143
|
+
const cache5 = ensureCacheSurface();
|
|
5144
|
+
const cacheW = cache5.canvas.width;
|
|
5145
|
+
const cacheH = cache5.canvas.height;
|
|
5146
|
+
if (!scaledExtendScratch || scaledExtendScratch.width !== cacheW || scaledExtendScratch.height !== cacheH) {
|
|
5147
|
+
scaledExtendScratch = document.createElement("canvas");
|
|
5148
|
+
scaledExtendScratch.width = cacheW;
|
|
5149
|
+
scaledExtendScratch.height = cacheH;
|
|
5150
|
+
}
|
|
5151
|
+
const sctx = scaledExtendScratch.getContext("2d");
|
|
5152
|
+
sctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
5153
|
+
sctx.clearRect(0, 0, cacheW, cacheH);
|
|
5154
|
+
sctx.drawImage(cache5.canvas, 0, 0);
|
|
5155
|
+
cache5.ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
5156
|
+
cache5.ctx.clearRect(0, 0, cacheW, cacheH);
|
|
5157
|
+
cache5.ctx.drawImage(
|
|
5158
|
+
scaledExtendScratch,
|
|
5159
|
+
layout.dest.x,
|
|
5160
|
+
layout.dest.y,
|
|
5161
|
+
layout.dest.w,
|
|
5162
|
+
layout.dest.h
|
|
5163
|
+
);
|
|
5164
|
+
cacheCamX = camera.x;
|
|
5165
|
+
cacheCamY = camera.y;
|
|
5166
|
+
cacheCamZ = camera.z;
|
|
5167
|
+
const strips = [
|
|
5168
|
+
layout.strips.top,
|
|
5169
|
+
layout.strips.bottom,
|
|
5170
|
+
layout.strips.left,
|
|
5171
|
+
layout.strips.right
|
|
5172
|
+
];
|
|
5173
|
+
for (const s of strips) {
|
|
5174
|
+
if (s.w > 0 && s.h > 0) {
|
|
5175
|
+
renderCacheStrip(cache5, camera.x, camera.y, camera.z, s.x, s.y, s.w, s.h);
|
|
5176
|
+
}
|
|
5177
|
+
}
|
|
5178
|
+
};
|
|
5088
5179
|
const cacheSourceOffset = (camera) => {
|
|
5089
5180
|
const dpr = staticSurface.dpr;
|
|
5090
5181
|
return {
|
|
@@ -5106,21 +5197,72 @@ var createRenderer = (opts) => {
|
|
|
5106
5197
|
staticSurface.ctx.clearRect(0, 0, w, h);
|
|
5107
5198
|
staticSurface.ctx.drawImage(cache5.canvas, srcX, srcY, w, h, 0, 0, w, h);
|
|
5108
5199
|
};
|
|
5200
|
+
const snapshotCacheCamera = (cache5) => ({
|
|
5201
|
+
camX: cacheCamX,
|
|
5202
|
+
camY: cacheCamY,
|
|
5203
|
+
camZ: cacheCamZ,
|
|
5204
|
+
widthDevicePx: cache5.canvas.width,
|
|
5205
|
+
heightDevicePx: cache5.canvas.height,
|
|
5206
|
+
dpr: cache5.dpr,
|
|
5207
|
+
marginCssPx: SCENE_CACHE_MARGIN_PX
|
|
5208
|
+
});
|
|
5209
|
+
const snapshotView = (camera) => ({
|
|
5210
|
+
camX: camera.x,
|
|
5211
|
+
camY: camera.y,
|
|
5212
|
+
camZ: camera.z,
|
|
5213
|
+
widthCssPx: staticSurface.cssWidth,
|
|
5214
|
+
heightCssPx: staticSurface.cssHeight
|
|
5215
|
+
});
|
|
5216
|
+
const presentStaticScaled = (camera) => {
|
|
5217
|
+
const cache5 = ensureCacheSurface();
|
|
5218
|
+
const w = staticSurface.canvas.width;
|
|
5219
|
+
const h = staticSurface.canvas.height;
|
|
5220
|
+
const { srcX, srcY, srcW, srcH } = computeCacheSourceRect(
|
|
5221
|
+
snapshotCacheCamera(cache5),
|
|
5222
|
+
snapshotView(camera)
|
|
5223
|
+
);
|
|
5224
|
+
staticSurface.ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
5225
|
+
staticSurface.ctx.clearRect(0, 0, w, h);
|
|
5226
|
+
staticSurface.ctx.drawImage(cache5.canvas, srcX, srcY, srcW, srcH, 0, 0, w, h);
|
|
5227
|
+
};
|
|
5228
|
+
const SCALED_BLIT_MAX_RATIO = 4;
|
|
5229
|
+
const SCALED_EXTEND_MIN_RATIO = 0.5;
|
|
5109
5230
|
const paintStatic = () => {
|
|
5110
5231
|
const camera = store.getCamera();
|
|
5111
5232
|
if (!cacheStale && camera.z === cacheCamZ) {
|
|
5112
5233
|
if (viewportFitsInCache(camera)) {
|
|
5113
5234
|
presentStatic(camera);
|
|
5235
|
+
lastDrawPath = "present";
|
|
5114
5236
|
return;
|
|
5115
5237
|
}
|
|
5116
5238
|
if (canExtend(camera)) {
|
|
5117
5239
|
extendCache(camera);
|
|
5118
5240
|
presentStatic(camera);
|
|
5241
|
+
lastDrawPath = "extend";
|
|
5242
|
+
return;
|
|
5243
|
+
}
|
|
5244
|
+
}
|
|
5245
|
+
if (!cacheStale && camera.z !== cacheCamZ && store.getInteractionState().mode === "zooming" && cacheSurface) {
|
|
5246
|
+
const cacheCam = snapshotCacheCamera(cacheSurface);
|
|
5247
|
+
const view = snapshotView(camera);
|
|
5248
|
+
if (scaleRatioInBounds(cacheCam.camZ, view.camZ, SCALED_BLIT_MAX_RATIO) && cacheCoversViewport(cacheCam, view)) {
|
|
5249
|
+
presentStaticScaled(camera);
|
|
5250
|
+
lastDrawPath = "scaled";
|
|
5119
5251
|
return;
|
|
5120
5252
|
}
|
|
5253
|
+
if (zoomExtendRatioInBounds(cacheCam.camZ, view.camZ, SCALED_EXTEND_MIN_RATIO)) {
|
|
5254
|
+
const layout = cacheReuseLayout(cacheCam, view);
|
|
5255
|
+
if (layout.valid) {
|
|
5256
|
+
extendCacheScaled(camera, layout);
|
|
5257
|
+
presentStatic(camera);
|
|
5258
|
+
lastDrawPath = "scaled-extend";
|
|
5259
|
+
return;
|
|
5260
|
+
}
|
|
5261
|
+
}
|
|
5121
5262
|
}
|
|
5122
5263
|
renderFullCache(camera);
|
|
5123
5264
|
presentStatic(camera);
|
|
5265
|
+
lastDrawPath = "full";
|
|
5124
5266
|
};
|
|
5125
5267
|
const paintCustomCanvasFallback = (ctx, node, def, drawScale, env) => {
|
|
5126
5268
|
if (def.getSnapshot) {
|
|
@@ -5443,9 +5585,11 @@ var createRenderer = (opts) => {
|
|
|
5443
5585
|
};
|
|
5444
5586
|
const onInteractionChange = (state) => {
|
|
5445
5587
|
interactiveDirty = true;
|
|
5446
|
-
if (state.mode === "dragging" || state.mode === "resizing" || state.mode === "rotating" || state.mode === "panning" || state.mode === "
|
|
5588
|
+
if (state.mode === "dragging" || state.mode === "resizing" || state.mode === "rotating" || state.mode === "panning" || state.mode === "idle") {
|
|
5447
5589
|
staticDirty = true;
|
|
5448
5590
|
cacheStale = true;
|
|
5591
|
+
} else if (state.mode === "zooming") {
|
|
5592
|
+
staticDirty = true;
|
|
5449
5593
|
}
|
|
5450
5594
|
loop.requestFrame();
|
|
5451
5595
|
};
|
|
@@ -5509,6 +5653,7 @@ var createRenderer = (opts) => {
|
|
|
5509
5653
|
},
|
|
5510
5654
|
stats: () => loop.stats(),
|
|
5511
5655
|
lastDrawCount: () => lastDrawn,
|
|
5656
|
+
getLastDrawPath: () => lastDrawPath,
|
|
5512
5657
|
getOverlaySet: () => [...overlaySet],
|
|
5513
5658
|
getAssetCache: () => assetCache,
|
|
5514
5659
|
dispose() {
|