{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "container-text-scroll", "type": "registry:ui", "title": "Container Text Scroll", "description": "Scroll-triggered text animation component with smooth parallax effects using Framer Motion.", "dependencies": [ "motion" ], "files": [ { "path": "registry/ruixenui/container-text-scroll.tsx", "content": "\"use client\";\nimport React, { useRef } from \"react\";\nimport { useScroll, useTransform, motion, MotionValue } from \"motion/react\";\n\nexport const ContainerTextScroll = ({\n titleComponent,\n children,\n}: {\n titleComponent: string | React.ReactNode;\n children: React.ReactNode;\n}) => {\n const containerRef = useRef(null);\n const { scrollYProgress } = useScroll({ target: containerRef });\n\n const [isMobile, setIsMobile] = React.useState(false);\n React.useEffect(() => {\n const checkMobile = () => setIsMobile(window.innerWidth <= 768);\n checkMobile();\n window.addEventListener(\"resize\", checkMobile);\n return () => window.removeEventListener(\"resize\", checkMobile);\n }, []);\n\n // Scale from smaller to full size as we scroll\n const scaleDimensions = () => (isMobile ? [0.8, 1] : [0.9, 1]);\n\n // Tilt forward from bottom: start 20°, end 0° (straight)\n const rotate = useTransform(scrollYProgress, [0, 1], [-20, 0]);\n const scale = useTransform(scrollYProgress, [0, 1], scaleDimensions());\n const translateY = useTransform(scrollYProgress, [0, 1], [100, 0]); // moves up\n const titleTranslateY = useTransform(scrollYProgress, [0, 1], [100, 0]);\n const titleScale = useTransform(scrollYProgress, [0, 1], [0.8, 1]);\n\n return (\n \n \n {/* Card */}\n \n {children}\n\n {/* Title inside card */}\n \n
{titleComponent}
\n \n
\n \n \n );\n};\n\nexport const Card = ({\n rotate,\n scale,\n children,\n}: {\n rotate: MotionValue;\n scale: MotionValue;\n children: React.ReactNode;\n}) => {\n return (\n \n
\n {children}\n
\n \n );\n};\n", "type": "registry:ui", "target": "components/ruixen/container-text-scroll.tsx" } ] }