summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-03-22 16:40:02 +0100
committerskal <pascal.massimino@gmail.com>2026-03-22 16:40:02 +0100
commit31c6287f58b128f3e9a8a7bca5b09befa7fc96b5 (patch)
tree27892e3bd835a878ea4e87463792649f56798ffc
parente46c2a6a110e803cab1e50095dd8ef60add8c788 (diff)
fix(cnn_v3/tools): zoom canvas fits remaining panel space (both axes, rAF measure)
-rw-r--r--cnn_v3/tools/index.html6
-rw-r--r--cnn_v3/tools/tester.js49
2 files changed, 29 insertions, 26 deletions
diff --git a/cnn_v3/tools/index.html b/cnn_v3/tools/index.html
index f22084d..26fee9b 100644
--- a/cnn_v3/tools/index.html
+++ b/cnn_v3/tools/index.html
@@ -142,11 +142,11 @@ video{display:none}
<div class="right">
<div class="panel" style="flex:1;display:flex;flex-direction:column;min-height:0">
<div class="ph">Layer Visualization</div>
- <div class="pc" id="layerViz" style="flex:1;overflow:auto">
+ <div class="pc" id="layerViz" style="flex:1;min-height:0;overflow:auto">
<p style="color:#444;text-align:center">Load image + weights</p>
</div>
- <div id="chzoomWrap" style="display:none;flex-direction:column;align-items:center;gap:3px;padding:6px;border-top:1px solid #333;background:#1a1a1a">
- <span id="chzoomLbl" style="font-size:9px;color:#666"></span>
+ <div id="chzoomWrap" style="display:none;flex-direction:column;align-items:center;justify-content:center;gap:3px;padding:6px;border-top:1px solid #333;background:#1a1a1a;flex:1;min-height:0;overflow:hidden">
+ <span id="chzoomLbl" style="font-size:9px;color:#666;flex-shrink:0"></span>
<canvas id="chzoom" style="image-rendering:pixelated;display:block"></canvas>
</div>
</div>
diff --git a/cnn_v3/tools/tester.js b/cnn_v3/tools/tester.js
index fd2b7bd..4286060 100644
--- a/cnn_v3/tools/tester.js
+++ b/cnn_v3/tools/tester.js
@@ -491,31 +491,34 @@ class CNNv3Tester {
const tex = this.layerTextures[layerId];
if (!def || !tex || !this.device) return;
const wrap = document.getElementById('chzoomWrap');
- const dst = document.getElementById('chzoom');
const lbl = document.getElementById('chzoomLbl');
- // Size: fit canvas to available container width (height:auto doesn't work on <canvas>)
- const maxW = wrap.clientWidth - 12; // subtract wrap padding
- const scale = Math.min(1, maxW / tex.width);
- dst.width = Math.round(tex.width * scale);
- dst.height = Math.round(tex.height * scale);
- dst.style.width = '';
- dst.style.height = '';
- lbl.textContent = label;
+ lbl.textContent = label;
wrap.style.display = 'flex';
- // Re-render via WebGPU (WebGPU canvas pixels are not readable by drawImage)
- const pl = def.t === 'f32' ? this.getVizF32() : this.getVizU32();
- const ctx = dst.getContext('webgpu');
- try { ctx.configure({device: this.device, format: this.format}); } catch(_) { return; }
- const chBuf = this.device.createBuffer({size:4, usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});
- this.device.queue.writeBuffer(chBuf, 0, new Uint32Array([ch]));
- const bg = this.device.createBindGroup({layout: pl.getBindGroupLayout(0),
- entries:[{binding:0, resource:tex.createView()}, {binding:1, resource:{buffer:chBuf}}]});
- const enc = this.device.createCommandEncoder();
- const rp = enc.beginRenderPass({colorAttachments:[{
- view:ctx.getCurrentTexture().createView(), loadOp:'clear', storeOp:'store'}]});
- rp.setPipeline(pl); rp.setBindGroup(0, bg); rp.draw(6); rp.end();
- this.device.queue.submit([enc.finish()]);
- chBuf.destroy();
+ // Wait for layout so clientWidth/clientHeight reflect the flex-distributed size
+ requestAnimationFrame(() => {
+ const dst = document.getElementById('chzoom');
+ const pad = 12;
+ const lblH = lbl.offsetHeight + 6;
+ const availW = wrap.clientWidth - pad;
+ const availH = wrap.clientHeight - pad - lblH;
+ const scale = Math.min(1, availW / tex.width, availH / tex.height);
+ dst.width = Math.round(tex.width * scale);
+ dst.height = Math.round(tex.height * scale);
+ // Re-render via WebGPU (WebGPU canvas pixels are not readable by drawImage)
+ const pl = def.t === 'f32' ? this.getVizF32() : this.getVizU32();
+ const ctx = dst.getContext('webgpu');
+ try { ctx.configure({device: this.device, format: this.format}); } catch(_) { return; }
+ const chBuf = this.device.createBuffer({size:4, usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});
+ this.device.queue.writeBuffer(chBuf, 0, new Uint32Array([ch]));
+ const bg = this.device.createBindGroup({layout: pl.getBindGroupLayout(0),
+ entries:[{binding:0, resource:tex.createView()}, {binding:1, resource:{buffer:chBuf}}]});
+ const enc = this.device.createCommandEncoder();
+ const rp = enc.beginRenderPass({colorAttachments:[{
+ view:ctx.getCurrentTexture().createView(), loadOp:'clear', storeOp:'store'}]});
+ rp.setPipeline(pl); rp.setBindGroup(0, bg); rp.draw(6); rp.end();
+ this.device.queue.submit([enc.finish()]);
+ chBuf.destroy();
+ });
}
// ── Save PNG ─────────────────────────────────────────────────────────────