Overview

Legend Motion provides a set of components wrapping React Native Views.

import { Motion } from "@legendapp/motion"

This page includes live examples running through React Native Web.


Simple animations

We can simply set values on the animate prop.

<Motion.View
    animate={{
        x: value * 100
    }}
/>
value:
0

When any value in animate changes, it will automatically animate to the new values.


Transitions

Animations use a tween of 300ms by default, which you can change with the transition prop. The easiest way to do that is to set a Transition on all animations.

<Motion.View
    animate={{
        x: value * 100
    }}
    transition={{
        type: "spring",
        damping: 20,
        stiffness: 400
    }}
/>
value:
0

You can customize the animations even further by settings a Transition for each animated property. The default Transition will apply to all animated properties unless they have a specified transition.

<Motion.View
    animate={{
        x: value * 100,
        opacity: value ? 1 : 0.2,
        scale: value ? 1 : 0.5
    }}
    transition={{
        default: {
            type: "spring",
            damping: 20,
            stiffness: 300,
        },
        x: {
            type: "spring",
            damping: 20,
            stiffness: 1000
        },
        opacity: {
            type: "tween",
            duration: 1000
        }
    }}
/>
value:
0

Legend Motion supports two kinds of transitions, spring or timing. They pass straight through to Animated, so see the React Native docs on Timing and Spring for usage.

Transitions with durations are called timing in React Native's Animated and tween in Framer Motion, so Legend Motion has transition types of both names that do the same thing, to make it easy to match props with the rest of your codebase.


Animate on mount

When a component mounts, it will automatically be set to the animate value. But you want to animate it into position on mount, set initial as a starting point.

<Motion.View
    initial={{ x: 0 }}
    animate={{ x: 100 }}
/>

This example can be hard to see because it's a mount transition, so try refreshing the page to see it animate into place.


Automatic interpolating

For values that are strings or arrays, Legend Motion automatically interpolates between the values so you don't have to worry about it.

<Motion.View
    animate={{
        backgroundColor:
            value ? '#F81FEC' : '#59B0F8'
    }}
/>
value:
0

Text

With the automatic interpolating, it's easy to animate text colors as well as simple numbers like fontSize.

<Motion.Text
    animate={{
        color: value ? '#F81FEC' : '#59B0F8',
        fontSize: value ? 48 : 24
    }}
>
    Text
</Motion.Text>
Text
value:
0

Easing

React Native and Framer Motion use different naming, so Legend Motion supports either ease or easing props, which do the same thing.

It accepts the same easing functions as React Native's Animated along with some named functions to match usage of Framer Motion.

The supported values match most of Framer Motion's options:

linear, easeIn, easeOut, easeInOut, circIn, circOut, circInOut, backIn, backOut, backInOut'

See the React Native docs for more details.

<Motion.View
    animate={{ x: value * 100 }}
    transition={{
        type: 'timing',
        duration: 300,
        easing: 'linear'
    }}
/>
<Motion.View
    animate={{ x: value * 100 }}
    transition={{
        type: 'timing',
        duration: 300,
        easing: Easing.easing
    }}
/>
value:
0

Gestures

The whileTap prop animates to the target while the component is pressed, and the whileHover prop animates to the target while the component is hovered. Try pressing the box on the right to see it in action. whileHover is only supported in react-native-web.

These props require a Motion.Pressable ancestor, which is uses for tracking whether it is hovered or pressed. So you could have multiple inner elements that use the same hovered/pressed state.

<Motion.Pressable>
    <Motion.View
        whileHover={{ scale: 1.2 }}
        whileTap={{ y: 20 }}
        transition={{
            type: 'spring',
            damping: 20,
            stiffness: 300
        }}
    />
</Motion.Pressable>