Skip to content
Native Animation
Recap Share Poster animation preview

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

npx nativeanimation add recap-share-poster
Year in reviewSkia

Recap Share Poster

An annual recap that assembles into a touch-responsive bento poster, with configurable stats, ribbon text, colors, and fonts.

$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

An annual recap that assembles into a touch-responsive bento poster, with configurable stats, ribbon text, colors, and fonts.

Why this one

The final recap becomes a physical object: five spring-driven tiles settle into place, mechanical digits arrive with them, and a ribbon passes behind the upper corner and in front of the lower corner. Soft holographic light follows the same tilt as the card.

How it works

  1. Five staggered springs drive both native text and tile artwork. The measured defaults are 110 ms apart, with damping 15, stiffness 170, and explicit mass 1.
  2. Each tile has one animated native view containing its background, text, and clipped Skia artwork. A four-point star anchors the small accent tile.
  3. All decoration shares one fixed-size Skia Canvas. A clipped ribbon passes behind the upper-right corner and in front of the lower-left corner; its path reveals over 700 ms.
  4. Ribbon glyphs are rasterized once into a 3× atlas. One animated distance moves the sprites along a precomputed track at 40 points per second, with no React component per character. Geist ExtraBold supplies the default face; ribbonFont replaces it.
  5. Gesture Handler updates a normalized tilt shared value. Perspective is 900, rotation is limited to 10 degrees, and release returns through a spring. Idle sway has an eight-second period.
  6. Sharing is a callback. The component never captures a screenshot or opens a share sheet.

Install

npx expo install @expo-google-fonts/geist @shopify/react-native-skia react-native-gesture-handler react-native-reanimated react-native-worklets

Use a GestureHandlerRootView at the app root and the Reanimated/worklets configuration required by your Expo SDK. For web, initialize CanvasKit before mounting this component, following Skia's web setup. No additional native modules are required beyond this project's Expo Go stack.

Usage

import { RecapSharePoster } from './recap-share-poster';

<RecapSharePoster
  year={2026}
  handle="@alex.moves"
  stats={{
    main: { value: '1,284', label: 'workouts' },
    streak: { value: '42 days', label: 'Longest streak' },
    time: { value: '6:30 AM', label: 'Favorite hour' },
    top: { value: 'Strength', label: 'Your #1' },
  }}
  onShare={() => openYourShareFlow()}
/>

Personalize the typography, ribbon, colors, and pace:

<RecapSharePoster
  ref={posterRef}
  fontFamily="YourInterfaceFont"
  displayFontFamily="YourHeavyFont"
  monoFontFamily="YourNumberFont"
  ribbonFont={require('./assets/your-heavy-font.ttf')}
  ribbonText="2026 ✦ KEEP GOING ✦"
  ribbonSpeed={28}
  colors={{ ribbon: '#7CE8B8', ribbonInk: '#101028' }}
  onShare={shareYourData}
/>
// posterRef.current?.replay();

The component uses 78% of the container width when height permits, caps tablet enlargement, and preserves 9:16 when height requires a smaller card. The parent supplies safe-area insets. Numeric display strings use compact mechanical columns; keep labels and values concise for a story-sized layout.

Props

PropTypeDefaultPurpose
statsRecapPosterStatsFour example fitness statsmain, streak, time, and top, each with value and label
yearnumber2026Header year
handlestring@youFooter username
brandReactNodeNoneHost-owned brand tile and wordmark
colorsPartial<RecapPosterColors>Collection palettePaper, ink, tile colors, on-dark ink, ribbon, button, and holographic colors
ribbonTextstringYear followed by ✦Repeated ribbon copy
ribbonSpeednumber40Points per second; zero freezes lettering
tiltEnabledbooleantrueTouch tilt and idle sway
onShare() => voidNoneHost share action
shareLabelstringShareButton text and accessible label
yearLabelstringMyHeader prefix
accessibilityLabelstringGenerated summaryOverride the full poster description
fontFamilystringSystemInterface copy
displayFontFamilystringInterface fontHeader type
monoFontFamilystringSystemRolling values
ribbonFontDataSourceParamGeist ExtraBoldOptional font asset for ribbon lettering
staggerMsnumber110Time between arrivals
ribbonRevealMsnumber700Ribbon reveal time
swayPeriodMsnumber8000Ambient sway cycle
styleStyleProp<ViewStyle>NoneRoot container styling
testIDstringrecap-share-posterRoot identifier; button appends -share

Ref methods: play(), replay(), and tiltTo(x, y) for a host-controlled presentation pose in the range −1 to 1. Assembly starts on mount. The demo owns the autoplay loop and simulates left/right poses, then rests for two seconds before replaying.

Compatibility

Expo Go includes the required native modules in this project's SDK.

Accessibility

The poster is exposed as one image whose label summarizes the year, all four values and labels, and the handle. The separate Share button has a minimum 48-point target and a stable test identifier. Reduced motion uses a 200 ms fade, stationary digits and ribbon, and disables tilt and ambient sway. Tilt changes decoration only; every statistic and the Share action remain available without dragging.

Demo icon: Lucide (ISC), supplied with its license. Demo brand: the project's invented Aurora identity.