links: React Native MOC


How to use diffclamp in reanimated 2

Reanimated 2 comes with a feature called "worklet", any function marked as worklet will run on native thread. Here’s the code to calculate clamp

/**
* @summary Clamps a node with a lower and upper bound.
* @example
clamp(-1, 0, 100); // 0
clamp(1, 0, 100); // 1
clamp(101, 0, 100); // 100
* @worklet
*/
export const clamp = (
	value: number,
	lowerBound: number,
	upperBound: number,
) => {
	'worklet';
	return Math.min(Math.max(lowerBound, value), upperBound);
};

Now let’s assume you want to animate something based on scroll view, we can’t consider just event.contentOffset.y because it ranges from 0 to Height of the ScrollView or FlatList. if you are somewhere in the middle of the list and try to scroll back the header doesn’t appear. The reason would be animating based on offset, instead if you animate based on diffclamp which gives you a value between the min and max.

const scrollY = useSharedValue(0);
const handleScroll = useAnimatedScrollHandler<{ prevY?: number }>({
	onBeginDrag: (event, ctx) => {
		ctx.prevY = event.contentOffset.y;
	},
	onScroll: (event, ctx) => {
		let { y } = event.contentOffset;
		if (y < 0) {
			y = 0;
		}
		const dy = y - (ctx?.prevY ?? 0);
		scrollY.value = clamp(scrollY.value + dy, 0, 50);
		// the clamp function always returns a value between 0 and 50
		ctx.prevY = y;
	},
});

Now you can use this clamped scrollY value to interpolate the header or any other

const headerY = useAnimatedStyle(() => {
	const dy = interpolate(
		props.scrollY.value,
		[0, 50],
		[0, -50],
		Extrapolate.CLAMP,
	);
	
	return {
		transform: [
			{
				translateY: dy,
			},
		],
	};
});

Now as scrollY moves from 0 to 50, dy moves 0 to -50 that way header will be hidden


tags: reanimated, react-native, maths, diffclamp

source: