Animations play an important role in mobile apps by giving life into the process of interaction and are especially good for mobile apps that have to be developed with limited screen estate, while providing an informative and functional interface.
Commonly used method in building interactive animations in react native is by using Animated api,that covers our most of the animation use cases and scenarios such as duration-based animation or spring or decay animation and APIs for canceling animation or repeat and interpolation
Problem arises while using the core animated api is that animated Api uses the JS thread for the calculating the animated values and if the js thread is busy running a complex business logic then the frame drops can occur at massive rate that destroys the overall animation experience and interactions
Why Reanimated ?
Reanimated saves us from the frame drop hell in react native,reanimated solves this very problem, by allowing us to run animation natively on the UI thread and thus eliminating any kind of delays.
Version 2 of the package, or what came to be known as reanimated 2 in the community, provides us with a set of useful hooks and functions allowing us to write cleaner code, less boilerplate and using plain JavaScript instead of the library’s own functions compared to the first version.
More details about working of the package can be found in official doc
Lets dive deep into key concepts of reanimated 2
In part 1 of the article we will be looking at the important hooks that came along with the version 2 of reanimated and in the end we will be building a simple animation using the learned concepts
- Worklets
Worklets are simple javascript functions that run completely on UI thread,The only thing that is needed is for that function to have “worklet” directive at the top.. Each worklet function can be run either on the main React Native thread if you just call that function in your code, or you can execute it on the UI thread using runOnUI
function someWorklet(greeting) {
'worklet';
console.log(greeting, 'From the UI thread');
}function onPress() {
runOnUI(someWorklet)('Howdy');
}
2. Shared Values
Shared Values are among fundamental concepts behind Reanimated 2.0, similar to that of Animated.values from react natives animated Api.They serve a similar purpose of carrying “animateable” data, providing a notion of reactiveness, and driving animations.In order to create a Shared Value reference, you should use useSharedValue
hook.
import Animated, {
useSharedValue,
useAnimatedScrollHandler,
} from 'react-native-reanimated';function SomeComponent({ children }) {
const scrollOffset = useSharedValue(0);const scrollHandler = useAnimatedScrollHandler({
onScroll: (event) => {
scrollOffset.value = event.contentOffset.y;
},
});return (
<Animated.ScrollView onScroll={scrollHandler}>
{children}
</Animated.ScrollView>
);
}
From the example given above from the official docs we can see that ,the scroll handler is a worklet and runs the scroll event logic on the UI thread. and the Updates made in that worklets are synchronous.
3. useAnimatedStyle
Allows us to create an association between shared values and View properties,arguments for the hooks are updater(function)
and dependencies(array)
that returns Animated style — in order to connect the animated style hook result, you need to pass it as one of the style
properties to the Animated
version of the component (e.g. Animated.View
).
const App = () => {
const [state, setState] = useState(0);
const sv = useSharedValue(state);const style = useAnimatedStyle(() => {
return {
width: sv.value,
};
}, dependencies);
//...
return <></>;
};
4. useDerivedValue
Allows us for creating shared value reference that can change in response to updating of one or more other shared values.arguments for the hooks are updater(function)
and dependencies(array)
that returns a reference to a shared value initialized with the provided data. The reference is an object with .value
property, that can be accessed and modified from worklets, but also updated directly from the main JS thread.
import { Button } from 'react-native';
import { useSharedValue, useDerivedValue } from 'react-native-reanimated';function App() {
const progress = useSharedValue(0);
const width = useDerivedValue(() => {
return progress.value * 250;
});return (
<View>
<SomeComponent width={width} />
<Button onPress={() => (progress.value = Math.random())} />
</View>
);
}
Now lets implement a simple reanimated animation using the learned concepts
In the above example we used withRepeat hook to repeat an animation several time and which then changes the style of the view using the animated style hook that returns a new style object for new values and then we used a worklet to calculate the shape for the transformed object that runs completely on the UI thread that results the animation given below
Conclusion
That’s pretty much everything about the basics of the reanimated from my perspective and i will keep exploring on this awesome library done by softwaremansion
More details about animation hooks provided by reanimated will be covered in the Part 2 of this article with some awesome cool animations that run on UI thread