About this animation
A chapter story with layered photo parallax and rolling years, with configurable chapter content, fonts, and brand slot.
Why this one
Each chapter is an illuminated photographic plate against a darker, full-bleed world. The origin opens through a tall architectural arch with hillside sunlight; craft uses a crisp studio frame and fine dust, the café has cool rain, and the final morning has soft rising light. No illustrated leaves are used. The rolling year and illuminated rail connect the chapters without turning the story into a static timeline.
How it works
- Measure the container with
onLayout; chapter height follows the actual available space. - Derive one continuous chapter progress from the real ScrollView's offset on the UI thread.
- Stack full-bleed photographs with entry-only opacity. Float a cropped photographic plate in front, with a fine accent edge and two shadow layers; draw radial light and atmospheric foregrounds in one Skia canvas.
- Keep poses still around chapter centers; move the three planes at 0.18×, 0.42×, and 0.85× during transitions.
- Alternate the frame tilt during chapter transitions, with a stable pose at each center. Separate heading windows so neighboring titles never overlap. Roll only year columns whose digits change at the chapter boundary.
- Place the final action inside the ScrollView. The demo drives that same scroll offset, stops on touch, and loops through black.
Install
npx expo install expo-image expo-linear-gradient react-native-reanimated react-native-worklets @shopify/react-native-skiaFor web, initialize CanvasKit before rendering this component, using Skia's WithSkiaWeb loader. The catalog integration must load this demo through its existing withSkia wrapper. Fonts and photos are supplied by the caller; the component has no dependency on the demo or the catalog theme.
Usage
import { BrandChaptersParallax } from './brand-chapters-parallax';
<BrandChaptersParallax
chapters={[
{
id: 'beginning', image: require('./beginning.jpg'), year: '2009',
title: 'Every story starts somewhere.', subtitle: 'Start here.',
body: 'We planted the first seeds.', eyebrow: 'ORIGIN',
accent: '#FCD34D', foreground: 'leaves',
},
]}
onAction={() => openCollection()}
/><BrandChaptersParallax
chapters={chapters}
parallaxIntensity={0.7}
yearDuration={600}
titleFontFamily="YourSerif"
italicFontFamily="YourSerifItalic"
monoFontFamily="YourMono"
ctaLabel="Explore the collection"
onChapterChange={trackChapter}
/>Props
| Prop | Type | Default | Purpose |
|---|---|---|---|
| chapters | readonly BrandChapter[] | Required | Images, four-digit years, two heading lines, body, eyebrow, accent, foreground |
| brand | ReactNode | — | Custom tile and wordmark |
| fontFamily | string | System | Body and action font |
| titleFontFamily | string | System | Editorial heading font |
| italicFontFamily | string | System | Second-line font |
| monoFontFamily | string | System | Year and counter font |
| hintLabel | string | Scroll to discover | First-chapter discovery button text |
| ctaLabel | string | Explore the story | Accessible action text |
| onAction | () => void | — | Final action callback |
| onChapterChange | (index: number) => void | — | Transition-center callback on JS |
| onInteraction | () => void | — | Stop autoplay on reader input |
| parallaxIntensity | number | 1 | Layer displacement multiplier |
| yearDuration | number | 600 | Year animation duration in ms |
| snapToChapters | boolean | true | Native-only chapter snap |
| style | StyleProp<ViewStyle> | — | Root styles |
| testID | string | — | Test selector |
Ref methods: scrollToChapter(index, duration = 1800) scrolls the real content; reset() fades through black and replays the entrance. The demo travels every 2.6 seconds with a 1.9-second cinematic transition. No React state updates occur per frame.
Compatibility
Targets Expo SDK 58, React Native 0.88.0, Reanimated 4.7.1, worklets 0.13.0, and Skia 2.14.0. Uses Expo Go-compatible installed modules. Supports iOS, Android, and web. Web intentionally avoids mandatory scroll snap.
Accessibility
Chapter copy exposes a header and readable supporting text. The rail and first-screen scroll hint provide 48 pt tap alternatives. The final action has a button role and its visible label. Reduced motion removes parallax, zoom, foreground travel, and entrance blur; short fades replace travel. The CTA uses a separate press scale, so release cannot cancel chapter motion.
The entrance reveals the photograph from black, raises the framed plate, and rolls the year within 1.4 seconds. In short containers, a smaller headline and shorter plate preserve the body and final action. Landscape uses copy on the left and art on the right; tablet content widths are capped. The host screen owns safe-area insets. Long custom copy or larger accessibility text should be checked in the host layout.
Dark veils and soft text shadows maintain contrast. The demo uses local assets and an invented brand from the provided kit. Icons: Lucide (ISC).
Customization notes
Set chapters[].accent to color each chapter.




