shutter-text
jolyui-ui/shutter-textFreeComponent
jolyui/ui publishes no description for this item.
Live preview
live · rendered by the registry
Rendered by jolyui/ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://jolyui.dev/r/shutter-text.jsonSource
1"use client";23import { AnimatePresence, motion, useInView } from "framer-motion";4import {5 type HTMLAttributes,6 useCallback,7 useEffect,8 useRef,9 useState,10} from "react";1112interface ShutterTextProps extends HTMLAttributes<HTMLDivElement> {13 text?: string;14 trigger?: "auto" | "scroll" | "click" | "hover";15}1617export default function ShutterText({18 text = "IMMERSE",19 trigger = "auto",20 className = "",21 ...props22}: ShutterTextProps) {23 const [count, setCount] = useState(0);24 const [active, setActive] = useState(25 trigger === "auto" || trigger === "click" || trigger === "hover",26 );27 const [animating, setAnimating] = useState(trigger === "auto");28 const ref = useRef<HTMLDivElement>(null);29 const isInView = useInView(ref, { once: false, amount: 0.5 });30 const characters = text.split("");3132 // Handle scroll trigger33 useEffect(() => {34 if (trigger === "scroll" && isInView) {35 setActive(true);36 setAnimating(true);37 setCount((c) => c + 1);38 }39 if (trigger === "scroll" && !isInView) {40 setActive(false);41 setAnimating(false);42 }43 }, [trigger, isInView]);4445 // Handle auto trigger – animate once on mount46 useEffect(() => {47 if (trigger === "auto") {48 setActive(true);49 setAnimating(true);50 setCount((c) => c + 1);51 }52 }, [trigger]);5354 const handleClick = useCallback(() => {55 if (trigger === "click") {56 setAnimating(true);57 setCount((c) => c + 1);58 }59 }, [trigger]);6061 const handleMouseEnter = useCallback(() => {62 if (trigger === "hover") {63 setAnimating(true);64 setCount((c) => c + 1);65 }66 }, [trigger]);6768 const handleMouseLeave = useCallback(() => {69 if (trigger === "hover") {70 setAnimating(false);71 }72 }, [trigger]);7374 return (75 <div76 ref={ref}77 role="button"78 tabIndex={0}79 onClick={handleClick}80 onMouseEnter={handleMouseEnter}81 onMouseLeave={handleMouseLeave}82 className={`relative inline-flex flex-wrap items-center justify-center ${className}`}83 {...props}84 >85 <AnimatePresence mode="wait">86 {animating ? (87 <motion.span88 key={count}89 className="flex flex-wrap items-center justify-center"90 >91 {characters.map((char, i) => (92 <span93 key={i}94 className="relative inline-block overflow-hidden px-[0.1vw]"95 >96 {/* Main Character */}97 <motion.span98// … truncated
What it pulls in
npm packages
Files it writes
More from jolyui/ui
All 199 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| ai-prompt-boxai-prompt-box | jolyui/ui | Components | Free | 4 deps | |
| animated-beamanimated-beam | jolyui/ui | Components | Free | 1 dep | |
| animated-tableanimated-table | jolyui/ui | Components | Free | 2 deps | |
| animated-theme-toggleanimated-theme-toggle | jolyui/ui | Components | Free | 2 deps | |
| animated-toastanimated-toast | jolyui/ui | Components | Free | 2 deps | |
| animated-tooltipanimated-tooltip | jolyui/ui | Components | Free | 1 dep | |
| bento-gridbento-grid | jolyui/ui | Components | Free | no deps | |
| buttonbutton | jolyui/ui | Components | Free | 3 deps |
