About this animation
A scroll-driven sunrise-to-night landscape with configurable chapter content, fonts, and scroll distance per chapter.
Why this one
Four unrelated property photos rarely share the same geometry. This piece keeps one cabin, one mountain ridge, and one grove of pines throughout the day. Shadows rotate and lengthen, and four windows light up individually as the sun sets. The scroll becomes the clock, rather than a slideshow.
How it works
- Measure the container with
onLayout. The vector artwork scales from a 390 × 844 coordinate system; interface text stays in points. useAnimatedScrollHandlerderives a single chapter progress from the actual scroll offset. The imperative controller also moves the real ScrollView usingscrollTo.- Interpolate sky colors by RGB components with gamma 1. Mountain layers darken independently. Smoothstep keyframes hold the sun and lighting poses around each chapter.
- Render the cabin, porch, rotating shadows, staggered window glow, chimney smoke, and 120 deterministic stars in one Skia canvas. A second small canvas renders the scroll icon.
- Separate title entrance and exit windows leave a gap between chapters. Clock and temperature digits move only near their next integer; tens move only at the carry.
- Keep the final button in scroll content. The demo drives chapter transitions every 2.6 seconds and fades through black before resetting. Touch or wheel input stops autoplay.
Install
npx expo install @shopify/react-native-skia react-native-reanimated react-native-workletsUse Expo SDK 58 with its compatible package versions. For web, initialize CanvasKit before rendering Skia, using your app's Skia loading boundary. This catalog's host must register the demo using its existing withSkia loader. No image downloads or assets are needed.
Usage
import DaylightTimelapseScroll from './daylight-timelapse-scroll';
export function StayScreen() {
return <DaylightTimelapseScroll onBook={() => openBooking()} />;
}Customize the typography and scroll pacing:
import { useRef } from 'react';
import {
DaylightTimelapseScroll,
type DaylightTimelapseScrollRef,
} from './daylight-timelapse-scroll';
export function CustomizedStay() {
const scene = useRef<DaylightTimelapseScrollRef>(null);
return (
<DaylightTimelapseScroll
ref={scene}
fontFamily="YourInterfaceFont"
serifFontFamily="YourEditorialFont"
italicFontFamily="YourEditorialItalic"
monoFontFamily="YourMonoFont"
chapterLength={1.1}
sunriseDuration={1500}
bookingLabel="Reserve the cabin"
onBook={() => openBooking()}
/>
);
}The parent must provide bounded height. Load custom fonts before mounting; the component falls back to system fonts. The Northwind demo passes Geist, Geist Mono, and Instrument Serif from the host.
Props
| Prop | Type | Default | Purpose |
|---|---|---|---|
chapters | Four-element DaylightChapter tuple | Generic day narrative | Titles, italic lines, eyebrows, descriptions, and accents |
fontFamily | string | System | Interface and booking copy |
serifFontFamily | string | System | Main editorial line |
italicFontFamily | string | System | Accent editorial line |
monoFontFamily | string | System | Rolling clock, temperature, counters |
brand | ReactNode | None | Identity above the clock |
bookingLabel | string | Reserve your stay | Button and accessible label |
onBook | () => void | None | Booking action |
onInteraction | () => void | None | Stops external playback on user input |
onChapterChange | (chapter: number) => void | None | Nearest chapter, dispatched on JS |
chapterLength | number | 1 | Viewport heights between chapters; minimum 0.5 |
sunriseDuration | number | 1500 | Initial dawn reveal duration in milliseconds |
snapToChapters | boolean | true | Native chapter snapping; web stays continuous |
style | StyleProp<ViewStyle> | None | Outer container |
testID | string | None | Test identifier |
Ref methods: scrollToChapter(chapter, duration = 900), stop(), and reset(). Fractional chapter positions are accepted. Autoplay belongs to the demo and uses these methods.
Compatibility
Targets Expo SDK 58, React Native 0.88.0, Reanimated 4.7.1, Worklets 0.13.0, and Skia 2.14.0.
Accessibility
Each visible chapter exposes a header and supporting copy. Hidden chapters are removed from the accessibility tree. Four 44-point chapter buttons provide a tap alternative to scrolling, with a selected state. The booking button has a button role and the booking text as its label. Clock and temperature labels expose the current chapter's settled values.
Reduced motion uses 200 ms chapter fades, removes title displacement and digit rolling, holds stars still, removes smoke drift and the shooting star, and renders dawn immediately. There is no zoom or parallax. Button pressure uses a static 0.97 scale. Native snapping is disabled on web so mouse-wheel scroll remains continuous.
Icons: Lucide (ISC). The Northwind compass tile uses the supplied demo brand kit. The cabin, mountains, and trees are original vector scene artwork.
Customization notes
Set chapters[].accent to theme the chapter highlights; atmospheric colors follow time of day.




