Skip to content
Native Animation
Layered Drink Scroll animation preview

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

npx nativeanimation add layered-drink-scroll
Skia

Layered Drink Scroll

A scroll-driven drink builder with settling liquid and rolling measures, with configurable chapters, background image, fonts, and accent color.

$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 scroll-driven drink builder with settling liquid and rolling measures, with configurable chapters, background image, fonts, and accent color.

Why this one

A typical drink page shows a finished photo and an ingredient list. Here, your finger builds the drink: espresso blooms over syrup, milk rises beneath microfoam, and 30 cinnamon flecks land on the surface. A live thermometer and volume ruler make the recipe measurable. Highlights are clipped into the glass and crema, so the material carries the effect.

How it works

  1. Measure the container with onLayout. Each chapter spans one container height; the glass occupies 50% of its width and height, from 14% to 64% vertically.
  2. Derive one continuous progress value, p = clamp(scrollY / height, 0, 4), using useAnimatedScrollHandler. All liquid levels, measurements, chapter windows, and photo entrances derive from it.
  3. Fill syrup, espresso, milk, and foam to 8%, 30%, 40%, and 14% of the glass. Smoothstep transitions leave 20% rest zones around each chapter. Clip the fluids to the tapered glass path; blend their edges over 6 points.
  4. Excite the sinusoidal surfaces when progress changes. A UI frame clock decays the energy at 4/s even after scrolling stops. Scrolling backward withdraws the fluids and reverses the stream and spice positions.
  5. Reveal chapter headings with separate, nonoverlapping entry and exit windows. Stack blurred local photos using incoming opacity only. The dark veil protects the copy.
  6. Keep the chapter buttons and final CTA inside the scroll content. Native devices can snap; web stays continuous. Imperative controls animate the real scroll position, so playback and touch use the same progress.

Install

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

Copy this folder without demo/ into your application. Follow the Skia web setup for your host application and load CanvasKit before importing this component on web (the catalog uses its withSkia loader). Load any custom fonts in the host app before rendering. Icons: Lucide (ISC); the copied paths are in icons.ts.

Usage

import { LayeredDrinkScroll } from './layered-drink-scroll';

export default function RecipeScreen() {
  return <LayeredDrinkScroll onOrder={() => openCheckout()} />;
}

With local art, typography, and controls:

const drink = useRef<LayeredDrinkScrollRef>(null);

<LayeredDrinkScroll
  ref={drink}
  background={require('./assets/counter.jpg')}
  headingLabel="Build your seasonal drink"
  accentColor="#F59E0B"
  waveAmplitude={4}
  fontFamily="YourInterfaceFont"
  titleFontFamily="YourSerifFont"
  italicFontFamily="YourItalicFont"
  monoFontFamily="YourMonoFont"
  orderLabel="Order for pickup — $5.40"
  onOrder={openCheckout}
/>;
// Call from a button handler or a timer, after layout:
drink.current?.goTo(1);

Import LayeredDrinkScrollRef as a type for the second example. reset() fades to black, resets the scroll, then fades back in. goTo(chapter, animated = true) accepts chapters 0–4. Both controls remain interruptible by touch.

Props

PropTypeDefaultPurpose
chaptersreadonly DrinkChapter[]DEFAULT_CHAPTERSFive recipe chapters, in syrup / espresso / milk / foam / spice order.
backgroundDataSourceParamundefinedLocal background image; never required by the reusable component.
headerReact.ReactNodeundefinedHeader content, such as a brand tile and wordmark.
headingLabelstring'Build your drink'Small heading beneath the optional brand.
fontFamilystringundefinedMain interface face.
titleFontFamilystringundefinedEditorial headline face.
italicFontFamilystringundefinedEditorial italic face.
monoFontFamilystringundefinedTabular metric face.
accentColorstring'#F59E0B'Highlight and order-button color.
waveAmplitudenumber5Maximum wave amplitude in points.
snapToChaptersbooleantrueChapter scroll snapping on native touch devices.
orderLabelstring'Continue'Final button text.
onOrder() => voidundefinedCalled when the final button is pressed.
onChapterChange( chapter: number, ) => voidundefinedCalled when the nearest chapter changes.
onInteraction() => voidundefinedCalled on touch or drag; a demo can stop its autoplay.
styleStyleProp<ViewStyle>undefinedOuter container style.
testIDstringundefinedTest identifier.
durationnumber1250Programmatic chapter scroll duration in milliseconds. Spring physics and reduced-motion timing are unchanged.

DrinkChapter contains eyebrow, title, subtitle, body, and optional background. The recipe has five chapters and four fixed liquid proportions; the fifth chapter adds spice.

Compatibility

Targets Expo SDK 58, React Native 0.88.0, Reanimated 4.7.1, Worklets 0.13.0, and Skia 2.14.0. Uses the installed Expo Go stack. Web requires CanvasKit initialization.

Accessibility

Each chapter heading has the header role. Five labeled chapter buttons provide a tap alternative to scrolling, with 44 × 44 point targets. The 54-point CTA has a button role and a label matching its action. Metrics use tabular digits with invisible sizing copies, per-column carry, and a short transition window to avoid resting between digits.

Reduced motion removes liquid waves, pouring ribbons, falling spice movement, metric rolling, hint bouncing, and animated scroll navigation; headings use a 200 ms fade. There is no parallax, zoom, or velocity trail. The demo stops its timer-driven navigation on touch or drag. Its pickup button confirms locally; connect onOrder to the host checkout for a real order.

Demo timing

The demo begins its espresso chapter at 380 ms and completes navigation by approximately 1.63 s: syrup, crema sweep, and 142°F are visible within the first three seconds. Later chapters advance roughly every 2.6 s. After a final hold, a 200 ms fade hides the reset; playback repeats. Touch stops autoplay.

Layout: the header reserves 66 points on the right for the viewer close control. At 390 × 844 and 320 × 694, the glass stays in the 14–64% band; chapter navigation precedes text at 69%; short-screen headlines use 33-point type, with body copy below. The final CTA sits lower in scroll content and can scroll into view. Contrast comes from a 60% brown veil, top/bottom shading, text shadows, and dark measurement pills. Crema light is inside the liquid/glass clipping geometry, not a colored block over the copy.