Slider allows users to adjust a value or control a setting by sliding a handle along a track. It is commonly used to adjust settings such as volume, brightness, or in this case, the width of a box.
We use the useSharedValue
hook to store the offset of the slider handle, allowing for smooth animation during sliding.
const offset = useSharedValue(0);
This example is done using Pan gesture from react-native-gesture-handler
library. It adjusts the handle's position and width of the box accordingly to the current offset. The offset is a shared value and is updated during the onChange
event of the pan gesture.
const pan = Gesture.Pan().onChange((event) => {
offset.value =
Math.abs(offset.value) <= MAX_VALUE
? offset.value + event.changeX <= 0
? 0
: offset.value + event.changeX >= MAX_VALUE
? MAX_VALUE
: offset.value + event.changeX
: offset.value;
const newWidth = INITIAL_BOX_SIZE + offset.value;
boxWidth.value = newWidth;
});
The useAnimatedStyle
hook is used to create animated styles for both the box and the slider handle. This ensures that changes to the offset value result in smooth animations for both components.
const boxStyle = useAnimatedStyle(() => {
return {
width: INITIAL_BOX_SIZE + offset.value,
};
});
const sliderStyle = useAnimatedStyle(() => {
return {
transform: [{ translateX: offset.value }],
};
});
Leveraging animated props allows us to run them on the UI thread instead of the JS thread. To prevent unnecessary re-renders when the text displaying the current width of the box changes, we used the useAnimatedProps
hook.
Additionally, we opted for TextInput instead of Text because TextInput has a text
property that can be animated, whereas Text only has children.
This approach also enabled us to animate TextInput using shared values.
Slider const animatedProps = useAnimatedProps(() => {
return {
text: `Box width: ${Math.round(boxWidth.value)}`,
defaultValue: `Box width: ${boxWidth.value}`,
};
});