Skip to content
Native Animation
Gradient Mesh Hero animation preview

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

npx nativeanimation add gradient-mesh-hero
Welcome

Gradient Mesh Hero

A welcome hero with a touch-responsive gradient mesh and configurable palette, copy, fonts, and title size.

$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 welcome hero with a touch-responsive gradient mesh and configurable palette, copy, fonts, and title size.

Why this one

The background is a live SkSL shader rather than a looping image or video. Five independently orbiting colors respond to your finger; a sixth white light swells inside the mesh and fades on release. Three curated palettes and a shader-level contrast guard keep the copy readable without flattening the entire scene.

How it works

  1. onLayout measures the container. One Canvas renders the mesh and optional Lucide kit tile.
  2. A UI-thread clock moves five points on Lissajous orbits with 11–19-second periods. Softened inverse-distance weights blend their colors.
  3. Pan and tap compete through Gesture Handler. The nearest point is selected at touch-down; independent springs follow the finger and pull that point away from its orbit. Release restores the orbit and fades the white light over 600 ms.
  4. A fixed 4% grain breaks up banding. A transparent-to-indigo veil starts at 45% height. From 51% height, the shader bounds every sRGB channel to 0.36 after grain and touch light, guaranteeing readable settled copy even in the brightest state.
  5. One entrance progress reveals the mesh from black with 1.15→1 zoom over 1,200 ms. Words start at 300 ms, stagger by 60 ms, and fade, sharpen from 8 px blur, and rise 12 pt. Buttons finish the entrance with a real blur material and independent press springs.
  6. Autoplay belongs to the demo. The public ref exposes replay(), touch(x, y) with normalized coordinates, and release().

Install

npx expo install @shopify/react-native-skia expo-blur react-native-gesture-handler react-native-reanimated react-native-worklets

Wrap your app in GestureHandlerRootView. Load your fonts before mounting. On web, initialize CanvasKit using your app's Skia loading boundary before importing this component; the host catalog uses its withSkia boundary. No images, network requests, or additional native modules are needed.

Usage

import GradientMeshHero from './gradient-mesh-hero';

export function WelcomeScreen() {
  return <GradientMeshHero onGetStarted={() => openSignup()} onSignIn={() => openSignin()} />;
}

Customize the palette and content:

<GradientMeshHero
  palette="lagoon"
  brand="Your studio"
  title={'A fresh start.\nEvery day.'}
  subtitle="Find a little space for your ideas."
  primaryLabel="Get started"
  secondaryLabel="Sign in"
  fontFamily="YourSansFont"
  titleFontFamily="YourDisplayFont"
  titleSize={60}
  speed={0.8}
  grain={0.03}
  entranceDuration={1200}
/>

Props

PropTypeDefaultDescription
palette'dusk' | 'lagoon' | 'ember'duskFive-color palette.
brandstringWelcomeWordmark.
brandAccessoryReactNode—Optional wordmark accessory.
showBrandTilebooleanfalseAurora kit tile in the same Canvas.
titlestringCreate something / beautiful.Newlines set line breaks; longer lines wrap.
subtitlestringA little inspiration goes a long way.Supporting copy.
primaryLabelstringContinueMain action text.
secondaryLabelstringSign inGlass action text.
onGetStarted / onSignInfunction—Action callbacks on JS.
fontFamily / titleFontFamilystringSystemBody/control and headline/wordmark fonts.
titleSizenumber61.36Headline size at 390 pt; scales down on smaller containers.
entranceDurationnumber1200Entrance milliseconds.
speednumber1Nonnegative orbit speed multiplier.
grainnumber0.04Grain amplitude, clamped to 0–0.04.
styleStyleProp<ViewStyle>—Container style.
testIDstring—Root test identifier.

The demo's PALETTE constant selects its art direction. Brand starts at 8% height, copy at 52%, and controls at min(84% height, height − 146 pt). This preserves two 56 pt targets, a 10 pt gap, and 24 pt bottom breathing room at 320×694 and 390×844. Keep custom copy short; large accessibility text may require a scrollable host.

Compatibility

Targets Expo SDK 58, React Native 0.88.0, Reanimated 4.7.1, and Skia 2.14.0. Native dependencies are bundled in the matching Expo Go. Android uses BlurTargetView and dimezisBlurViewSdk31Plus, with a translucent fallback on Android versions below API 31. See the SDK 58 BlurView documentation.

Accessibility

Both actions have button roles and labels with 56 pt hit areas. The mesh has an explicit screen-reader activation action, and a tap provides the same color attraction as a drag. Text is separately exposed as a single headline. Buttons sit outside the mesh GestureDetector. Reduced motion fixes the mesh at time zero, disables touch distortion and light, removes zoom, translation, blur, and press scaling, and uses a 220 ms entrance fade.

For settled copy, the worst-case channel ceiling of 0.36 yields white headline contrast of approximately 6.71:1 and 80%-white subtitle contrast of approximately 5.00:1, including white interaction light and grain. Entrance opacity intentionally begins at zero. The wordmark region has the same channel guard plus a diffuse shadow. Icons: Lucide (ISC); the sparkles path is copied from the repository kit.

Layout

Font metrics measured from the bundled Instrument Serif font keep both demo headline lines within 88% width: 338.6/319.1 pt at 390 pt wide and 276.9/262.9 pt at 320 pt wide. The wordmark stays on the left; no control occupies the viewer close-button area. Copy and controls have separate vertical regions; the shorter screen moves controls up to keep them visible. Autoplay attracts a color from 1.05 seconds and drags it through the center before 2.3 seconds. Grain, light, veil, zoom, and contrast are computed inside the shader, with no solid effect block over the text.