Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: camera orientation — stop mutating shared constraint dimensions

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) <noreply@anthropic.com>

+21 -20
+21 -20
system/public/aesthetic.computer/bios.mjs
··· 19504 19504 cHeight = options.height; 19505 19505 19506 19506 async function getDevice(facingModeChoice) { 19507 - // Swap width and height on iOS. (Implementation default differences.) 19508 - // Set a height / width aspect ratio on iOS because 19509 - // of implementation differences. 19510 - 19511 - // console.log("Trying: Width:", cWidth, "Height:", cHeight); 19507 + // Use local copies so we don't mutate the outer cWidth/cHeight 19508 + // across repeated calls (camera swap, resize, etc.). 19509 + let reqWidth = cWidth, 19510 + reqHeight = cHeight; 19512 19511 19513 19512 const constraints = { 19514 19513 facingMode: facingModeChoice, 19515 19514 frameRate: { ideal: 30 }, 19516 19515 }; 19517 19516 19518 - // Calculate target aspect ratio for better matching 19519 - const targetAR = cWidth / cHeight; 19520 - 19517 + // Swap width/height on mobile in portrait — camera sensors are 19518 + // natively landscape, so request landscape constraints. 19521 19519 if ( 19522 19520 (iOS || Android) && 19523 19521 window.matchMedia("(orientation: portrait)").matches && 19524 19522 (facingModeChoice === "environment" || facingModeChoice === "user") 19525 - // && 19526 - // firstVideo 19527 19523 ) { 19528 - const temp = cWidth; 19529 - cWidth = cHeight; 19530 - cHeight = temp; 19531 - // firstVideo = false; 19524 + const temp = reqWidth; 19525 + reqWidth = reqHeight; 19526 + reqHeight = temp; 19532 19527 } 19533 19528 19534 - // alert(cWidth + " " + cHeight); 19529 + // Calculate target aspect ratio AFTER the swap so it matches 19530 + // the width/height we actually request. 19531 + const targetAR = reqWidth / reqHeight; 19532 + 19533 + constraints.width = { ideal: reqWidth }; 19534 + constraints.height = { ideal: reqHeight }; 19535 19535 19536 - // Request ideal dimensions with aspect ratio hint 19537 - constraints.width = { ideal: cWidth }; 19538 - constraints.height = { ideal: cHeight }; 19539 - 19540 - // Add aspect ratio constraint if supported (helps get better match) 19541 19536 if (targetAR > 0 && isFinite(targetAR)) { 19542 19537 constraints.aspectRatio = { ideal: targetAR }; 19543 19538 } ··· 19606 19601 const sizeChange = !isNaN(width) && !isNaN(height); 19607 19602 19608 19603 if (sizeChange) { 19604 + // Update outer dimensions from the new size. 19605 + cWidth = width; 19606 + cHeight = height; 19607 + 19609 19608 video.addEventListener( 19610 19609 "loadedmetadata", 19611 19610 () => { 19611 + // Buffer should match the requested screen dimensions, 19612 + // not the (possibly swapped) constraint dimensions. 19612 19613 buffer.width = cWidth; 19613 19614 buffer.height = cHeight; 19614 19615 process();