feat(frame): CROP ratios in the library editor, and the framed-photo fixes
CROP chip on the FRAME tab for the library's plain frames: NONE, FREE (drag the box) and the fixed ratios 1:1, 2:3, 3:2, 3:4, 4:3, 16:9. The preview draws the keep-rectangle over the photo and the export honours it pixel-for-pixel, pinching and dragging inside the band to pick the framing. - Viewfinder: build frameRect from the normalised rect so the Skia canvas never sees undefined width/height (nothing to commit until now), keep the watermark drag target across the WATERMARK tab so a zoomed photo no longer resets, and derive the crop band + export rect from the photo fit rect. - exportEngine: crop by fraction rect (or the ratio fallback) before the frame is composited. - Leaving a plain frame clears the crop, and the ratio strip closes with the CROP chip it belongs to.
This commit is contained in:
@@ -30,6 +30,30 @@ export const ASPECT_RATIO_W_H: Record<Exclude<AspectRatio, 'full'>, number> = {
|
||||
'3:2': 2 / 3,
|
||||
};
|
||||
|
||||
// FRAME-tab CROP. Ratio convention is w:h (so 2:3 is an upright crop, 16:9 a
|
||||
// wide one); 'free' is a user-dragged rectangle instead of a fixed shape.
|
||||
export type CropRatio = 'none' | 'free' | '1:1' | '2:3' | '3:2' | '3:4' | '4:3' | '16:9';
|
||||
// Keep-rectangle as 0..1 fractions of the (post-rotation) source photo.
|
||||
export interface CropRect {
|
||||
x: number;
|
||||
y: number;
|
||||
w: number;
|
||||
h: number;
|
||||
}
|
||||
// w/h of the kept area for each fixed crop choice.
|
||||
export const CROP_W_H: Record<Exclude<CropRatio, 'none' | 'free'>, number> = {
|
||||
'1:1': 1,
|
||||
'2:3': 2 / 3,
|
||||
'3:2': 3 / 2,
|
||||
'3:4': 3 / 4,
|
||||
'4:3': 4 / 3,
|
||||
'16:9': 16 / 9,
|
||||
};
|
||||
// FREE crop starts as a visible inset rectangle the user can immediately grab.
|
||||
export const DEFAULT_CROP_RECT: CropRect = { x: 0.1, y: 0.1, w: 0.8, h: 0.8 };
|
||||
// Smallest FREE-crop side, in source fractions.
|
||||
export const MIN_CROP_FRAC = 0.08;
|
||||
|
||||
// Cinematic seasonal atmosphere grade. Not a fake re-light: it reads the
|
||||
// photo's EXISTING exposure — warm tint + soft glow on areas already lit,
|
||||
// cool tint in shade, plus a seasonal atmospheric haze/fog veil.
|
||||
|
||||
Reference in New Issue
Block a user