Improve CSS test preview: HD resolution, screen-only border, and refactor frontend docs
- Bump capture preview resolution from 480×360 to 960×540 (HD) - Increase preview FPS from 2 to ~12 FPS (AUX_INTERVAL 0.5→0.08) - Add accent-color border on screen rect only (not LED edges) via ::after - Use dynamic aspect-ratio from decoded JPEG frames instead of fixed height - Widen modal to 900px for picture sources - Move frontend conventions from CLAUDE.md to contexts/frontend.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -775,7 +775,7 @@ async def test_color_strip_ws(
|
||||
if is_picture and hasattr(stream, '_live_stream'):
|
||||
_frame_live = stream._live_stream
|
||||
_last_aux_time = 0.0
|
||||
_AUX_INTERVAL = 0.5 # send JPEG preview / brightness updates every 0.5s
|
||||
_AUX_INTERVAL = 0.08 # send JPEG preview / brightness updates ~12 FPS
|
||||
|
||||
# Stream binary RGB frames at ~20 Hz
|
||||
while True:
|
||||
@@ -832,7 +832,7 @@ async def test_color_strip_ws(
|
||||
img = img[:, :, :3]
|
||||
# Downscale for bandwidth
|
||||
h, w = img.shape[:2]
|
||||
scale = min(480 / w, 360 / h, 1.0)
|
||||
scale = min(960 / w, 540 / h, 1.0)
|
||||
if scale < 1.0:
|
||||
new_w = max(1, int(w * scale))
|
||||
new_h = max(1, int(h * scale))
|
||||
|
||||
@@ -175,8 +175,10 @@
|
||||
grid-template-columns: 14px 1fr 14px;
|
||||
grid-template-rows: 14px 1fr 14px;
|
||||
width: 100%;
|
||||
height: 320px;
|
||||
aspect-ratio: 16 / 9;
|
||||
max-height: 70vh;
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.css-test-rect-corner {
|
||||
@@ -184,12 +186,11 @@
|
||||
}
|
||||
|
||||
.css-test-rect-screen {
|
||||
position: relative;
|
||||
background-image: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
border-radius: 2px;
|
||||
outline: 1px solid rgba(255, 255, 255, 0.15);
|
||||
outline-offset: -1px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
@@ -198,6 +199,16 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.css-test-rect-screen::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border: 2px solid var(--primary-color);
|
||||
border-radius: 2px;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.css-test-rect-label {
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
font-size: 0.8rem;
|
||||
|
||||
@@ -1973,6 +1973,10 @@ function _cssTestConnect(sourceId, ledCount) {
|
||||
document.getElementById('css-test-layers-view').style.display = _cssTestIsComposite ? '' : 'none';
|
||||
document.getElementById('css-test-status').style.display = 'none';
|
||||
|
||||
// Widen modal for picture sources to show the screen rectangle larger
|
||||
const modalContent = document.querySelector('#test-css-source-modal .modal-content');
|
||||
if (modalContent) modalContent.style.maxWidth = isPicture ? '900px' : '';
|
||||
|
||||
// Hide LED count control for picture sources (LED count is fixed by calibration)
|
||||
document.getElementById('css-test-led-control').style.display = isPicture ? 'none' : '';
|
||||
|
||||
@@ -2016,6 +2020,14 @@ function _cssTestConnect(sourceId, ledCount) {
|
||||
screen.style.backgroundSize = 'cover';
|
||||
screen.style.backgroundPosition = 'center';
|
||||
if (oldUrl) URL.revokeObjectURL(oldUrl);
|
||||
// Set aspect ratio from first decoded frame
|
||||
const rect = document.getElementById('css-test-rect');
|
||||
if (rect && !rect._aspectSet && img.naturalWidth && img.naturalHeight) {
|
||||
rect.style.aspectRatio = `${img.naturalWidth} / ${img.naturalHeight}`;
|
||||
rect.style.height = 'auto';
|
||||
rect._aspectSet = true;
|
||||
requestAnimationFrame(() => _cssTestRenderTicks(_cssTestMeta?.edges));
|
||||
}
|
||||
};
|
||||
img.onerror = () => URL.revokeObjectURL(url);
|
||||
img.src = url;
|
||||
@@ -2356,6 +2368,12 @@ export function closeTestCssSourceModal() {
|
||||
// Revoke blob URL for frame preview
|
||||
const screen = document.getElementById('css-test-rect-screen');
|
||||
if (screen && screen._blobUrl) { URL.revokeObjectURL(screen._blobUrl); screen._blobUrl = null; screen.style.backgroundImage = ''; }
|
||||
// Reset aspect ratio for next open
|
||||
const rect = document.getElementById('css-test-rect');
|
||||
if (rect) { rect.style.aspectRatio = ''; rect.style.height = ''; rect._aspectSet = false; }
|
||||
// Reset modal width
|
||||
const modalContent = document.querySelector('#test-css-source-modal .modal-content');
|
||||
if (modalContent) modalContent.style.maxWidth = '';
|
||||
const modal = document.getElementById('test-css-source-modal');
|
||||
if (modal) { modal.style.display = 'none'; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user