"use client" import { useRef } from "react" import { motion, useAnimationFrame, useMotionValue, useReducedMotion, useScroll, useSpring, useTransform, useVelocity, } from "motion/react" import { cn } from "@/lib/utils" function wrap(min: number, max: number, value: number) { const range = max - min return ((((value - min) % range) + range) % range) + min } /** * Endless text band. Scrolling speeds it up, scrolling up reverses it. * `baseVelocity` is in percent of one copy per second. */ function VelocityRow({ items, baseVelocity, className, }: { items: string[] baseVelocity: number className?: string }) { const reduced = useReducedMotion() const baseX = useMotionValue(0) const { scrollY } = useScroll() const velocity = useVelocity(scrollY) const smoothVelocity = useSpring(velocity, { damping: 50, stiffness: 400 }) const factor = useTransform(smoothVelocity, [0, 1000], [0, 4], { clamp: false }) const x = useTransform(baseX, (value) => `${wrap(-50, 0, value)}%`) const direction = useRef(1) useAnimationFrame((_, delta) => { if (reduced) return const f = factor.get() if (f < 0) direction.current = -1 else if (f > 0) direction.current = 1 let move = direction.current * baseVelocity * (delta / 1000) move += move * Math.abs(f) baseX.set(baseX.get() + move) }) const content = ( {items.map((item, index) => ( {item} ✦ ))} ) return (