Skip to content
Native Animation
Gooey Merge Slider animation preview
Skia

Gooey Merge Slider

A premium multi-layer sound mixer whose slider thumbs shed and reclaim liquid droplets at speed.

$9 for this animation

Checkout opens soon. Leave your email and we will tell you the moment you can buy it.

One email when checkout opens. No spam.

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.

npx nativeanimation add gooey-merge-slider

About this animation

A premium multi-layer sound mixer whose slider thumbs shed and reclaim liquid droplets at speed.

Why this one

Most liquid sliders stop at a soft blob or a decorative wave. This one connects the interaction to the material: velocity pulls a daughter droplet from the thumb, a real blurred alpha threshold fuses the forms, values roll in sync, and release energy returns as a restrained ripple. The included Tidal demo places the control in a credible soundscape product with responsive atmosphere instead of presenting it as an isolated experiment.

How it works

  1. Each row owns one continuous normalized progress value; thumb position, fill length, and displayed percentage all derive from it.
  2. Gesture Handler updates progress directly on the UI thread and passes release velocity into an interruptible spring.
  3. Skia draws the fill, thumb, and velocity-reactive daughter droplet into a layer with blur and an alpha-threshold ColorMatrix, producing a genuine metaball merge.
  4. A short release value expands a fine ring around the thumb, while a layout-synchronized text transition rolls the numeric value.
  5. The imperative API coordinates the three launch animations without adding demo concerns to the reusable component.

Icons: Lucide (ISC).

Install

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

On web, follow Expo's Skia setup so CanvasKit is loaded before this component is rendered.

Usage

import GooeyMergeSlider from './GooeyMergeSlider';

export function Mixer() {
  return <GooeyMergeSlider />;
}
import { useRef } from 'react';
import GooeyMergeSlider, {
  type GooeyMergeSliderRef,
} from './GooeyMergeSlider';

export function CustomMixer() {
  const ref = useRef<GooeyMergeSliderRef>(null);

  return (
    <GooeyMergeSlider
      ref={ref}
      rowGap={18}
      trackColor="rgba(255,255,255,0.1)"
      onValueChangeEnd={(index, value) => {
        // Persist the settled value for the selected layer.
      }}
    />
  );
}

Props

NameTypeDefaultDescription
itemsGooeyMergeSliderItem[]Rain, Ocean, and WindLabels, Lucide icons, colors, and target values.
onValueChange(index, value) => void—Runs when a rounded value changes.
onValueChangeEnd(index, value) => void—Runs after a drag or track tap settles.
fontFamilystringSystemLabel font family.
monoFontFamilystringSystemNumeric value font family.
trackColorstringrgba(255,255,255,0.08)Unfilled track color.
rowGapnumber22Vertical space between rows.
accessibilityLabelstringSoundscapePrefix for each adjustable control label.
styleStyleProp<ViewStyle>—Outer-container styling.
testIDstring—Test identifier.

The ref exposes playIntro(), setValue(index, value), and reset().

Compatibility

  • Expo SDK 57
  • React Native 0.86
  • Reanimated 4.5
  • React Native Worklets 0.10
  • React Native Skia 2.6
  • iOS: unverified
  • Android: unverified
  • Web: verified by export and bundle checks; visual review pending
  • Expo Go: supported because every native dependency is included in this project's Expo Go runtime

Accessibility

Every row exposes the adjustable role, current value, and increment/decrement actions. The full 54-point track is tappable as an alternative to dragging. Reduce Motion places the sliders at their final values, removes the velocity trail and ripple, and keeps value changes immediate.