[Lightbox] Fix jump when zooming out on iOS (#6633)
This commit is contained in:
@@ -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} />
|
||||||
|
|||||||
Reference in New Issue
Block a user