From ecd2844c08486d08477c3d6a1c53462a1d4899dd Mon Sep 17 00:00:00 2001 From: Jeffrey Alan Scudder Date: Sun, 29 Mar 2026 17:52:44 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20camera=20orientation=20=E2=80=94=20stop?= =?UTF-8?q?=20mutating=20shared=20constraint=20dimensions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getDevice() was mutating outer-scope cWidth/cHeight on every call, causing dimension swap to toggle unpredictably across camera swaps and resizes. Also fixed aspectRatio constraint contradicting the swapped width/height (was computed before the swap). Co-Authored-By: Claude Opus 4.6 (1M context) --- system/public/aesthetic.computer/bios.mjs | 41 ++++++++++++----------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/system/public/aesthetic.computer/bios.mjs b/system/public/aesthetic.computer/bios.mjs index 3a2885b0db..9c8bff6bc3 100644 --- a/system/public/aesthetic.computer/bios.mjs +++ b/system/public/aesthetic.computer/bios.mjs @@ -19504,40 +19504,35 @@ async function boot(parsed, bpm = 60, resolution, debug) { cHeight = options.height; async function getDevice(facingModeChoice) { - // Swap width and height on iOS. (Implementation default differences.) - // Set a height / width aspect ratio on iOS because - // of implementation differences. - - // console.log("Trying: Width:", cWidth, "Height:", cHeight); + // Use local copies so we don't mutate the outer cWidth/cHeight + // across repeated calls (camera swap, resize, etc.). + let reqWidth = cWidth, + reqHeight = cHeight; const constraints = { facingMode: facingModeChoice, frameRate: { ideal: 30 }, }; - // Calculate target aspect ratio for better matching - const targetAR = cWidth / cHeight; - + // Swap width/height on mobile in portrait — camera sensors are + // natively landscape, so request landscape constraints. if ( (iOS || Android) && window.matchMedia("(orientation: portrait)").matches && (facingModeChoice === "environment" || facingModeChoice === "user") - // && - // firstVideo ) { - const temp = cWidth; - cWidth = cHeight; - cHeight = temp; - // firstVideo = false; + const temp = reqWidth; + reqWidth = reqHeight; + reqHeight = temp; } - // alert(cWidth + " " + cHeight); + // Calculate target aspect ratio AFTER the swap so it matches + // the width/height we actually request. + const targetAR = reqWidth / reqHeight; + + constraints.width = { ideal: reqWidth }; + constraints.height = { ideal: reqHeight }; - // Request ideal dimensions with aspect ratio hint - constraints.width = { ideal: cWidth }; - constraints.height = { ideal: cHeight }; - - // Add aspect ratio constraint if supported (helps get better match) if (targetAR > 0 && isFinite(targetAR)) { constraints.aspectRatio = { ideal: targetAR }; } @@ -19606,9 +19601,15 @@ async function boot(parsed, bpm = 60, resolution, debug) { const sizeChange = !isNaN(width) && !isNaN(height); if (sizeChange) { + // Update outer dimensions from the new size. + cWidth = width; + cHeight = height; + video.addEventListener( "loadedmetadata", () => { + // Buffer should match the requested screen dimensions, + // not the (possibly swapped) constraint dimensions. buffer.width = cWidth; buffer.height = cHeight; process(); -- 2.51.2