Slider with Fancy animated text
Description
A tick-mark slider that feels like a physical dial. Instead of a knob on a track, the control is a row of thin vertical lines, one per value, and a small triangle indicator that rides along the top. As you drag, the lines closest to your finger stretch upward and the ones further away fade out, so the slider "bulges" around your touch like a magnifying lens moving across a ruler.
Above the slider, the current value is rendered with a per-character animated text: when the number changes, the outgoing digits shrink and float up while the incoming digits drop into place, and the layout re-flows smoothly when the value goes from one digit to two. Flip the toggle and the same component displays the value as a word (`"twenty-three"` instead of `23`) using the exact same character-level transition.
### Interaction details
- **Drag anywhere** on the row: the indicator jumps to your finger on touch-down, not just from where it currently sits.
- **Snaps on release**: the indicator springs to the nearest tick, and `onValueChange` fires with the rounded integer.
- **Live feedback**: the lines and value label react to the raw finger position while dragging, and only the final rounded value gets committed.
- **Markers**: optional labels underneath (`1x`, `5x`, `10x`, `25x`, `50x` by default) mark the important stops.
### How it's built
- **Reanimated 4 + Gesture Handler.** The whole thing is one `Gesture.Pan()`, and every visual update runs on the UI thread. The JS thread is only touched once, on release, via `scheduleOnRN`.
- **One shared value drives everything.** A single `position` (in pixels) is converted with `useAnimatedReaction` into a fractional `offsetValue` (in tick units) and a `roundedValue`. Each tick line interpolates its `scaleY` and `opacity` against `offsetValue` relative to its own index, so the "bulge" is just an `interpolate` with input range `[index - 3, index - 1, index, index + 1, index + 3]` and `transformOrigin: "bottom center"` so lines grow upward.
- **Spring snap.** On finalize, `position` animates with `withSpring` to `roundedValue * (lineWidth + gap)`, which gives the settle a bit of physicality.
- **Animated text without a text-animation library.** `FancyAnimatedText` splits the value into characters and gives each one a `LinearTransition` layout animation, a `FadeInDown` entering animation, and a custom exiting worklet that scales down and lifts the outgoing character. The key includes both the index and the character, so only the digits that actually changed animate.
- **Value or word.** The label accepts a `SharedValue` or `SharedValue`, so switching to word mode is just passing a `useDerivedValue` that maps the rounded value through a lookup table.
### Props
```ts
console.log(value)}
/>
```
Good fit for anything where the user picks a discrete number and you want the picking itself to feel tactile: multipliers, quantities, zoom levels, tip percentages.
Installation
bunx @animatereactnative/cli@latest add slider-with-fancy-animated-text
npx @animatereactnative/cli@latest add slider-with-fancy-animated-text
yarn @animatereactnative/cli@latest add slider-with-fancy-animated-text
pnpm dlx @animatereactnative/cli@latest add slider-with-fancy-animated-text