Make flying away nice

This commit is contained in:
Dan Abramov
2024-11-02 02:52:35 +00:00
parent 58e261676b
commit d8c1354e96
+24 -3
View File
@@ -19,6 +19,7 @@ import {
import {Gesture} from 'react-native-gesture-handler' import {Gesture} from 'react-native-gesture-handler'
import PagerView from 'react-native-pager-view' import PagerView from 'react-native-pager-view'
import { import {
cancelAnimation,
interpolate, interpolate,
SharedValue, SharedValue,
useAnimatedReaction, useAnimatedReaction,
@@ -52,12 +53,14 @@ const SCREEN_HEIGHT = Dimensions.get('window').height
function ImageViewing({ function ImageViewing({
lightbox, lightbox,
openProgress, openProgress,
onFlyAway,
onRequestClose, onRequestClose,
onPressSave, onPressSave,
onPressShare, onPressShare,
}: { }: {
lightbox: Lightbox lightbox: Lightbox
openProgress: SharedValue<number> openProgress: SharedValue<number>
onFlyAway: () => void
onRequestClose: () => void onRequestClose: () => void
onPressSave: (uri: string) => void onPressSave: (uri: string) => void
onPressShare: (uri: string) => void onPressShare: (uri: string) => void
@@ -95,7 +98,7 @@ function ImageViewing({
}) })
const activeImageStyle = useAnimatedStyle(() => { const activeImageStyle = useAnimatedStyle(() => {
if (openProgress.value === 1) { if (openProgress.value === 1 || dismissSwipeTranslateY.value !== 0) {
return { return {
transform: [{translateY: dismissSwipeTranslateY.value}], transform: [{translateY: dismissSwipeTranslateY.value}],
} }
@@ -127,8 +130,11 @@ function ImageViewing({
.onEnd(e => { .onEnd(e => {
'worklet' 'worklet'
if (Math.abs(e.velocityY) > 1000) { if (Math.abs(e.velocityY) > 1000) {
dismissSwipeTranslateY.value = withDecay({velocity: e.velocityY}) dismissSwipeTranslateY.value = withDecay({
runOnJS(onRequestClose)() velocity: e.velocityY,
velocityFactor: 2,
deceleration: 1, // Danger! This relies on the reaction below stopping it.
})
} else { } else {
dismissSwipeTranslateY.value = withSpring(0, { dismissSwipeTranslateY.value = withSpring(0, {
stiffness: 700, stiffness: 700,
@@ -136,6 +142,16 @@ function ImageViewing({
}) })
} }
}) })
useAnimatedReaction(
() => Math.abs(dismissSwipeTranslateY.value) > SCREEN_HEIGHT,
(isOut, wasOut) => {
if (isOut && !wasOut) {
// Stop the animation from blocking the screen forever.
cancelAnimation(dismissSwipeTranslateY)
onFlyAway()
}
},
)
const onTap = useCallback(() => { const onTap = useCallback(() => {
setShowControls(show => !show) setShowControls(show => !show)
@@ -428,6 +444,11 @@ function ImageViewingRoot({
lightbox={activeLightbox} lightbox={activeLightbox}
openProgress={openProgress} openProgress={openProgress}
onRequestClose={onRequestClose} onRequestClose={onRequestClose}
onFlyAway={() => {
'worklet'
openProgress.value = 0
runOnJS(onRequestClose)()
}}
onPressSave={onPressSave} onPressSave={onPressSave}
onPressShare={onPressShare} onPressShare={onPressShare}
/> />