Skip to content
Native Animation
welcomephotosparallaxform

Rising Photo Welcome

A full-screen welcome form where each new photo rises over the last and carries its color into translucent input fields.

$9 for this animation

Checkout opens soon. Leave your email and we will tell you the moment you can buy it.

One email when checkout opens. No spam.

Add to your project

Copy the component and its assets into your app with the Native Animation CLI.

npx nativeanimation add rising-photo-welcome

About this animation

A full-screen welcome form where each new photo rises over the last and carries its color into translucent input fields.

How it works

  1. The component keeps only the current and next images mounted, then waits for the incoming image to load before moving it.
  2. A single continuous progress shared value drives every animated property, keeping the photo layers and field tint synchronized on the UI thread.
  3. The incoming photo follows a measured upward easing curve while its scale settles over a longer, softer tail.
  4. The outgoing photo moves more slowly, grows slightly, and darkens to create depth without competing with the new image.
  5. interpolateColor blends the translucent fields from the outgoing slide's tint to the incoming slide's tint over the same entrance.

Install

npx expo install react-native-reanimated expo-image expo-linear-gradient

This component also imports react-native-worklets, which is installed with Reanimated in an Expo project.

Usage

import RisingPhotoWelcome from './RisingPhotoWelcome';

const slides = [
  { image: require('./assets/lounge.jpg'), tint: '#556467' },
  { image: require('./assets/garden.jpg'), tint: '#607D53' },
];

export function WelcomeScreen() {
  return <RisingPhotoWelcome slides={slides} />;
}

Use the timing, fonts, callbacks, and imperative controls to adapt the pattern:

import { useRef } from 'react';
import RisingPhotoWelcome, {
  type RisingPhotoWelcomeRef,
} from './RisingPhotoWelcome';

export function WelcomeScreen() {
  const welcomeRef = useRef<RisingPhotoWelcomeRef>(null);

  return (
    <RisingPhotoWelcome
      ref={welcomeRef}
      slides={slides}
      title="NORTH"
      subtitle="Save a place for tonight."
      interval={3200}
      transitionDuration={900}
      titleFontFamily="YourSerifFont"
      bodyFontFamily="YourSansFont"
      monoFontFamily="YourMonoFont"
      onCountryPress={() => openCountryPicker()}
      onSubmit={(phone) => continueWith(phone)}
      onIndexChange={(index) => trackVisiblePhoto(index)}
    />
  );
}

The forwarded ref exposes next(), pause(), and resume().

Props

PropTypeDefaultDescription
slidesWelcomeSlide[]RequiredAt least two { image, tint } entries.
titlestring'WELCOME'Large heading near the top.
subtitlestring'Find the places you love.'Supporting copy below the heading.
phoneLabelstring'Phone number'Label above the phone controls.
countryCodestring'+1'Text inside the country-code button.
placeholderstring'(555) 000-0000'Phone input placeholder.
onPhoneChange(value: string) => void—Called after each phone-number edit.
onSubmit(value: string) => void—Called by the keyboard's done action.
onCountryPress() => void—Called when the country-code button is pressed.
onIndexChange(index: number) => void—Called when an incoming photo reaches its final position.
autoAdvancebooleantrueEnables automatic transitions.
intervalnumber2400Milliseconds from one transition start to the next.
transitionDurationnumber1000Duration of the upward entrance in milliseconds.
titleFontFamilystringSystem fontFont used for the heading.
bodyFontFamilystringSystem fontFont used for supporting text and the country code.
monoFontFamilystringSystem fontFont used for the phone input.
styleStyleProp<ViewStyle>—Outer-container style.
testIDstring—Test identifier for the outer container.

Compatibility

  • Expo SDK 57
  • React Native 0.86
  • Reanimated 4.5 and Worklets 0.10
  • iOS: supported, not yet verified on a device
  • Android: supported, not yet verified on a device
  • Web: verified
  • Works in Expo Go because all native dependencies are included in the SDK

Accessibility

The country-code control is exposed as a labeled button and the phone field uses its visible label as its accessibility label. Focusing the phone field pauses automatic transitions and blurring it resumes them. When reduced motion is enabled, the rise, scale, and parallax are replaced by a 300 ms crossfade while the tint still transitions in sync.