Let the wall-frame photo be dragged inside its opening
This commit is contained in:
@@ -922,6 +922,10 @@ const Viewfinder = forwardRef<ViewfinderHandle, ViewfinderProps>(function Viewfi
|
||||
const [libZoom, setLibZoom] = useState({ s: 1, tx: 0, ty: 0 });
|
||||
const pinchRef = useRef<{ d: number; s: number; tx: number; ty: number; fx: number; fy: number } | null>(null);
|
||||
const pinchUsedRef = useRef(false);
|
||||
// Framed-window drag: anchor at touch-down (finger + transform origin), so a
|
||||
// move never accumulates rounding across a slow drag.
|
||||
const panRef = useRef<{ x: number; y: number; tx: number; ty: number } | null>(null);
|
||||
const panUsedRef = useRef(false);
|
||||
const lastTapRef = useRef<{ x: number; y: number; t: number } | null>(null);
|
||||
const clampZoom = (s: number) => Math.max(1, Math.min(6, s));
|
||||
// Contain-fit rect of the loaded photo in canvas coordinates (image is
|
||||
@@ -1170,11 +1174,16 @@ const Viewfinder = forwardRef<ViewfinderHandle, ViewfinderProps>(function Viewfi
|
||||
y <= box.y + box.h + 8;
|
||||
// Library framed (polaroid/wall) returns reuse the SAME responder handlers as
|
||||
// plain library (see the framed JSX below): single-finger drags place/move
|
||||
// the text watermark while armed, pinch + double-tap repositions the photo
|
||||
// inside the frame window (watermark stays armed when zoomed so detail can
|
||||
// be inspected without accidentally moving text — matching plain library).
|
||||
// the text watermark while armed, and otherwise DRAG the photo inside the
|
||||
// framed window (same cover clamp as pinch, so the opening never shows the
|
||||
// card/mat through it); pinch + double-tap zoom that same repositioning.
|
||||
// The pan only bites once the photo is zoomed past 1x: at the cover scale it
|
||||
// already fills the opening exactly, so the clamp has nowhere to move.
|
||||
const onLibTouchStart = (e: any) => {
|
||||
const ts = e.nativeEvent.touches;
|
||||
panRef.current =
|
||||
ts.length === 1 ? { x: ts[0].locationX, y: ts[0].locationY, tx: libZoom.tx, ty: libZoom.ty } : null;
|
||||
panUsedRef.current = false;
|
||||
if (ts.length >= 2) {
|
||||
const [a, b] = ts;
|
||||
pinchUsedRef.current = true;
|
||||
@@ -1198,6 +1207,22 @@ const Viewfinder = forwardRef<ViewfinderHandle, ViewfinderProps>(function Viewfi
|
||||
placeWm(t.pageX ?? t.locationX, t.pageY ?? t.locationY);
|
||||
return;
|
||||
}
|
||||
// One finger, no pinch running: drag the photo inside the framed window
|
||||
// (polaroid card / wall-frame opening). Goes through the same clamp as
|
||||
// pinch, so the opening always stays covered by the picture.
|
||||
if (ts.length === 1 && !pinchRef.current && zoomWindowRect()) {
|
||||
const t = ts[0];
|
||||
const pan0 = panRef.current;
|
||||
if (pan0) {
|
||||
const dx = t.locationX - pan0.x;
|
||||
const dy = t.locationY - pan0.y;
|
||||
if (Math.abs(dx) > 6 || Math.abs(dy) > 6) panUsedRef.current = true;
|
||||
if (panUsedRef.current) {
|
||||
setLibZoom(clampZoomToWindow(libZoom.s, pan0.tx + dx, pan0.ty + dy));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
let p = pinchRef.current;
|
||||
if (ts.length >= 2 && !p) {
|
||||
// Responder grant fires once on the first finger; a second finger that
|
||||
@@ -1229,9 +1254,14 @@ const Viewfinder = forwardRef<ViewfinderHandle, ViewfinderProps>(function Viewfi
|
||||
};
|
||||
const onLibTouchEnd = (e: any) => {
|
||||
const wasPinch = pinchUsedRef.current;
|
||||
const wasPan = panUsedRef.current;
|
||||
pinchRef.current = null;
|
||||
pinchUsedRef.current = false;
|
||||
if (wasPinch) return; // a double-tap is always a single finger
|
||||
panRef.current = null;
|
||||
panUsedRef.current = false;
|
||||
// A drag is neither a tap nor the first half of a double-tap.
|
||||
if (wasPan) lastTapRef.current = null;
|
||||
if (wasPinch || wasPan) return; // a double-tap is always a single finger
|
||||
const x = e.nativeEvent.locationX;
|
||||
const y = e.nativeEvent.locationY;
|
||||
// Mark drawn but its editor CLOSED: a double-tap ON the mark re-opens the
|
||||
|
||||
Reference in New Issue
Block a user