Skip to content
Native Animation
Weather Hero animation preview
Skia

Weather Hero

An editorial weather screen with crisp rolling temperature digits, a hand-drawn forecast set, and a living Skia sky.

$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, or paste the agent prompt into Claude Code, Codex or Cursor once the MCP server is connected.

npx nativeanimation add weather-hero

About this animation

An editorial weather screen with crisp rolling temperature digits, a hand-drawn forecast set, and a living Skia sky.

Why this one

Most oversized weather heroes treat the forecast and the scene as separate layers. This one keeps the selected day, rolling temperature, condition label, forecast highlight, and atmospheric palette on one transition path. The result stays synchronized even through fast repeated taps, while the custom sun, cloud, rain, and storm drawings remain readable at compact mobile sizes.

How it works

  1. The component measures its container and derives every position, size, and type scale from its width and height.
  2. Skia draws the gradient sun, layered cotton clouds, occasional wind trails, and rain. One UI-thread clock drives every ambient loop without React renders per frame.
  3. A shared transition blends the backdrop, cloud coverage, sun visibility, cloud tone, rain, and lightning when the selected forecast changes.
  4. React Native text keeps the giant temperature crisp and accessible. Incoming and outgoing values each use their natural typographic width, stay centered independently of the degree symbol, and are committed together before a layout effect starts their roll.
  5. Forecast buttons and the imperative selectDay() method use the same transition path, so direct interaction and autoplay behave identically.

Install

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

On web, wait for CanvasKit before mounting the application:

import { LoadSkiaWeb } from '@shopify/react-native-skia/lib/module/web';

LoadSkiaWeb().then(() => {
  root.render(<App />);
});

Usage

import WeatherHero, { type ForecastDay } from './WeatherHero';

const days: ForecastDay[] = [
  { label: 'TODAY', high: 64, low: 52, sky: 'partly' },
  { label: 'WED', high: 68, low: 53, sky: 'sunny' },
  { label: 'THU', high: 61, low: 50, sky: 'cloudy' },
  { label: 'FRI', high: 57, low: 48, sky: 'rain' },
  { label: 'SAT', high: 59, low: 47, sky: 'partly' },
  { label: 'SUN', high: 66, low: 51, sky: 'sunny' },
  { label: 'MON', high: 55, low: 46, sky: 'storm' },
];

export function WeatherScreen() {
  return <WeatherHero days={days} />;
}

Customize the typography, highlight color, labels, callback, and external control:

import { useRef } from 'react';
import WeatherHero, { type WeatherHeroRef } from './WeatherHero';

export function WeatherScreen() {
  const weatherRef = useRef<WeatherHeroRef>(null);

  return (
    <WeatherHero
      ref={weatherRef}
      accent="#F06449"
      city="Portland"
      days={days}
      fontFamily="Geist_400Regular"
      numberFontFamily="Geist_300Light"
      skyLabels={{
        sunny: 'Clear',
        partly: 'Some clouds',
        cloudy: 'Overcast',
        rain: 'Light showers',
        storm: 'Thunderstorms',
      }}
      onDayChange={(index) => trackForecastDay(index)}
    />
  );
}

The forwarded ref exposes selectDay(index).

Props

PropTypeDefaultDescription
citystring'Portland'City shown above the sky.
daysForecastDay[]RequiredSeven selectable forecast days; the first is selected initially.
unitstring'°'Temperature suffix.
skyLabelsPartial<Record<SkyState, string>>Built-in labelsVisible labels for any sky states you want to override.
accentstring'#FF5A4E'Sun, selection, and highlight color.
numberFontFamilystringSystem fontFont family for the giant temperature.
fontFamilystringSystem fontFont family for labels and forecast values.
onDayChange(index: number) => void—Called after a day transition completes.
styleStyleProp<ViewStyle>—Outer-container style.
testIDstring—Test identifier for the outer container.

ForecastDay contains label, high, low, and sky. SkyState is 'sunny' | 'partly' | 'cloudy' | 'rain' | 'storm'.

Compatibility

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

Accessibility

Each forecast day is a labeled button with its selected state, condition, high, and low exposed to assistive technology. The current city, temperature, and condition form a polite live region. With reduced motion enabled, clouds, wind, and rain remain still, while day changes use a 250 ms crossfade instead of rolling or traveling motion.