Skip to main content

Usage

Timing animations

Timing animations transition from one value to another over a fixed duration with an easing curve.

<EaseView
animate={{ opacity: isVisible ? 1 : 0 }}
transition={{ type: 'timing', duration: 300, easing: 'easeOut' }}
/>
ParameterTypeDefaultDescription
durationnumber300Duration in milliseconds
easingEasingType'easeInOut'Easing curve or [x1, y1, x2, y2] cubic bezier
delaynumber0Delay in milliseconds before the animation starts
loopstring'repeat' restarts from the beginning, 'reverse' alternates

Available easing curves:

  • 'linear'
  • 'easeIn'
  • 'easeOut'
  • 'easeInOut'
  • [x1, y1, x2, y2]

Custom easing

<EaseView
animate={{ opacity: isVisible ? 1 : 0 }}
transition={{ type: 'timing', duration: 300, easing: [0.4, 0, 0.2, 1] }}
/>
<EaseView
animate={{ scale: active ? 1.2 : 1 }}
transition={{ type: 'timing', duration: 500, easing: [0.68, -0.55, 0.265, 1.55] }}
/>

Spring animations

<EaseView
animate={{ translateX: isOpen ? 200 : 0 }}
transition={{ type: 'spring', damping: 15, stiffness: 120, mass: 1 }}
/>
ParameterTypeDefaultDescription
dampingnumber15Friction — higher values reduce oscillation
stiffnessnumber120Spring constant — higher values mean faster animation
massnumber1Mass of the object — higher values mean slower, more momentum
delaynumber0Delay in milliseconds before the animation starts

Disabling animations

<EaseView
animate={{ opacity: isVisible ? 1 : 0 }}
transition={{ type: 'none' }}
/>

Per-property transitions

<EaseView
animate={{ opacity: visible ? 1 : 0, translateY: visible ? 0 : 30 }}
transition={{
opacity: { type: 'timing', duration: 150, easing: 'easeOut' },
transform: { type: 'spring', damping: 12, stiffness: 200 },
}}
/>

Available category keys:

KeyProperties
defaultFallback for categories not explicitly listed
transformtranslateX, translateY, scaleX, scaleY, rotate, rotateX, rotateY
opacityopacity
borderRadiusborderRadius
backgroundColorbackgroundColor
borderborderWidth, borderColor
shadowshadowOpacity, shadowRadius, shadowColor, shadowOffset, elevation

When no default key is provided, the library default (timing 300ms easeInOut) applies to all categories.

Android note: backgroundColor uses timing animation only. If a per-property map specifies type: 'spring' for backgroundColor, it falls back to timing 300ms.

Border radius

<EaseView
animate={{ borderRadius: expanded ? 0 : 16 }}
transition={{ type: 'timing', duration: 300 }}
style={styles.card}
>
<Image source={heroImage} style={styles.image} />
<Text>Content is clipped to rounded corners</Text>
</EaseView>

When borderRadius is in animate, any borderRadius in style is automatically stripped to avoid conflicts.

Background color

<EaseView
animate={{ backgroundColor: isActive ? '#3B82F6' : '#E5E7EB' }}
transition={{ type: 'timing', duration: 300 }}
style={styles.card}
>
<Text>Tap to change color</Text>
</EaseView>

On Android, background color uses timing animation only. On iOS, it supports both timing and spring transitions.

Border

<EaseView
animate={{
borderWidth: selected ? 3 : 0,
borderColor: selected ? '#3B82F6' : '#E5E7EB',
}}
transition={{ border: { type: 'spring', damping: 15, stiffness: 120 } }}
style={styles.card}
/>

Shadow / Elevation

Shadow properties are iOS-only. On Android, use elevation for material shadows.

<EaseView
animate={{
shadowOpacity: active ? 0.4 : 0,
shadowRadius: active ? 16 : 0,
shadowOffset: active ? { width: 0, height: 8 } : { width: 0, height: 0 },
elevation: active ? 12 : 0,
}}
transition={{ shadow: { type: 'spring', damping: 15, stiffness: 120 } }}
style={{ shadowColor: '#000', backgroundColor: '#fff', borderRadius: 16 }}
/>

Animatable properties

<EaseView
animate={{
opacity: 1,
translateX: 0,
translateY: 0,
scale: 1,
scaleX: 1,
scaleY: 1,
rotate: 0,
rotateX: 0,
rotateY: 0,
borderRadius: 0,
backgroundColor: 'transparent',
borderWidth: 0,
borderColor: 'black',
shadowOpacity: 0, // iOS only
shadowRadius: 0, // iOS only
shadowColor: 'black', // iOS only
shadowOffset: { width: 0, height: 0 }, // iOS only
elevation: 0, // Android only
}}
/>

scale is shorthand for scaleX and scaleY.

Looping animations

<EaseView
initialAnimate={{ opacity: 0.3 }}
animate={{ opacity: 1 }}
transition={{ type: 'timing', duration: 1000, easing: 'easeInOut', loop: 'reverse' }}
/>

Loop requires initialAnimate to define the starting value. Spring animations do not support looping.

Enter animations

<EaseView
initialAnimate={{ opacity: 0, translateY: 20 }}
animate={{ opacity: 1, translateY: 0 }}
transition={{ type: 'spring', damping: 15, stiffness: 120, mass: 1 }}
/>

Delay

{items.map((item, i) => (
<EaseView
key={item.id}
initialAnimate={{ opacity: 0, translateY: 20 }}
animate={{ opacity: 1, translateY: 0 }}
transition={{ type: 'timing', duration: 300, delay: i * 100 }}
>
<Text>{item.label}</Text>
</EaseView>
))}

Interruption

Animations are interruptible by default. Changing animate values mid-animation smoothly redirects to the new target.

Transform origin

<EaseView
animate={{ rotate: isOpen ? 45 : 0 }}
transformOrigin={{ x: 0, y: 0 }}
transition={{ type: 'spring', damping: 12, stiffness: 200, mass: 1 }}
style={styles.card}
/>
ValuePosition
{ x: 0, y: 0 }Top-left
{ x: 0.5, y: 0.5 }Center (default)
{ x: 1, y: 1 }Bottom-right

Transform perspective

Control the 3D perspective depth for rotateX and rotateY animations. Lower values create a more dramatic 3D effect; higher values look flatter.

<EaseView
animate={{ rotateY: flipped ? 180 : 0 }}
transformPerspective={800}
transition={{ type: 'timing', duration: 600, easing: 'easeInOut' }}
style={styles.card}
/>

Default is 1280, matching React Native's default perspective.

iOS

On iOS, the parent view must not be flattened by Fabric for perspective to render correctly. Ensure the parent has collapsable={false} or a style that prevents flattening (e.g. transform, opacity, zIndex).

Style handling

If a property appears in both style and animate, the animated value takes priority and the style value is stripped.

<EaseView
animate={{ translateY: moved ? -10 : 0 }}
transition={{ type: 'spring', damping: 15, stiffness: 120, mass: 1 }}
style={{
opacity: 0.9,
backgroundColor: 'white',
borderRadius: 16,
padding: 16,
}}
>
<Text>Notification card</Text>
</EaseView>