Ripple to Still
Installation
npx shadcn@latest add https://uibrik.com/r/ripple-to-still.jsonInstall the packages
npm install motionCopy the source into your project
components/uibrik/ripple-to-still/ripple-to-still.tsx"use client"; import { animate } from "motion/react"; import { useEffect, useId, useRef } from "react"; import { EASE_OUT, TEXT, type EffectProps } from "../_text-effects/shared"; // 22 — The line starts wobbling like a reflection in water; the ripple calms // until the letters are sharp. Turbulence feeds a displacement map whose // strength runs down to zero while its frequency drifts, so the ripples move. export function RippleToStill({ play, text = "Still water", duration = 1.4, strength = 16, }: EffectProps & { text?: string; /** Seconds for the ripple to calm. */ duration?: number; /** Starting displacement in px. */ strength?: number; }) { const id = `liquid-${useId().replace(/[^a-zA-Z0-9]/g, "")}`; const noiseRef = useRef<SVGFETurbulenceElement>(null); const mapRef = useRef<SVGFEDisplacementMapElement>(null); useEffect(() => { if (!play) return; const controls = animate(1, 0, { duration, ease: EASE_OUT, onUpdate: (t) => { mapRef.current?.setAttribute("scale", String(strength * t)); noiseRef.current?.setAttribute("baseFrequency", `${0.012 + 0.012 * (1 - t)} ${0.06 + 0.04 * t}`); }, }); return () => controls.stop(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [play]); return ( <> <svg width="0" height="0" aria-hidden="true" className="absolute"> <filter id={id} x="-20%" y="-60%" width="140%" height="220%"> <feTurbulence ref={noiseRef} type="turbulence" baseFrequency="0.012 0.06" numOctaves="2" seed="4" /> <feDisplacementMap ref={mapRef} in="SourceGraphic" scale="0" xChannelSelector="R" yChannelSelector="G" /> </filter> </svg> <p className={TEXT} style={{ filter: `url(#${id})` }}> {text} </p> </> ); }
Adds the files to
components/uibrik/ripple-to-still and installs motion. With the @uibrik namespace set up: npx shadcn@latest add @uibrik/ripple-to-still.Props
RippleToStill- text
- Type string
- "Still water"
- The copy to animate.
- duration
- Type number
- 1.4
- Time for the ripple to calm.
- strength
- Type number
- 16
- Starting displacement.
- playrequired
- Type number
- –
- Each change plays the effect again; 0 shows its resting state.