[Lightbox] Fix jump when zooming out on iOS (#6633)

This commit is contained in:
dan
2024-11-22 13:34:16 +00:00
committed by GitHub
parent 5028753367
commit a0acd514ab
@@ -16,9 +16,11 @@ import {
import Animated, { import Animated, {
runOnJS, runOnJS,
SharedValue, SharedValue,
useAnimatedProps,
useAnimatedReaction, useAnimatedReaction,
useAnimatedRef, useAnimatedRef,
useAnimatedStyle, useAnimatedStyle,
useSharedValue,
} from 'react-native-reanimated' } from 'react-native-reanimated'
import {useSafeAreaFrame} from 'react-native-safe-area-context' import {useSafeAreaFrame} from 'react-native-safe-area-context'
import {Image} from 'expo-image' import {Image} from 'expo-image'
@@ -75,6 +77,7 @@ const ImageItem = ({
}: Props) => { }: Props) => {
const scrollViewRef = useAnimatedRef<Animated.ScrollView>() const scrollViewRef = useAnimatedRef<Animated.ScrollView>()
const [scaled, setScaled] = useState(false) const [scaled, setScaled] = useState(false)
const isDragging = useSharedValue(false)
const screenSizeDelayedForJSThreadOnly = useSafeAreaFrame() const screenSizeDelayedForJSThreadOnly = useSafeAreaFrame()
const maxZoomScale = Math.max( const maxZoomScale = Math.max(
MIN_SCREEN_ZOOM, MIN_SCREEN_ZOOM,
@@ -86,11 +89,20 @@ const ImageItem = ({
const scrollHandler = useAnimatedScrollHandler({ const scrollHandler = useAnimatedScrollHandler({
onScroll(e) { onScroll(e) {
'worklet'
const nextIsScaled = e.zoomScale > 1 const nextIsScaled = e.zoomScale > 1
if (scaled !== nextIsScaled) { if (scaled !== nextIsScaled) {
runOnJS(handleZoom)(nextIsScaled) runOnJS(handleZoom)(nextIsScaled)
} }
}, },
onBeginDrag() {
'worklet'
isDragging.value = true
},
onEndDrag() {
'worklet'
isDragging.value = false
},
}) })
function handleZoom(nextIsScaled: boolean) { function handleZoom(nextIsScaled: boolean) {
@@ -199,6 +211,11 @@ const ImageItem = ({
const borderRadius = const borderRadius =
type === 'circle-avi' ? 1e5 : type === 'rect-avi' ? 20 : 0 type === 'circle-avi' ? 1e5 : type === 'rect-avi' ? 20 : 0
const scrollViewProps = useAnimatedProps(() => ({
// Don't allow bounce at 1:1 rest so it can be swiped away.
bounces: scaled || isDragging.value,
}))
return ( return (
<GestureDetector gesture={composedGesture}> <GestureDetector gesture={composedGesture}>
<Animated.ScrollView <Animated.ScrollView
@@ -210,8 +227,7 @@ const ImageItem = ({
maximumZoomScale={maxZoomScale} maximumZoomScale={maxZoomScale}
onScroll={scrollHandler} onScroll={scrollHandler}
style={containerStyle} style={containerStyle}
bounces={scaled} animatedProps={scrollViewProps}
bouncesZoom={true}
centerContent> centerContent>
{showLoader && ( {showLoader && (
<ActivityIndicator size="small" color="#FFF" style={styles.loading} /> <ActivityIndicator size="small" color="#FFF" style={styles.loading} />