Letter Swap Pingpong Anim
fancy/letter-swap-pingpong-animFreeComponent
A ui component.
Install it
npx shadcn@latest add https://www.fancycomponents.dev/r/letter-swap-pingpong-anim.jsonSource
1"use client"23import { useState } from "react"4import { debounce } from "lodash"5import { AnimationOptions, motion, stagger, useAnimate } from "motion/react"67interface TextProps {8 label: string9 reverse?: boolean10 transition?: AnimationOptions11 staggerDuration?: number12 staggerFrom?: "first" | "last" | "center" | number13 className?: string14 onClick?: () => void15}1617const LetterSwapPingPong = ({18 label,19 reverse = true,20 transition = {21 type: "spring",22 duration: 0.7,23 },24 staggerDuration = 0.03,25 staggerFrom = "first",26 className,27 onClick,28 ...props29}: TextProps) => {30 const [scope, animate] = useAnimate()31 const [isHovered, setIsHovered] = useState(false)3233 const mergeTransition = (baseTransition: AnimationOptions) => ({34 ...baseTransition,35 delay: stagger(staggerDuration, {36 from: staggerFrom,37 }),38 })3940 const hoverStart = debounce(41 () => {42 if (isHovered) return43 setIsHovered(true)4445 animate(46 ".letter",47 { y: reverse ? "100%" : "-100%" },48 mergeTransition(transition)49 )5051 animate(52 ".letter-secondary",53 {54 top: "0%",55 },56 mergeTransition(transition)57 )58 },59 100,60 { leading: true, trailing: true }61 )6263 const hoverEnd = debounce(64 () => {65 setIsHovered(false)6667 animate(68 ".letter",69 {70 y: 0,71 },72 mergeTransition(transition)73 )7475 animate(76 ".letter-secondary",77 {78 top: reverse ? "-100%" : "100%",79 },80 mergeTransition(transition)81 )82 },83 100,84 { leading: true, trailing: true }85 )8687 return (88 <motion.span89 className={`flex justify-center items-center relative overflow-hidden ${className} `}90 onHoverStart={hoverStart}91 onHoverEnd={hoverEnd}92 onClick={onClick}93 ref={scope}94 {...props}95 >96 <span className="sr-only">{label}</span>9798 {label.split("").map((letter: string, i: number) => {99 return (100 <span101 className="whitespace-pre relative flex"102 key={i}103 aria-hidden={true}104 >105 <motion.span className={`relative letter`} style={{ top: 0 }}>106 {letter}107 </motion.span>108 <motion.span109 className="absolute letter-secondary "110 style={{ top: reverse ? "-100%" : "100%" }}111 >112 {letter}113 </motion.span>114// … 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 |
