Show captured border width overlay in picture CSS test preview

Backend: send border_width in WS metadata and frame_dims (width, height)
as a separate JSON message on first JPEG frame.

Frontend: render semi-transparent green overlay rectangles on each active
edge showing the sampling region depth, plus a small px label. Overlays
are proportionally sized based on border_width relative to frame dimensions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-17 02:09:29 +03:00
parent 00c9ad3a86
commit 823cb90d2d
3 changed files with 85 additions and 1 deletions

View File

@@ -2612,6 +2612,12 @@ function _cssTestConnect(sourceId, ledCount, fps) {
return;
}
// Handle frame dimensions — render border-width overlay
if (msg.type === 'frame_dims' && _cssTestMeta) {
_cssTestRenderBorderOverlay(msg.width, msg.height);
return;
}
// Initial metadata
_cssTestMeta = msg;
const isPicture = _cssTestMeta.edges && _cssTestMeta.edges.length > 0;
@@ -2913,6 +2919,61 @@ function _cssTestRenderRect(rgbBytes, edges) {
}
}
function _cssTestRenderBorderOverlay(frameW, frameH) {
const screen = document.getElementById('css-test-rect-screen');
if (!screen || !_cssTestMeta) return;
// Remove any previous border overlay
screen.querySelectorAll('.css-test-border-overlay').forEach(el => el.remove());
const bw = _cssTestMeta.border_width;
if (!bw || bw <= 0) return;
const edges = _cssTestMeta.edges || [];
const activeEdges = new Set(edges.map(e => e.edge));
// Compute border as percentage of frame dimensions
const bwPctH = (bw / frameH * 100).toFixed(2); // % for top/bottom
const bwPctW = (bw / frameW * 100).toFixed(2); // % for left/right
const overlayStyle = 'position:absolute;pointer-events:none;background:rgba(var(--primary-color-rgb, 76,175,80),0.18);border:1px solid rgba(var(--primary-color-rgb, 76,175,80),0.4);';
if (activeEdges.has('top')) {
const el = document.createElement('div');
el.className = 'css-test-border-overlay';
el.style.cssText = `${overlayStyle}top:0;left:0;right:0;height:${bwPctH}%;`;
el.title = `${t('calibration.border_width')} ${bw}px`;
screen.appendChild(el);
}
if (activeEdges.has('bottom')) {
const el = document.createElement('div');
el.className = 'css-test-border-overlay';
el.style.cssText = `${overlayStyle}bottom:0;left:0;right:0;height:${bwPctH}%;`;
el.title = `${t('calibration.border_width')} ${bw}px`;
screen.appendChild(el);
}
if (activeEdges.has('left')) {
const el = document.createElement('div');
el.className = 'css-test-border-overlay';
el.style.cssText = `${overlayStyle}top:0;bottom:0;left:0;width:${bwPctW}%;`;
el.title = `${t('calibration.border_width')} ${bw}px`;
screen.appendChild(el);
}
if (activeEdges.has('right')) {
const el = document.createElement('div');
el.className = 'css-test-border-overlay';
el.style.cssText = `${overlayStyle}top:0;bottom:0;right:0;width:${bwPctW}%;`;
el.title = `${t('calibration.border_width')} ${bw}px`;
screen.appendChild(el);
}
// Show border width label
const label = document.createElement('div');
label.className = 'css-test-border-overlay css-test-border-label';
label.textContent = `${bw}px`;
screen.appendChild(label);
}
function _cssTestRenderTicks(edges) {
const canvas = document.getElementById('css-test-rect-ticks');
const rectEl = document.getElementById('css-test-rect');