diff --git a/src/components/Viewfinder.tsx b/src/components/Viewfinder.tsx index 882bc68..a120473 100644 --- a/src/components/Viewfinder.tsx +++ b/src/components/Viewfinder.tsx @@ -374,6 +374,9 @@ export default function Viewfinder({ // the preview flicker. All live values flow through the synchronizables. type SkiaCameraOnFrame = NonNullable['onFrame']>; const toneFailLogged = useMemo(() => createSynchronizable(false), []); + // DEBUG-4x3 (remove after diagnosis): log actual stream geometry at runtime. + const dbgCountSync = useMemo(() => createSynchronizable(0), []); + const dbgLastSync = useMemo(() => createSynchronizable(''), []); // Composition band fed to the frame worklet: [active, viewAspect, fx, fy, // fw, fh] where (fx,fy,fw,fh) is the photo-area rect (ratio band / polaroid // window / wall window) normalized to the view. While active the worklet @@ -438,14 +441,23 @@ export default function Viewfinder({ // sensor there. Equal-aspect bands (ratio 4:3 == native 3:4 sensor) // then show the ENTIRE sensor; narrower bands crop like the export. const feed = feedRectSync.getBlocking(); - const bandActive = feed[0] > 0; - if (!bandActive) { - drawFullFrame(); - return; - } const ftW = frameTexture.width(); const ftH = frameTexture.height(); const orient = frame.orientation; + const dbgMir = frame.isMirrored === true; + const dbgCount = dbgCountSync.getBlocking(); + dbgCountSync.setBlocking(dbgCount + 1); + const bandActive = feed[0] > 0; + if (!bandActive) { + // DEBUG-4x3 (remove): stream ground truth, no-band branch + const line = `ft=${ftW}x${ftH} o=${orient} mir=${dbgMir} band=0 feed=[${feed.map((f) => f.toFixed(3)).join(',')}]`; + if (dbgCount % 60 === 0 || line !== dbgLastSync.getBlocking()) { + dbgLastSync.setBlocking(line); + console.warn('[camdebug] ' + line); + } + drawFullFrame(); + return; + } const isLand = orient === 'left' || orient === 'right'; const ow = isLand ? ftH : ftW; const oh = isLand ? ftW : ftH; @@ -514,6 +526,12 @@ export default function Viewfinder({ const dh = s * ftH; const dx = u0 + (rw - dw) / 2; const dy = v0 + (rh - dh) / 2; + // DEBUG-4x3 (remove): full geometry log for the band branch + const line = `ft=${ftW}x${ftH} o=${orient} mir=${dbgMir} band=1 feed=[${feed.map((f) => f.toFixed(3)).join(',')}] up=${ow}x${oh} ac=${ac.toFixed(4)} vis=${visX.toFixed(3)}x${visY.toFixed(3)} X0=${X0.toFixed(0)} Y0=${Y0.toFixed(0)} X1=${X1.toFixed(0)} Y1=${Y1.toFixed(0)} raw=${u0.toFixed(0)},${v0.toFixed(0)} ${rw.toFixed(0)}x${rh.toFixed(0)} s=${s.toFixed(4)} d=${dx.toFixed(0)},${dy.toFixed(0)}`; + if (dbgCount % 60 === 0 || line !== dbgLastSync.getBlocking()) { + dbgLastSync.setBlocking(line); + console.warn('[camdebug] ' + line); + } // Fresh paint; its default color is opaque black (Skia default), so // the surface fill below needs no explicit color set. const blackPaint = Skia.Paint(); @@ -603,6 +621,18 @@ export default function Viewfinder({ : [0, 0, 0, 0, 0, 0] ); }, [cameraPhotoRect, vw, vh, feedRectSync]); + // DEBUG-4x3 (remove): correlate JS view/region state with the worklet log. + useEffect(() => { + console.log( + '[camdebug-js] region=' + JSON.stringify(region) + + ' band=' + regionBand + + ' ratio=' + aspectRatio + + ' frame=' + selectedFrame + + ' view=' + vw + 'x' + vh + + ' feed=' + (cameraPhotoRect ? JSON.stringify([1, vw / vh, cameraPhotoRect.x / vw, cameraPhotoRect.y / vh, cameraPhotoRect.w / vw, cameraPhotoRect.h / vh]) : 'null') + ); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [region, regionBand, aspectRatio, selectedFrame, cameraPhotoRect]); const onLibTouchStart = (e: any) => { const ts = e.nativeEvent.touches; if (ts.length >= 2) {