diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-13 16:08:06 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-13 16:08:06 +0100 |
| commit | b5e8abad0490e47b52d300d2d0c48425c3fac4f3 (patch) | |
| tree | 1b285cc1d286706ca8801581446b33854b655542 | |
| parent | d3d72f7b70e8f7d1f1ec0fb3030c447a8f876d8f (diff) | |
CNN v2 test tool: UI improvements and video playback fixes
- Change Depth control from number input to slider (0-1 range)
- Move video controls to floating overlay at top of canvas
- Remove View mode indicator from header (shortcuts still work)
- Remove scrollbar from Layer Visualization panel
- Fix layer viz flickering during video playback
- Fix video controls responsiveness during playback
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
| -rw-r--r-- | tools/cnn_v2_test/index.html | 77 |
1 files changed, 41 insertions, 36 deletions
diff --git a/tools/cnn_v2_test/index.html b/tools/cnn_v2_test/index.html index 95ec788..79c54b7 100644 --- a/tools/cnn_v2_test/index.html +++ b/tools/cnn_v2_test/index.html @@ -120,6 +120,19 @@ position: relative; background: #1a1a1a; } + .video-controls-float { + position: absolute; + top: 16px; + left: 50%; + transform: translateX(-50%); + display: flex; + gap: 8px; + background: rgba(42, 42, 42, 0.95); + padding: 8px 12px; + border-radius: 4px; + border: 1px solid #404040; + z-index: 100; + } .main.drop-active::after { content: 'Drop PNG/video here'; position: absolute; @@ -291,11 +304,6 @@ <div class="header"> <h1>CNN v2 Testing Tool</h1> <div class="controls"> - <div class="control-group" id="videoControls"> - <button id="playPauseBtn" disabled>Play</button> - <button id="stepBackBtn" disabled>◄ Frame</button> - <button id="stepForwardBtn" disabled>Frame ►</button> - </div> <div class="control-group"> <label>Blend:</label> <input type="range" id="blend" min="0" max="1" step="0.01" value="1.0"> @@ -303,11 +311,8 @@ </div> <div class="control-group"> <label>Depth:</label> - <input type="number" id="depth" min="0" max="1" step="0.1" value="1.0"> - </div> - <div class="control-group"> - <label>View:</label> - <span id="viewMode">CNN Output</span> + <input type="range" id="depth" min="0" max="1" step="0.01" value="1.0"> + <span id="depthValue">1.0</span> </div> </div> </div> @@ -333,12 +338,17 @@ </div> </div> <div class="main" id="mainDrop"> + <div class="video-controls-float" id="videoControls"> + <button id="playPauseBtn" disabled>Play</button> + <button id="stepBackBtn" disabled>◄ Frame</button> + <button id="stepForwardBtn" disabled>Frame ►</button> + </div> <canvas id="canvas"></canvas> </div> <div class="sidebar"> <div class="panel" style="flex: 1; display: flex; flex-direction: column; min-height: 0;"> <div class="panel-header">Layer Visualization</div> - <div class="panel-content" id="layerViz" style="flex: 1; overflow-y: auto;"> + <div class="panel-content" id="layerViz" style="flex: 1; overflow: hidden;"> <p style="color: #808080; text-align: center;">Load image + weights</p> </div> </div> @@ -1192,9 +1202,6 @@ class CNNTester { } updateLayerVizPanel() { - // Optimization: Skip layer viz updates during video playback (~5-10ms saved per frame) - if (this.isVideo && !this.video.paused) return; - const panel = document.getElementById('layerViz'); if (!this.layerOutputs || this.layerOutputs.length === 0) { @@ -1202,31 +1209,30 @@ class CNNTester { return; } - let html = '<div class="layer-buttons">'; - // Static features: two buttons for 8D (0-3 and 4-7) - html += `<button onclick="tester.visualizeLayer(0, 0)" id="layerBtn0_0">Static 0-3</button>`; - html += `<button onclick="tester.visualizeLayer(0, 4)" id="layerBtn0_4">Static 4-7</button>`; + // Only rebuild panel structure if layer count changed + const needsRebuild = !this.lastLayerCount || this.lastLayerCount !== this.layerOutputs.length; - // CNN layers: Layer 0, Layer 1, Layer 2, ... - for (let i = 1; i < this.layerOutputs.length; i++) { - // i=1: Layer 0 (weights.layers[0]) - // i=2: Layer 1 (weights.layers[1]), etc. - const label = `Layer ${i - 1}`; - html += `<button onclick="tester.visualizeLayer(${i})" id="layerBtn${i}">${label}</button>`; - } - html += '</div>'; - - html += '<div class="layer-grid" id="layerGrid"></div>'; - html += '<div class="layer-zoom"><div class="layer-view-label">Zoom x4</div><canvas id="zoomCanvas"></canvas></div>'; + if (needsRebuild) { + let html = '<div class="layer-buttons">'; + html += `<button onclick="tester.visualizeLayer(0, 0)" id="layerBtn0_0">Static 0-3</button>`; + html += `<button onclick="tester.visualizeLayer(0, 4)" id="layerBtn0_4">Static 4-7</button>`; - panel.innerHTML = html; + for (let i = 1; i < this.layerOutputs.length; i++) { + const label = `Layer ${i - 1}`; + html += `<button onclick="tester.visualizeLayer(${i})" id="layerBtn${i}">${label}</button>`; + } + html += '</div>'; - this.log(`Layer visualization ready: ${this.layerOutputs.length} layers`); + html += '<div class="layer-grid" id="layerGrid"></div>'; + html += '<div class="layer-zoom"><div class="layer-view-label">Zoom x4</div><canvas id="zoomCanvas"></canvas></div>'; - // Create initial canvases - this.recreateCanvases(); + panel.innerHTML = html; + this.log(`Layer visualization ready: ${this.layerOutputs.length} layers`); + this.recreateCanvases(); + this.lastLayerCount = this.layerOutputs.length; + } - // Restore previous selection or default to static features (channels 0-3) + // Update current visualization if (this.currentLayerIdx !== null) { this.visualizeLayer(this.currentLayerIdx, this.currentChannelOffset || 0); } else { @@ -1700,6 +1706,7 @@ document.getElementById('blend').addEventListener('input', e => { document.getElementById('depth').addEventListener('input', e => { tester.depth = parseFloat(e.target.value); + document.getElementById('depthValue').textContent = e.target.value; if ((tester.image || tester.isVideo) && tester.weights) tester.run(); }); @@ -1716,7 +1723,6 @@ document.addEventListener('keydown', e => { tester.viewMode = 1; } const modeName = ['CNN Output', 'Original', 'Diff (×10)'][tester.viewMode]; - document.getElementById('viewMode').textContent = modeName; if ((tester.image || tester.isVideo) && tester.weights) { tester.log(`View mode: ${modeName}`); tester.updateDisplay(); @@ -1732,7 +1738,6 @@ document.addEventListener('keydown', e => { tester.viewMode = 2; } const modeName = ['CNN Output', 'Original', 'Diff (×10)'][tester.viewMode]; - document.getElementById('viewMode').textContent = modeName; if ((tester.image || tester.isVideo) && tester.weights) { tester.log(`View mode: ${modeName}`); tester.updateDisplay(); |
