About this animation
A shoe-fit ruler with rolling US sizes and an animated fit preview, with configurable shoe image, size mapping, accent color, and fonts.
Why this one
A size chart makes shoppers translate numbers into a decision. This finder connects an inch ruler to an anatomical footprint, gives the size a small threshold tick, and brings the shoe onto the footprint on release. Three softly pulsing pressure zones make the fit preview tangible. The width selector changes the actual outline rather than only a label.
How it works
- A pan and an exclusive tap gesture write the same continuous length shared value. The ruler covers 9.0–12.5 inches with quarter-inch markings; taps and accessible step buttons provide alternatives to dragging.
- The footprint's length follows that measurement with a nearly critically damped spring. A separate width shared value scales the anatomical path horizontally.
- Whole-size threshold crossings update independent digit columns on the UI thread. Each column fades by distance and settles at an integer; the tens column moves only when its digit changes. A separate scale value supplies the 1.06 tick.
- Release starts one fit-preview clock: 0–480 ms flight and rotation, 480–1120 ms alignment and pressure visualization, 1120–1600 ms return. The same clock controls color, opacity, pulse, and shoe position. The transparent Skia outline sits above the shoe; no rectangular effect layer covers the artwork or text.
- React receives threshold changes, settled selections, and preview events through
scheduleOnRN. There is no React state update on every drag frame. New input can interrupt the measurement or preview. - The demo owns playback timers and stops them when touched. It measures from 9.5 to 10.4 inches, previews the fit by about 2 seconds, selects Wide, and repeats every 4.8 seconds.
Install
npx expo install @shopify/react-native-skia expo-image expo-linear-gradient react-native-gesture-handler react-native-reanimated react-native-workletsCopy this folder without demo/. Wrap your application in GestureHandlerRootView. Use the SDK-compatible package versions in piece.json; no extra dependency is needed. For web, initialize CanvasKit before importing this Skia component using your application's existing Skia loader. The catalog host must register this demo with its withSkia wrapper.
Usage
import { SizeFitFinder } from './size-fit-finder';
<SizeFitFinder
shoeSource={require('./assets/running-shoe.png')}
onAdd={(selection) => addToCart(selection.size, selection.width)}
/>With custom branding, sizing, and imperative controls:
import { useRef } from 'react';
import { SizeFitFinder, type SizeFitFinderRef } from './size-fit-finder';
function ProductFit() {
const finder = useRef<SizeFitFinderRef>(null);
return (
<SizeFitFinder
ref={finder}
shoeSource={require('./assets/running-shoe.png')}
title="Find your fit"
productName="Daily trainer"
price="$140"
accentColor="#2563EB"
initialLength={10.4}
baseSize={6}
inchesPerSize={1 / 3}
springDamping={30}
colorScheme="light"
onFitPreview={(selection) => saveFit(selection)}
/>
);
}The ref exposes measure(inches, duration?), preview(), setWidth(width), and stop(). duration is useful for scripted demonstrations; real drag input remains on the UI thread. Provide a local, transparent side-profile shoe image with its toe pointing left. The demo supplies its bundled artwork; the reusable component has no demo or shared theme imports.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
shoeSource | ImageSourcePropType | Required | Shoe artwork. |
title | string | Find your size | Main heading. |
productName | string | Running shoe | Product descriptor. |
price | string | $140 | Purchase price. |
initialLength | number | 9.5 | Initial length, clamped to 9–12.5 inches. |
initialWidth | FitWidth | Regular | Narrow, Regular, or Wide. |
baseSize | number | 6 | Whole US size at 9 inches; clamped to 0–50. |
inchesPerSize | number | 1 / 3 | Measurement increment per whole size, minimum 0.1 inches. |
confidenceText | string | Measured for your next run. | Optional product-specific recommendation copy. |
accentColor | string | #2563EB | Measurement and action accent. |
fitColor | string | #22C55E | Aligned-fit contour. |
cautionColor | string | #F59E0B | Between-size contour. |
springDamping | number | 28 | Length and width damping, minimum 28. |
previewDuration | number | 1600 | Fit clock duration, minimum 1000 ms. |
colorScheme | light / dark / auto | auto | Component appearance. |
fontFamily | string | System | Interface font. |
serifFontFamily | string | System | Size and heading font; size digits use 72 × 1.18 pt. |
monoFontFamily | string | System | Measurement and ruler font. |
onSelectionChange | (selection) => void | — | Threshold, release, or width-selection event. |
onFitPreview | (selection) => void | — | Shoe alignment event. |
onAdd | (selection) => void | — | Purchase action. |
onUserInteraction | () => void | — | Direct input, used to stop demo playback. |
accessibilityLabel | string | Foot length in inches | Adjustable ruler label. |
style | StyleProp<ViewStyle> | — | Root container style. |
testID | string | — | Root identifier. |
SizeFitSelection contains length, size, width, and betweenSizes. The demo's size calibration, 98% copy, and pressure visualization are illustrative product content. Supply your own validated sizing calibration and evidence-backed copy for a real store; the pressure zones are visual feedback derived from length, not sensor measurements.
Compatibility
Containers shorter than 640 points scroll vertically through a complete compact composition. The smaller shoe preview leaves the width controls unobstructed. Wide hosts also cap the preview by the available vertical space.
Built for Expo SDK 58, React Native 0.88.0, Reanimated 4.7.1, worklets 0.13.0, Gesture Handler 3.3, and Skia 2.14.0. Uses the installed SDK-compatible Expo Image and Linear Gradient packages. Intended for iOS, Android, and web with Expo Go's bundled modules or a development build containing these dependencies.
The root measures its container with onLayout and hides the layout until measured. The demo allocates its brand header separately, reserves the top-right viewer close area, and uses a compact composition below a 680 pt component height. The shoe rests at 70% of component width, with a 0.92 scale in compact containers. Standard review sizes are 390×844 and 320×694; unusually short embedded panels and enlarged system type need host review.
Accessibility
All actions have button roles and descriptive labels with at least 44 pt hit areas. The ruler has an adjustable role, current inch value, increment/decrement accessibility actions, and both tap and plus/minus alternatives. Width buttons expose their selected state. The recommendation and purchase action include the selected US size. Fit completion and width selection are announced; important fit feedback uses a polite live region.
Reduced motion removes the shoe flight, rotation, spring overshoot, numeric rolling, and blurred pressure pulses. Fit feedback uses opacity transitions; size changes fade in over 200 ms. A separate press value avoids native onPressOut canceling the fit animation.
Icons: Lucide (ISC), copied from the project kit. Tidewell's demo tile, droplet glyph, gradient, and wordmark follow the kit specification. No network artwork or proprietary brand assets are used.




