Gate pinch zoom behind an existing zoom
A two-finger pinch only changes scale once the photo is already zoomed in; at 100% the gesture is inert, so the paging strip keeps behaving like a plain gallery. The responder is now held for the whole pinch so the paging ScrollView cannot steal it mid-gesture.
This commit is contained in:
@@ -6,6 +6,8 @@ import { Animated, PanResponder } from 'react-native';
|
||||
// While zoomed in, responder termination is refused so the parent ScrollView
|
||||
// cannot steal the gesture — the photo pans instead of paging; swiping to the
|
||||
// next photo resumes after zooming back out (double tap or pinch below 1.15).
|
||||
// Two-finger pinch only zooms once the photo is already zoomed in: at 100% the
|
||||
// pinch stays inert, so the paging strip still behaves like a plain gallery.
|
||||
//
|
||||
// ponytail: pinch zooms around the image center, not the finger midpoint;
|
||||
// focal zoom needs per-touch location math against the image's screen rect.
|
||||
@@ -99,7 +101,8 @@ export default function ZoomableImage({ uri, width }: ZoomableImageProps) {
|
||||
onMoveShouldSetPanResponder: () => true,
|
||||
// Page the strip while zoom is off; once zoomed (or mid-pinch) the
|
||||
// image keeps the gesture for panning/zooming itself.
|
||||
onPanResponderTerminationRequest: () => st.scale <= 1.001,
|
||||
onPanResponderTerminationRequest: () =>
|
||||
st.scale <= 1.001 && st.pinchStart === null,
|
||||
onPanResponderGrant: () => {
|
||||
st.grantAt = Date.now();
|
||||
st.moved = false;
|
||||
@@ -113,10 +116,13 @@ export default function ZoomableImage({ uri, width }: ZoomableImageProps) {
|
||||
const b = touches[1];
|
||||
const dist = Math.hypot(a.pageX - b.pageX, a.pageY - b.pageY);
|
||||
if (!st.pinchStart) st.pinchStart = { scale: st.scale, dist: dist || 1 };
|
||||
const next = Math.max(
|
||||
1,
|
||||
Math.min(MAX_SCALE, st.pinchStart.scale * (dist / st.pinchStart.dist))
|
||||
);
|
||||
const next =
|
||||
st.pinchStart.scale > 1.001
|
||||
? Math.max(
|
||||
1,
|
||||
Math.min(MAX_SCALE, st.pinchStart.scale * (dist / st.pinchStart.dist))
|
||||
)
|
||||
: 1;
|
||||
st.scale = next;
|
||||
if (next <= 1.001) {
|
||||
st.tx = 0;
|
||||
|
||||
Reference in New Issue
Block a user