Random Letter Swap Pingpong Anim
fancy/random-letter-swap-pingpong-animFreeComponent
A ui component.
Install it
npx shadcn@latest add https://www.fancycomponents.dev/r/random-letter-swap-pingpong-anim.jsonSource
1"use client"23import { useState } from "react"4import { debounce } from "lodash"5import { AnimationOptions, motion, useAnimate } from "motion/react"67interface TextProps {8 label: string9 reverse?: boolean10 transition?: AnimationOptions11 staggerDuration?: number12 className?: string13 onClick?: () => void14}1516const RandomLetterSwapPingPong = ({17 label,18 reverse = true,19 transition = {20 type: "spring",21 duration: 0.8,22 },23 staggerDuration = 0.02,24 className,25 onClick,26 ...props27}: TextProps) => {28 const [scope, animate] = useAnimate()29 const [blocked, setBlocked] = useState(false)3031 const mergeTransition = (transition: AnimationOptions, i: number) => ({32 ...transition,33 delay: i * staggerDuration,34 })3536 const shuffledIndices = Array.from(37 { length: label.length },38 (_, i) => i39 ).sort(() => Math.random() - 0.5)4041 const hoverStart = debounce(42 () => {43 if (blocked) return44 setBlocked(true)4546 for (let i = 0; i < label.length; i++) {47 const randomIndex = shuffledIndices[i]48 animate(49 ".letter-" + randomIndex,50 {51 y: reverse ? "100%" : "-100%",52 },53 mergeTransition(transition, i)54 )5556 animate(57 ".letter-secondary-" + randomIndex,58 {59 top: "0%",60 },61 mergeTransition(transition, i)62 )63 }64 },65 100,66 { leading: true, trailing: true }67 )6869 const hoverEnd = debounce(70 () => {71 setBlocked(false)7273 for (let i = 0; i < label.length; i++) {74 const randomIndex = shuffledIndices[i]75 animate(76 ".letter-" + randomIndex,77 {78 y: 0,79 },80 mergeTransition(transition, i)81 )8283 animate(84 ".letter-secondary-" + randomIndex,85 {86 top: reverse ? "-100%" : "100%",87 },88 mergeTransition(transition, i)89 )90 }91 },92 100,93 { leading: true, trailing: true }94 )9596 return (97 <motion.span98 className={`flex justify-center items-center relative overflow-hidden ${className} `}99 onHoverStart={hoverStart}100 onHoverEnd={hoverEnd}101 onClick={onClick}102 ref={scope}103 {...props}104 >105 <span className="sr-only">{label}</span>106107 {label.split("").map((letter: string, i: number) => {108 return (109 <span110 className="whitespace-pre relative flex"111 key={i}112 aria-hidden={true}113// … truncated
What it pulls in
npm packages
Files it writes
More from fancy
All 158 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Gradient With Svganimated-gradient-with-svg | fancy | Components | Free | no deps | |
| Basic Number Tickerbasic-number-ticker | fancy | Components | Free | 1 dep | |
| Box Carouselbox-carousel | fancy | Components | Free | 1 dep | |
| Breathing Textbreathing-text | fancy | Components | Free | 1 dep | |
| Circling Elementscircling-elements | fancy | Components | Free | 1 dep | |
| Css Boxcss-box | fancy | Components | Free | 1 dep | |
| Cursor Attractor And Gravitycursor-attractor-and-gravity | fancy | Components | Free | 5 deps | |
| Drag Elementsdrag-elements | fancy | Components | Free | 1 dep |
