[EN] React Native Flip Card Animation

Öztürk Şirin
3 min readMar 29, 2024

--

We will create a flip card design using React Native Expo and reanimated.

What is Reanimated?

Reanimated is a React Native library that allows creating seamless animations and interactions that work on the UI thread.

First, we install the library in our project.

npx create-expo-app FlipCardExpo && cd FlipCardExpo
npx expo install react-native-reanimated

Then we can start writing our code

import React from "react";
import { StyleSheet, Text, View, Pressable, Dimensions } from "react-native";
import Animated, {
interpolate,
useAnimatedStyle,
useSharedValue,
withTiming,
} from "react-native-reanimated";

After making our imports, we first create a rotate value using the useSharedValue hook provided by the reanimated library, this value tracks the rotation of the card.

We define two different animation styles using the useAnimatedStyle hook. We will use these styles to rotate the front and back of the card according to the rotate value.

const rotate = useSharedValue(0);

const frontAnimatedStyle = useAnimatedStyle(() => {
const rotateValue = interpolate(rotate.value, [0, 1], [0, 180]);
return {
transform: [
{
rotateY: withTiming(`${rotateValue}deg`, { duration: 500 }),
},
],
};
});

const backAnimatedStyle = useAnimatedStyle(() => {
const rotateValue = interpolate(rotate.value, [0, 1], [180, 360]);
return {
transform: [
{
rotateY: withTiming(`${rotateValue}deg`, { duration: 500 }),
},
],
};
});

const handleFlip = () => {
rotate.value = rotate.value ? 0 : 1;
};

The handleFlip function reverses the state of the board. This switches between the interpolations used to rotate the front and back faces of the board.

What is Interpolate?

Interpolation is a mathematical term that calculates things like the entry and exit point of animations, or their transformation (mapping) to another value. Interpolation is often used to improve the smoothness of animations.

What is withTiming ?

`withTiming` is a function used in the Reanimated library and is used to perform an animation movement in a specific time interval. This function allows animations to run at a specific speed or timing function within a certain period of time.

return (
<View style={styles.container}>
<Pressable
onPress={() => handleFlip()}
style={[styles.cardFrontBody, styles.card]}>
<Animated.View
style={[styles.cardFrontBody, styles.card, frontAnimatedStyle]}>
<Text style={styles.text}>Front</Text>
</Animated.View>
<Animated.View
style={[styles.cardBackBody, styles.card, backAnimatedStyle]}>
<Text style={styles.text}>Back</Text>
</Animated.View>
</Pressable>
</View>
);

This component represents the front and back of a card. When the user taps on the card, a rotation animation occurs between the front and back sides of the card.

The widget is nested inside a <View> component and contains a <Pressable> component that triggers the handleFlip function when the card is tapped.

Two <Animated.View> components are used to represent the front and back sides of the card. The frontAnimatedStyle and backAnimatedStyle styles allow switching between the front and back faces depending on the rotation of the card.

const wWidth = Dimensions.get("window").width;
const wHeight = Dimensions.get("window").height;

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
text: {
color: "white",
fontSize: 24,
fontWeight: "bold",
},

cardFrontBody: {
justifyContent: "center",
alignItems: "center",
backgroundColor: "#64676e",
width: wWidth * 0.8,
height: wHeight * 0.6,
borderRadius: 10,

cardArea: {
justifyContent: "center",
alignItems: "center",
flex: 1,
},
card: {
position: "absolute",
backfaceVisibility: "hidden",
},
cardBackBody: {
justifyContent: "center",
alignItems: "center",
backgroundColor: "#64676e",
width: wWidth * 0.8,
height: wHeight * 0.5,
borderRadius: 10,

});

You can style it as you like and use flip card with this function by changing the contents.
All code is available on GitHub.

Source:Taken by author
Source:Taken by author

--

--