Skip to content
Native Animation
Poster Parallax Hero animation preview

This preview uses fictional demo content. See the props below for the customization options available in this component.

npx nativeanimation add poster-parallax-hero

Poster Parallax Hero

A layered poster hero with touch parallax and a scroll fade, with configurable background image, subject image, headline, and fonts.

$9 for this animation

Add to your project

Copy the component and its assets into your app with the Native Animation CLI, or paste the agent prompt into Claude Code, Codex or Cursor once the MCP server is connected.

About this animation

A layered poster hero with touch parallax and a scroll fade, with configurable background image, subject image, headline, and fonts.

How it works

  1. Three layers (background, title and subject) share one tilt value. Each layer moves by a different factor of that value, which is what produces the depth.
  2. The tilt follows the pointer on web and a pan gesture on touch screens, and springs back to center when the gesture ends.
  3. Scrolling drives a second shared value: the hero scales slightly, drifts and fades into baseColor while children scroll up over it.
  4. Floating sparks in the accent color drift between the layers. They are generated once per sparkCount.

Title lines use a line height of 1.2 times their font size plus vertical padding to protect custom font ascenders and descenders on native platforms. The title size also accounts for the container height and line count, so the full stack fits in landscape and short embedded containers. It renders after the container has been measured.

Install

npx expo install expo-image expo-linear-gradient react-native-gesture-handler react-native-reanimated react-native-worklets

Wrap your app in GestureHandlerRootView if it is not already.

Usage

import PosterParallaxHero from './poster-parallax-hero';

export function HeroScreen() {
  return (
    <PosterParallaxHero
      background={require('./assets/scenery.jpg')}
      subject={require('./assets/subject.png')}
      eyebrow="Now streaming"
      titleLines={['NORTH', 'RIDGE']}
    >
      {/* Content that scrolls over the hero */}
    </PosterParallaxHero>
  );
}

subject needs a transparent background so the title shows behind it.

Props

PropTypeDefaultDescription
backgroundImageSource | numberRequiredFull-bleed scenery behind everything (sky, landscape).
subjectImageSource | numberRequiredTransparent cutout of the subject; it sits in front of the title.
titleLinesstring[]RequiredTitle words, one per line, drawn between the scenery and the subject.
eyebrowstringundefinedSmall label above the title.
accentColorstring'#FFB547'Color of the floating sparks and the eyebrow rule.
baseColorstring'#06090B'Color the hero fades into as it scrolls away; also the page background.
titleColorstring'#F4F1EA'Color of the hero title.
titleFontFamilystringundefinedTitle font. Bold condensed display faces work best.
fontFamilystringundefinedFont family for interface text.
tiltStrengthnumber1Strength of the pointer / drag parallax (0 disables it).
sparkCountnumber22Number of floating sparks (0 disables them).
childrenReactNodeundefinedContent that scrolls up over the faded hero.
styleStyleProp<ViewStyle>undefinedStyle applied to the outer container.
onInteraction() => voidundefinedCalled when a hover or drag interaction begins.
testIDstringundefinedRoot ID; ${testID}-scroll identifies the scroll and parallax surface. Suffix IDs are omitted when testID is absent.

Compatibility

  • Expo SDK 58
  • React Native 0.88
  • Reanimated 4.7
  • Gesture Handler 3.3
  • iOS, Android and web: supported
  • Works in Expo Go

Accessibility

  • The title is a single header whose label is the full title, so screen readers read it as one phrase rather than one word per line.
  • With Reduce Motion on, there are no sparks and the parallax tilt is disabled.

Customization notes

Parallax follows pointer, gesture, and scroll position. tiltStrength controls its intensity.