()
| 3261 | |
| 3262 | |
| 3263 | function updatePreviewSize() { |
| 3264 | const previewWrapper = document.querySelector(".preview-wrapper"); |
| 3265 | if (!previewWrapper) return; |
| 3266 | |
| 3267 | |
| 3268 | const wrapperRect = previewWrapper.getBoundingClientRect(); |
| 3269 | const availableWidth = wrapperRect.width - 32; |
| 3270 | const availableHeight = wrapperRect.height - 32; |
| 3271 | |
| 3272 | |
| 3273 | const baseScale = Math.min( |
| 3274 | availableWidth / dispWidth, |
| 3275 | availableHeight / dispHeight |
| 3276 | ); |
| 3277 | // OLED should scale by an integer so everything snaps to the pixel grid. |
| 3278 | const scale = driverMode === "u8g2" |
| 3279 | ? Math.max(1, Math.floor(baseScale * clamp(zoomFactor || 1, 0.5, 3))) |
| 3280 | : baseScale; |
| 3281 | |
| 3282 | preview.style.width = dispWidth * scale + "px"; |
| 3283 | preview.style.height = dispHeight * scale + "px"; |
| 3284 | preview.style.backgroundColor = bgColor; |
| 3285 | |
| 3286 | // OLED mode: show individual pixels |
| 3287 | if (driverMode === "u8g2") { |
| 3288 | preview.classList.add('oled-display'); |
| 3289 | // For OLED, use nearest neighbor scaling to show pixels clearly |
| 3290 | preview.style.imageRendering = 'pixelated'; |
| 3291 | preview.style.imageRendering = '-moz-crisp-edges'; |
| 3292 | preview.style.imageRendering = 'crisp-edges'; |
| 3293 | |
| 3294 | // Set pixel grid size based on scale (each display pixel = 1 physical pixel at 1:1 scale) |
| 3295 | const pixelSize = Math.max(1, scale); |
| 3296 | preview.style.setProperty('--pixel-size', pixelSize + 'px'); |
| 3297 | } else { |
| 3298 | preview.classList.remove('oled-display'); |
| 3299 | preview.style.imageRendering = 'auto'; |
| 3300 | preview.style.removeProperty('--pixel-size'); |
| 3301 | } |
| 3302 | |
| 3303 | preview.dataset.scale = scale; |
| 3304 | const driverLabel = driverMode === "u8g2" ? "U8g2 OLED" : "TFT_eSPI"; |
| 3305 | displayInfo.textContent = `${driverLabel} · ${dispWidth}x${dispHeight} px`; |
| 3306 | |
| 3307 | applyViewportTransform(); |
| 3308 | // Rulers + guides need to follow rendered size |
| 3309 | setTimeout(() => { |
| 3310 | try { ensureRulers(); } catch (_) {} |
| 3311 | }, 0); |
| 3312 | setTimeout(() => { |
| 3313 | try { renderGuides(); } catch (_) {} |
| 3314 | }, 0); |
| 3315 | } |
| 3316 | |
| 3317 | function addAssetElementToCanvas(assetId) { |
| 3318 | const a = (assets || []).find((x) => x && x.id === assetId); |
no test coverage detected