mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-08-01 16:58:06 +00:00
fix(web): size the live preview from the PNG's real dimensions, not config
The initial SSE render sized the preview image (and both overlay canvases) from the server-reported config dimensions (cols x chain_length, rows x parallel), while the scale slider's re-render path sized from img.naturalWidth/naturalHeight. Whenever the snapshot PNG's actual size disagrees with the config (stale config, display service not restarted after a hardware change), the initial render stretched the image at a fractional ratio - blurry despite image-rendering: pixelated - and touching the scale slider "fixed" it. Reported live on the devpi test rig. Both paths now size from the loaded image's natural dimensions inside img.onload (which also removes a transient wrong-size flash between src assignment and load). The meta label now reports the true snapshot size. The preview card also gets overflow-x-auto so on narrow screens a wide preview scrolls at its exact pixel-perfect size instead of being squeezed into the viewport (fractional downscaling of pixel art also reads as blur). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KEZK1P1Q1fu5pcuVrkrCFZ
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
84c41dfbf0
commit
b6a8a88665
@@ -1870,29 +1870,35 @@
|
||||
// Current scale from slider
|
||||
const scale = parseInt(document.getElementById('scaleRange')?.value || '8');
|
||||
|
||||
// Update image and meta label
|
||||
// Update image and meta label. Size everything from the PNG's
|
||||
// OWN dimensions (naturalWidth/Height) once it has loaded —
|
||||
// not from the server-reported config dimensions. If the
|
||||
// config disagrees with what the display service actually
|
||||
// renders (stale config, service not yet restarted), sizing
|
||||
// from config stretches the image at a fractional ratio and
|
||||
// the preview looks blurry until the scale slider forces a
|
||||
// re-render. The slider path always used natural dimensions;
|
||||
// now both paths do.
|
||||
img.style.imageRendering = 'pixelated';
|
||||
img.onload = () => {
|
||||
const nw = img.naturalWidth || data.width || 128;
|
||||
const nh = img.naturalHeight || data.height || 64;
|
||||
const width = nw * scale;
|
||||
const height = nh * scale;
|
||||
img.style.width = width + 'px';
|
||||
img.style.height = height + 'px';
|
||||
ledCanvas.width = width;
|
||||
ledCanvas.height = height;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
const meta = document.getElementById('previewMeta');
|
||||
if (meta) {
|
||||
meta.textContent = `${nw} x ${nh} @ ${scale}x`;
|
||||
}
|
||||
drawGrid(canvas, nw, nh, scale);
|
||||
renderLedDots();
|
||||
};
|
||||
img.src = `data:image/png;base64,${data.image}`;
|
||||
|
||||
const meta = document.getElementById('previewMeta');
|
||||
if (meta) {
|
||||
meta.textContent = `${data.width || 128} x ${data.height || 64} @ ${scale}x`;
|
||||
}
|
||||
|
||||
// Size the canvases to match
|
||||
const width = (data.width || 128) * scale;
|
||||
const height = (data.height || 64) * scale;
|
||||
img.style.width = width + 'px';
|
||||
img.style.height = height + 'px';
|
||||
ledCanvas.width = width;
|
||||
ledCanvas.height = height;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
drawGrid(canvas, data.width || 128, data.height || 64, scale);
|
||||
renderLedDots();
|
||||
} else {
|
||||
stage.style.display = 'none';
|
||||
placeholder.style.display = 'block';
|
||||
|
||||
Reference in New Issue
Block a user