Morphing Text
magicui/morphing-textFreeComponent
A dynamic text morphing component for Magic UI.
Live preview
live · rendered by the registry
Rendered by magicui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://magicui.design/r/morphing-text.jsonSource
1"use client"23import { useCallback, useEffect, useRef } from "react"45import { cn } from "@/lib/utils"67const morphTime = 1.58const cooldownTime = 0.5910const useMorphingText = (texts: string[]) => {11 const textIndexRef = useRef(0)12 const morphRef = useRef(0)13 const cooldownRef = useRef(0)14 const timeRef = useRef(new Date())1516 const text1Ref = useRef<HTMLSpanElement>(null)17 const text2Ref = useRef<HTMLSpanElement>(null)1819 const setStyles = useCallback(20 (fraction: number) => {21 const [current1, current2] = [text1Ref.current, text2Ref.current]22 if (!current1 || !current2) return2324 current2.style.filter = `blur(${Math.min(8 / fraction - 8, 100)}px)`25 current2.style.opacity = `${Math.pow(fraction, 0.4) * 100}%`2627 const invertedFraction = 1 - fraction28 current1.style.filter = `blur(${Math.min(29 8 / invertedFraction - 8,30 10031 )}px)`32 current1.style.opacity = `${Math.pow(invertedFraction, 0.4) * 100}%`3334 current1.textContent = texts[textIndexRef.current % texts.length]35 current2.textContent = texts[(textIndexRef.current + 1) % texts.length]36 },37 [texts]38 )3940 const doMorph = useCallback(() => {41 morphRef.current -= cooldownRef.current42 cooldownRef.current = 04344 let fraction = morphRef.current / morphTime4546 if (fraction > 1) {47 cooldownRef.current = cooldownTime48 fraction = 149 }5051 setStyles(fraction)5253 if (fraction === 1) {54 textIndexRef.current++55 }56 }, [setStyles])5758 const doCooldown = useCallback(() => {59 morphRef.current = 060 const [current1, current2] = [text1Ref.current, text2Ref.current]61 if (current1 && current2) {62 current2.style.filter = "none"63 current2.style.opacity = "100%"64 current1.style.filter = "none"65 current1.style.opacity = "0%"66 }67 }, [])6869 useEffect(() => {70 let animationFrameId: number7172 const animate = () => {73 animationFrameId = requestAnimationFrame(animate)7475 const newTime = new Date()76 const dt = (newTime.getTime() - timeRef.current.getTime()) / 100077 timeRef.current = newTime7879 cooldownRef.current -= dt8081 if (cooldownRef.current <= 0) doMorph()82 else doCooldown()83 }8485 animate()86 return () => {87 cancelAnimationFrame(animationFrameId)88 }89 }, [doMorph, doCooldown])9091 return { text1Ref, text2Ref }92}9394interface MorphingTextProps {95 className?: string96 texts: string[]97}9899// … truncated
Files it writes
More from magicui
All 247 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Androidandroid | magicui | Components | Free | no deps | |
| Animated Beamanimated-beam | magicui | Components | Free | 1 dep | |
| Animated Circular Progress Baranimated-circular-progress-bar | magicui | Components | Free | no deps | |
| Animated Gradient Textanimated-gradient-text | magicui | Components | Free | no deps | |
| Animated Grid Patternanimated-grid-pattern | magicui | Components | Free | 1 dep | |
| Animated Listanimated-list | magicui | Components | Free | 1 dep | |
| Animated Shiny Textanimated-shiny-text | magicui | Components | Free | no deps | |
| Theme Toggleranimated-theme-toggler | magicui | Components | Free | 1 dep |
