Show library photos at their own aspect instead of cropping to the ratio band
This commit is contained in:
@@ -775,6 +775,12 @@ export default function App() {
|
||||
setIsProcessing(true);
|
||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
|
||||
|
||||
// Plain library frames export the photo at its own aspect (the ratio band is
|
||||
// a camera-composition tool); polaroid/wall keep their framed ratio crop.
|
||||
const libraryPlainFrame =
|
||||
selectedFrame === 'none' || selectedFrame === 'classic-white' || selectedFrame === 'cinematic';
|
||||
const libraryAspect = aspectRatio === 'full' || libraryPlainFrame ? undefined : aspectRatio;
|
||||
|
||||
const result = NATIVE_EXPORT
|
||||
? await processAndExportPhotoNative(
|
||||
libraryImageUri,
|
||||
@@ -787,9 +793,10 @@ export default function App() {
|
||||
selectedFrame,
|
||||
useGeotag,
|
||||
gpsInfo,
|
||||
// Library export follows the same composition ratio as the viewfinder band.
|
||||
// Library export keeps the on-screen composition: plain frames export
|
||||
// the photo as seen (own aspect), polaroid/wall keep their ratio crop.
|
||||
{
|
||||
aspect: aspectRatio === 'full' ? undefined : aspectRatio,
|
||||
aspect: libraryAspect,
|
||||
watermark: wmForExport(),
|
||||
}
|
||||
)
|
||||
@@ -804,9 +811,10 @@ export default function App() {
|
||||
selectedFrame,
|
||||
useGeotag,
|
||||
gpsInfo,
|
||||
// Library export follows the same composition ratio as the viewfinder band.
|
||||
// Library export keeps the on-screen composition: plain frames export
|
||||
// the photo as seen (own aspect), polaroid/wall keep their ratio crop.
|
||||
{
|
||||
aspect: aspectRatio === 'full' ? undefined : aspectRatio,
|
||||
aspect: libraryAspect,
|
||||
watermark: wmForExport(),
|
||||
// Pinch/drag inside a polaroid card window or wall-frame opening:
|
||||
// save the same crop the preview showed (null = centered 1x).
|
||||
|
||||
@@ -216,6 +216,7 @@ const Viewfinder = forwardRef<ViewfinderHandle, ViewfinderProps>(function Viewfi
|
||||
// every consumer below degrades to the old fullscreen behavior untouched.
|
||||
const ratioWH = aspectRatio === 'full' ? null : ASPECT_RATIO_W_H[aspectRatio];
|
||||
const regionBand =
|
||||
mode === 'camera' &&
|
||||
ratioWH !== null &&
|
||||
(selectedFrame === 'none' || selectedFrame === 'classic-white' || selectedFrame === 'cinematic');
|
||||
const region = useMemo(() => {
|
||||
@@ -936,6 +937,17 @@ const Viewfinder = forwardRef<ViewfinderHandle, ViewfinderProps>(function Viewfi
|
||||
const dh = h * s;
|
||||
return { dx: (vw - dw) / 2, dy: (vh - dh) / 2, dw, dh };
|
||||
}, [skiaImage, vw, vh]);
|
||||
// Photo display rect + draw fit in the plain library viewer: the full photo
|
||||
// is contain-fitted to the screen (fill into its own aspect rect — no
|
||||
// distortion, identical to the old fullscreen contain). The ratio band only
|
||||
// shapes the CAMERA composition; a library export is the photo as framed.
|
||||
const dispRect = regionBand
|
||||
? { dx: region.x, dy: region.y, dw: region.w, dh: region.h }
|
||||
: imageFitRect;
|
||||
const dispFit: 'cover' | 'fill' = regionBand ? 'cover' : 'fill';
|
||||
// Rect the frame border / cinematic bars / grain hug: the ratio band on the
|
||||
// camera, the contain rect of the loaded library photo, fullscreen otherwise.
|
||||
const frameRect = mode === 'library' && dispRect ? dispRect : region;
|
||||
// Polaroid print geometry (JS/overlay space) for the CURRENT mode. The card
|
||||
// always fills/holds to the screen container; the photo WINDOW keeps the
|
||||
// *composition* aspect: with a ratio active that ratio (window content is
|
||||
@@ -1323,10 +1335,10 @@ const Viewfinder = forwardRef<ViewfinderHandle, ViewfinderProps>(function Viewfi
|
||||
};
|
||||
})();
|
||||
|
||||
// Border/bars scale with the composition region so framed exports stay
|
||||
// proportional to the cropped photo (region == fullscreen when no ratio).
|
||||
const borderWidth = Math.min(region.w, region.h) * 0.05;
|
||||
const barHeight = region.h * 0.12;
|
||||
// Border/bars scale with the visible photo rect so a framed export stays
|
||||
// proportional to the picture (band on the camera, contain rect in library).
|
||||
const borderWidth = Math.min(frameRect.w, frameRect.h) * 0.05;
|
||||
const barHeight = frameRect.h * 0.12;
|
||||
|
||||
const renderFrameOverlay = () => {
|
||||
if (selectedFrame === 'none') return null;
|
||||
@@ -1395,24 +1407,24 @@ const Viewfinder = forwardRef<ViewfinderHandle, ViewfinderProps>(function Viewfi
|
||||
}
|
||||
|
||||
if (selectedFrame === 'classic-white') {
|
||||
// Border drawn on the composition region (region == fullscreen when no
|
||||
// ratio band), so it always sits at the photo's edge.
|
||||
// Border drawn on the visible photo rect (frameRect), so it always sits
|
||||
// at the picture's edge — including the letterboxed library viewer.
|
||||
return (
|
||||
<Group color="white">
|
||||
<Rect x={region.x} y={region.y} width={region.w} height={borderWidth} />
|
||||
<Rect x={region.x} y={region.y + region.h - borderWidth} width={region.w} height={borderWidth} />
|
||||
<Rect x={region.x} y={region.y} width={borderWidth} height={region.h} />
|
||||
<Rect x={region.x + region.w - borderWidth} y={region.y} width={borderWidth} height={region.h} />
|
||||
<Rect x={frameRect.x} y={frameRect.y} width={frameRect.w} height={borderWidth} />
|
||||
<Rect x={frameRect.x} y={frameRect.y + frameRect.h - borderWidth} width={frameRect.w} height={borderWidth} />
|
||||
<Rect x={frameRect.x} y={frameRect.y} width={borderWidth} height={frameRect.h} />
|
||||
<Rect x={frameRect.x + frameRect.w - borderWidth} y={frameRect.y} width={borderWidth} height={frameRect.h} />
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
|
||||
if (selectedFrame === 'cinematic') {
|
||||
// Letterbox bars hug the composition region's top/bottom edges.
|
||||
// Letterbox bars hug the visible photo rect's top/bottom edges.
|
||||
return (
|
||||
<Group color="black">
|
||||
<Rect x={region.x} y={region.y} width={region.w} height={barHeight} />
|
||||
<Rect x={region.x} y={region.y + region.h - barHeight} width={region.w} height={barHeight} />
|
||||
<Rect x={frameRect.x} y={frameRect.y} width={frameRect.w} height={barHeight} />
|
||||
<Rect x={frameRect.x} y={frameRect.y + frameRect.h - barHeight} width={frameRect.w} height={barHeight} />
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
@@ -1706,14 +1718,6 @@ const Viewfinder = forwardRef<ViewfinderHandle, ViewfinderProps>(function Viewfi
|
||||
toneParams[0] !== 0 || toneParams[1] !== 0 || toneParams[2] !== 0 || toneParams[3] !== 0;
|
||||
const cinemaOn = cinemaEffect != null && !!cinemaParams;
|
||||
const useShaderPass = !!imageFitRect && ((toneEffect != null && toneOn) || cinemaOn);
|
||||
// Photo display rect + draw fit in the plain library viewer: with a ratio
|
||||
// band the photo is center-cropped (cover) into the composition region;
|
||||
// otherwise the full photo is contain-fitted to the screen (fill into its
|
||||
// own aspect rect — no distortion, identical to the old fullscreen contain).
|
||||
const dispRect = regionBand
|
||||
? { dx: region.x, dy: region.y, dw: region.w, dh: region.h }
|
||||
: imageFitRect;
|
||||
const dispFit: 'cover' | 'fill' = regionBand ? 'cover' : 'fill';
|
||||
|
||||
// RETRO POLAROID (library): the whole picture is contain-fitted into the
|
||||
// card's photo window — nothing is masked or cropped, and the card is
|
||||
@@ -1943,9 +1947,9 @@ const Viewfinder = forwardRef<ViewfinderHandle, ViewfinderProps>(function Viewfi
|
||||
</Group>
|
||||
{grainOpacity > 0 && noiseEffect && (
|
||||
<Group blendMode="overlay">
|
||||
{/* Grain covers the whole photo area — the composition region
|
||||
under a ratio band, the full screen otherwise. */}
|
||||
<Rect x={region.x} y={region.y} width={region.w} height={region.h} opacity={grainOpacity}>
|
||||
{/* Grain covers the whole photo area — the contain rect of the
|
||||
library photo, the ratio band on the camera. */}
|
||||
<Rect x={frameRect.x} y={frameRect.y} width={frameRect.w} height={frameRect.h} opacity={grainOpacity}>
|
||||
<Shader source={noiseEffect} />
|
||||
</Rect>
|
||||
</Group>
|
||||
|
||||
Reference in New Issue
Block a user