diff options
author | Paul Frazee <pfrazee@gmail.com> | 2024-11-23 16:20:24 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-23 16:20:24 -0800 |
commit | 32bf8122e8c8a0fbadd53b8a015cfbc9014519a2 (patch) | |
tree | 55bd24596e6fadadbf4326b26e3d14e418c5c7bb /src/view/com/lightbox/ImageViewing/index.tsx | |
parent | 523d1f01a51c0e85e49916fb42b204f7004ffac1 (diff) | |
parent | b4d07c4112b9a62b5380948051aa4a7fd391a2d4 (diff) | |
download | voidsky-32bf8122e8c8a0fbadd53b8a015cfbc9014519a2.tar.zst |
Merge branch 'main' into main
Diffstat (limited to 'src/view/com/lightbox/ImageViewing/index.tsx')
-rw-r--r-- | src/view/com/lightbox/ImageViewing/index.tsx | 95 |
1 files changed, 58 insertions, 37 deletions
diff --git a/src/view/com/lightbox/ImageViewing/index.tsx b/src/view/com/lightbox/ImageViewing/index.tsx index ab8306b36..4ba056eb0 100644 --- a/src/view/com/lightbox/ImageViewing/index.tsx +++ b/src/view/com/lightbox/ImageViewing/index.tsx @@ -32,6 +32,7 @@ import Animated, { useSharedValue, withDecay, withSpring, + WithSpringConfig, } from 'react-native-reanimated' import { Edge, @@ -62,8 +63,18 @@ const EDGES = ? (['top', 'bottom', 'left', 'right'] satisfies Edge[]) : (['left', 'right'] satisfies Edge[]) // iOS, so no top/bottom safe area -const SLOW_SPRING = {stiffness: 120} -const FAST_SPRING = {stiffness: 700} +const SLOW_SPRING: WithSpringConfig = { + mass: isIOS ? 1.25 : 0.75, + damping: 300, + stiffness: 800, + restDisplacementThreshold: 0.01, +} +const FAST_SPRING: WithSpringConfig = { + mass: isIOS ? 1.25 : 0.75, + damping: 150, + stiffness: 900, + restDisplacementThreshold: 0.01, +} export default function ImageViewRoot({ lightbox: nextLightbox, @@ -98,18 +109,22 @@ export default function ImageViewRoot({ // https://github.com/software-mansion/react-native-reanimated/issues/6677 requestAnimationFrame(() => { - openProgress.value = canAnimate ? withClampedSpring(1, SLOW_SPRING) : 1 + openProgress.set(() => + canAnimate ? withClampedSpring(1, SLOW_SPRING) : 1, + ) }) return () => { // https://github.com/software-mansion/react-native-reanimated/issues/6677 requestAnimationFrame(() => { - openProgress.value = canAnimate ? withClampedSpring(0, SLOW_SPRING) : 0 + openProgress.set(() => + canAnimate ? withClampedSpring(0, SLOW_SPRING) : 0, + ) }) } }, [nextLightbox, openProgress]) useAnimatedReaction( - () => openProgress.value === 0, + () => openProgress.get() === 0, (isGone, wasGone) => { if (isGone && !wasGone) { runOnJS(setActiveLightbox)(null) @@ -119,7 +134,7 @@ export default function ImageViewRoot({ const onFlyAway = React.useCallback(() => { 'worklet' - openProgress.value = 0 + openProgress.set(0) runOnJS(onRequestClose)() }, [onRequestClose, openProgress]) @@ -176,7 +191,7 @@ function ImageView({ const isFlyingAway = useSharedValue(false) const containerStyle = useAnimatedStyle(() => { - if (openProgress.value < 1 || isFlyingAway.value) { + if (openProgress.get() < 1 || isFlyingAway.get()) { return {pointerEvents: 'none'} } return {pointerEvents: 'auto'} @@ -185,11 +200,12 @@ function ImageView({ const backdropStyle = useAnimatedStyle(() => { const screenSize = measure(safeAreaRef) let opacity = 1 - if (openProgress.value < 1) { - opacity = Math.sqrt(openProgress.value) + const openProgressValue = openProgress.get() + if (openProgressValue < 1) { + opacity = Math.sqrt(openProgressValue) } else if (screenSize) { const dragProgress = Math.min( - Math.abs(dismissSwipeTranslateY.value) / (screenSize.height / 2), + Math.abs(dismissSwipeTranslateY.get()) / (screenSize.height / 2), 1, ) opacity -= dragProgress @@ -201,11 +217,11 @@ function ImageView({ }) const animatedHeaderStyle = useAnimatedStyle(() => { - const show = showControls && dismissSwipeTranslateY.value === 0 + const show = showControls && dismissSwipeTranslateY.get() === 0 return { pointerEvents: show ? 'box-none' : 'none', opacity: withClampedSpring( - show && openProgress.value === 1 ? 1 : 0, + show && openProgress.get() === 1 ? 1 : 0, FAST_SPRING, ), transform: [ @@ -216,12 +232,12 @@ function ImageView({ } }) const animatedFooterStyle = useAnimatedStyle(() => { - const show = showControls && dismissSwipeTranslateY.value === 0 + const show = showControls && dismissSwipeTranslateY.get() === 0 return { flexGrow: 1, pointerEvents: show ? 'box-none' : 'none', opacity: withClampedSpring( - show && openProgress.value === 1 ? 1 : 0, + show && openProgress.get() === 1 ? 1 : 0, FAST_SPRING, ), transform: [ @@ -248,7 +264,7 @@ function ImageView({ const screenSize = measure(safeAreaRef) return ( !screenSize || - Math.abs(dismissSwipeTranslateY.value) > screenSize.height + Math.abs(dismissSwipeTranslateY.get()) > screenSize.height ) }, (isOut, wasOut) => { @@ -386,10 +402,11 @@ function LightboxImage({ const transforms = useDerivedValue(() => { 'worklet' const safeArea = measureSafeArea() + const openProgressValue = openProgress.get() const dismissTranslateY = - isActive && openProgress.value === 1 ? dismissSwipeTranslateY.value : 0 + isActive && openProgressValue === 1 ? dismissSwipeTranslateY.get() : 0 - if (openProgress.value === 0 && isFlyingAway.value) { + if (openProgressValue === 0 && isFlyingAway.get()) { return { isHidden: true, isResting: false, @@ -399,9 +416,9 @@ function LightboxImage({ } } - if (isActive && thumbRect && imageAspect && openProgress.value < 1) { + if (isActive && thumbRect && imageAspect && openProgressValue < 1) { return interpolateTransform( - openProgress.value, + openProgressValue, thumbRect, safeArea, imageAspect, @@ -423,33 +440,37 @@ function LightboxImage({ .maxPointers(1) .onUpdate(e => { 'worklet' - if (openProgress.value !== 1 || isFlyingAway.value) { + if (openProgress.get() !== 1 || isFlyingAway.get()) { return } - dismissSwipeTranslateY.value = e.translationY + dismissSwipeTranslateY.set(e.translationY) }) .onEnd(e => { 'worklet' - if (openProgress.value !== 1 || isFlyingAway.value) { + if (openProgress.get() !== 1 || isFlyingAway.get()) { return } - if (Math.abs(e.velocityY) > 1000) { - isFlyingAway.value = true - if (dismissSwipeTranslateY.value === 0) { + if (Math.abs(e.velocityY) > 200) { + isFlyingAway.set(true) + if (dismissSwipeTranslateY.get() === 0) { // HACK: If the initial value is 0, withDecay() animation doesn't start. // This is a bug in Reanimated, but for now we'll work around it like this. - dismissSwipeTranslateY.value = 1 + dismissSwipeTranslateY.set(1) } - dismissSwipeTranslateY.value = withDecay({ - velocity: e.velocityY, - velocityFactor: Math.max(3000 / Math.abs(e.velocityY), 1), // Speed up if it's too slow. - deceleration: 1, // Danger! This relies on the reaction below stopping it. - }) + dismissSwipeTranslateY.set(() => + withDecay({ + velocity: e.velocityY, + velocityFactor: Math.max(3500 / Math.abs(e.velocityY), 1), // Speed up if it's too slow. + deceleration: 1, // Danger! This relies on the reaction below stopping it. + }), + ) } else { - dismissSwipeTranslateY.value = withSpring(0, { - stiffness: 700, - damping: 50, - }) + dismissSwipeTranslateY.set(() => + withSpring(0, { + stiffness: 700, + damping: 50, + }), + ) } }) @@ -706,7 +727,7 @@ function interpolateTransform( } } -function withClampedSpring(value: any, {stiffness}: {stiffness: number}) { +function withClampedSpring(value: any, config: WithSpringConfig) { 'worklet' - return withSpring(value, {overshootClamping: true, stiffness}) + return withSpring(value, {...config, overshootClamping: true}) } |