About this animation
A splash that traces a glyph into a gradient tile and reveals a home screen, with configurable glyph path, tile colors, wordmark font, and tagline.
How it works
- The component measures its own container with
onLayout, so the splash, wordmark, and destination screen scale from local dimensions rather than the device window. - One Reanimated shared value drives the full timeline: predawn light, path drawing, liquid fill, tile spring, letter stagger, and the transition into the app.
- Skia draws the supplied Lucide path in three coordinated layers: the permanent gradient stroke, a short fading trail, and a bright traveling point.
- A bottom-up mask fills the completed glyph with a second gradient while the rounded brand tile forms around it with a restrained overshoot.
- The same tile rises and shrinks into the destination header as a flight summary and travel card fade into place, keeping the splash visually connected to the product.
Palette
The default palette pairs a deep evergreen atmosphere (#081311 → #10231F → #1B3830) with a darker green tile (#244A40 → #18382F). The trace and final fill use two nearby sage tones (#B9DBCA → #8BBBA6), with a soft sage halo and ivory text (#F2F5EF). Muted copy, borders, and flight-status accents share the same green undertone. No warm sunrise or separate blue accent enters the transition.
Install
npx expo install @shopify/react-native-skia expo-linear-gradient react-native-reanimated react-native-workletsOn web, copy CanvasKit into your public assets and wait for LoadSkiaWeb before mounting the component:
npx setup-skia-webIcons: Lucide (ISC).
Usage
import StrokeLogoReveal from './StrokeLogoReveal';
const compass =
'M16.24 7.76l-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265zM2 12a10 10 0 1 0 20 0a10 10 0 1 0 -20 0';
export function LaunchScreen() {
return (
<StrokeLogoReveal
brandName="Northwind"
glyphPath={compass}
wordmarkFont={require('./Brand-Medium.ttf')}
/>
);
}Customize the home screen, atmosphere, and replay behavior:
<StrokeLogoReveal
brandName="Northwind"
tagline="Fly somewhere new"
glyphPath={compass}
tileColors={['#244A40', '#18382F']}
strokeColors={['#B9DBCA', '#8BBBA6']}
contentColor="#F2F5EF"
backgroundColors={['#081311', '#10231F', '#1B3830']}
greeting="Good morning, Avery"
flightNumber="NW 214"
originCode="JFK"
destinationCode="LIS"
departureTime="8:40 PM"
gate="B18"
seat="4A"
replayOnPress={false}
onRevealEnd={() => trackLaunchComplete()}
/>The forwarded ref exposes replay().
Props
| Prop | Type | Default | Description |
|---|---|---|---|
brandName | string | Required | Brand name revealed one letter at a time. |
tagline | string | 'Fly somewhere new' | Short brand promise shown below the wordmark. |
glyphPath | string | Required | Lucide SVG path data for the traced brand glyph. |
glyphViewBox | [number, number] | [24, 24] | View box used by the glyph path. |
tileColors | [string, string] | ['#244A40', '#18382F'] | Two deep evergreen colors used by the brand tile. |
strokeColors | [string, string] | ['#B9DBCA', '#8BBBA6'] | Nearby sage tones shared by the trace, final fill, and traveling glow. |
contentColor | string | '#F2F5EF' | Main wordmark and home-screen text color. |
backgroundColors | [string, string, string] | ['#081311', '#10231F', '#1B3830'] | Deep evergreen background colors from night to the softly lit horizon. |
wordmarkFont | DataSourceParam | undefined | Skia font asset used by the wordmark. |
fontFamily | string | undefined | Font family for home-screen interface copy. |
mediumFontFamily | string | undefined | Medium font family for labels and headings. |
monoFontFamily | string | undefined | Monospaced font family for flight details. |
greeting | string | 'Good morning, Avery' | Greeting on the destination home screen. |
nextFlightLabel | string | 'YOUR NEXT FLIGHT' | Label above the boarding-pass summary. |
flightNumber | string | 'NW 214' | Flight identifier. |
originCode | string | 'JFK' | Origin airport code. |
destinationCode | string | 'LIS' | Destination airport code. |
departureTime | string | '8:40 PM' | Departure time. |
gate | string | 'B18' | Boarding gate. |
seat | string | '4A' | Assigned seat. |
autoStart | boolean | true | Starts the reveal when the component mounts. |
replayOnPress | boolean | true | Allows a tap anywhere on the reveal to replay it. |
onRevealEnd | () => void | undefined | Called after the home screen settles. |
accessibilityLabel | string | Replay ${brandName} launch | Screen-reader label. |
style | StyleProp<ViewStyle> | undefined | Optional style for the outer container. |
testID | string | undefined | Test identifier applied to the outer container. |
duration | number | 760 | Opening stroke draw duration in milliseconds; later phases keep their own timing. Spring physics and reduced-motion timing are unchanged. |
Compatibility
- Expo SDK 58
- React Native 0.88
- Reanimated 4.7 and React Native Worklets 0.13
- React Native Skia 2.14
- iOS: supported
- Android: supported
- Web: supported
- Works in Expo Go because the required native modules are included in the SDK
Why this one
Most logo reveals stop at a finished mark on an empty background. This version makes the reveal useful: the glowing point visibly creates the glyph, the dawn responds to its progress, and the finished tile becomes real navigation chrome while a credible flight home screen arrives underneath. The identity moment and product moment are one continuous action rather than two unrelated scenes.
Accessibility
The full surface is a labeled replay button by default, so the animation never depends on a gesture. Set replayOnPress={false} to expose it as a static image. Reduced motion replaces tracing, blur, spring overshoot, and translation with a 220 ms fade directly to the complete home screen.




