derive final value

This commit is contained in:
Samuel Newman
2025-12-31 17:19:16 +02:00
parent 8930a226d6
commit ec7a9a8a34
+18 -15
View File
@@ -4,6 +4,7 @@ import Animated, {
runOnJS, runOnJS,
useAnimatedReaction, useAnimatedReaction,
useAnimatedStyle, useAnimatedStyle,
useDerivedValue,
withTiming, withTiming,
} from 'react-native-reanimated' } from 'react-native-reanimated'
import {useSafeAreaInsets} from 'react-native-safe-area-context' import {useSafeAreaInsets} from 'react-native-safe-area-context'
@@ -122,7 +123,18 @@ const MinimalHeader = memo(function MinimalHeader({
const [minimalHeaderHeight, setMinimalHeaderHeight] = useState(insets.top) const [minimalHeaderHeight, setMinimalHeaderHeight] = useState(insets.top)
const isScreenFocused = useIsFocused() const isScreenFocused = useIsFocused()
if (!ctx) throw new Error('MinimalHeader cannot be used on web') if (!ctx) throw new Error('MinimalHeader cannot be used on web')
const {scrollY, headerHeight} = ctx const {scrollY, clampedScrollY, headerHeight} = ctx
// similar to clampedScrollY but with a different threshold
// clamping outside of the animated style means it only updates
// when the it needs to, rather than on every scrollY change -sfn
const minHeaderTranslate = useDerivedValue(() => {
if (!_WORKLET || minimalHeaderHeight === 0) {
return 0
}
return Math.min(scrollY.get(), headerHeight - minimalHeaderHeight)
})
const animatedStyle = useAnimatedStyle(() => { const animatedStyle = useAnimatedStyle(() => {
// if we don't yet have the min header height in JS, hide // if we don't yet have the min header height in JS, hide
@@ -132,26 +144,17 @@ const MinimalHeader = memo(function MinimalHeader({
} }
} }
const scrollYValue = scrollY.get() const pastThreshold = clampedScrollY.get() >= 100
const pastThreshold = scrollYValue > 100
return { return {
opacity: pastThreshold opacity: pastThreshold
? withTiming(1, {duration: 75}) ? withTiming(1, {duration: 100})
: withTiming(0, {duration: 75}), : withTiming(0, {duration: 100}),
transform: [ transform: [{translateY: minHeaderTranslate.get()}],
{
translateY: Math.min(
scrollYValue,
headerHeight - minimalHeaderHeight,
),
},
],
} }
}) })
useAnimatedReaction( useAnimatedReaction(
() => scrollY.get() > 100, () => clampedScrollY.get() >= 100,
(value, prev) => { (value, prev) => {
if (prev !== value) { if (prev !== value) {
runOnJS(setVisible)(value) runOnJS(setVisible)(value)