Skip to content
Native Animation
E-bike Ride Dashboard animation preview

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

npx nativeanimation add ebike-ride-dashboard
OnboardingSlider

E-bike Ride Dashboard

An e-bike welcome-to-dashboard transition with live ride controls and configurable bike image, stats, 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 e-bike welcome-to-dashboard transition with live ride controls and configurable bike image, stats, colors, and fonts.

Why this one

The bike stays mounted throughout the transition. Controls change the product itself: the headlight casts a soft cone, the bell shakes the frame, and booking gives the bike a short starting impulse.

How it works

  1. Measure the host with onLayout. A compact arrangement handles short containers; wide hosts center a dashboard capped at 460 pt.
  2. A continuous stage value drives the reversible image transform, background, sheet, and staggered dashboard reveals. The image scales uniformly from 2.6 to 1.
  3. A separate charge value fills the battery in 900 ms. Only integer changes cross to React for the accessible counter.
  4. The lamp uses a single Skia canvas for the blurred light cone, halo, and ground shadow. Controls have independent press feedback.
  5. A Gesture Handler pan drives booking progress. Release below 85% springs back; completing the track books once. Tapping the knob is an accessible alternative.

Install

npx expo install @expo/vector-icons @shopify/react-native-skia expo-image expo-linear-gradient react-native-gesture-handler react-native-reanimated react-native-worklets

Configure Reanimated and wrap the host app with GestureHandlerRootView. For web, initialize Skia/CanvasKit before mounting this component, following the Skia web setup. No additional native modules beyond those bundled in Expo Go are required.

Usage

import { EbikeRideDashboard } from './ebike-ride-dashboard';

<EbikeRideDashboard
  bikeImage={require('./assets/bike.webp')}
  model="Strata X1"
  onBook={() => openReservation()}
/>
const bike = useRef<EbikeRideDashboardRef>(null);

<EbikeRideDashboard
  ref={bike}
  bikeImage={require('./assets/bike.webp')}
  bikeAspectRatio={1199 / 758}
  headlightOrigin={{ x: 0.75, y: 0.29 }}
  colors={{ accent: '#C4F15A', surface: '#FAFAF5' }}
  stats={[
    { label: 'Ride Time', value: '2h 10m', tone: 'accent' },
    { label: 'Distance', value: '18.2 mi', tone: 'dark' },
  ]}
/>
// bike.current?.start(); bike.current?.back(); bike.current?.reset();

Props

PropTypeDefault / purpose
bikeImageImageSourceRequired; image with alpha recommended
bikeAspectRationumber1199 / 758; prevents distortion
onboardingTitlestringRide smarter, every single mile
ctaLabelstringLet's start the ride
model, subtitlestringElectric bike / Electric Fat Tire
batterynumber99; clamped to 0–100
statsBikeStat[]Usage Time and Distance; first two tiles
togglesBikeToggle[]Headlight and Bell; first two controls
bookLabel, bookedLabelstringSwipe to Book / Booked · 2 h
headlightOrigin{ x: number; y: number }{ x: .75, y: .29 } in image coordinates
colorsPartial<Palette>Accent, ink, surface, muted, tile, border, onInk, onAccent, welcomeTop, welcomeBottom, beam
fontFamilystringSystem; regular interface text
titleFontFamilystringSystem; headline face
mediumFontFamilystringSystem; buttons and values
monoFontFamilystringSystem; counting battery
labelsPartial<Labels>Back, Location, On, Off, Battery, Electric bicycle
onStart, onBack, onBook() => voidTransition and completion callbacks
onToggle(id, enabled) => voidControl state callback
onLocation() => voidLocation button action
style, testIDStyleProp<ViewStyle>, stringHost layout / ebike-ride-dashboard

Ref methods: start(), back(), book(), toggle(id), reset(). Calls use the same transitions as user input. onBook fires once until reset. Returning to welcome preserves switch and booking state; reset() clears them.

Compatibility

Targets Expo SDK 58, React Native 0.88.0, Reanimated 4.7.1, worklets 0.13.0, and Skia 2.14.0. Supports iOS, Android, and web. This is a full-container composition; the host owns safe area insets. There is no internal scroll view. The demo passes Geist font names loaded once by its host; the exported component has no dependency on the catalog theme.

The supplied 1199 × 758 image covers the dashboard at about 3× on phone widths, but its intentional 2.6× onboarding crop exceeds 3× source density. Supply a larger original for maximum crop sharpness. The measured front-wheel crop anchor assumes a side-profile bicycle; a different silhouette may need the crop geometry adjusted.

Accessibility

Buttons have roles and labels; switches expose checked state. The slider supports tap and screen-reader activation in addition to drag. Reduced motion uses 200 ms fades, disables image travel, bell shake, idle waves, and lamp flicker. The host should verify large text, RTL, screen-reader focus, and real device frame rate before shipping.

Demo

The fictional Strata demo starts after 1.2 seconds, lights the headlamp at 3 seconds, rings at 4.5, books at 5.5, then resets at 8. Touching the demo stops autoplay. No audio is played by the bell.

Icons: Feather from @expo/vector-icons, the Lucide kit's supported fallback (MIT).