Storytelling Landing Page - Copy this React, Tailwind Component to your project
Import React, { useState, useEffect, useRef } from "react"; import { motion, useScroll, useTransform } from "framer motion"; import { FaArrowDown } from "react icons/fa"; const ScrollText: React.FC = () => { const [activeWordIndex, setActiveWordIndex] = useState<number>(0); const containerRef = useRef<HTMLDivElement>(null); const { scrollYProgress } = useScroll({ target: containerRef, offset: ["start", "end start"], }); const words: string[] = [ "Once", "upon", "a", "time", "in", "a", "digital", "realm", "far", "far", "away", ]; const backgroundY = useTransform(scrollYProgress, [0, 1], ["0%", "50%"]); const textY = useTransform(scrollYProgress, [0, 1], ["0%", "100%"]); useEffect(() => { const handleScroll = () => { if (containerRef.current) { const container = containerRef.current; const scrollPosition = window.scrollY; const containerHeight = container.clientHeight; const windowHeight = window.innerHeight; const scrollPercentage = scrollPosition / (containerHeight windowHeight); const newActiveWordIndex = Math.min( Math.floor(scrollPercentage * words.length), words.length 1 ); setActiveWordIndex(newActiveWordIndex); } }; window.addEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll); }, [words.length]); return ( <div ref={containerRef} className="relative h [200vh] overflow hidden bg gradient to b from purple 900 to indigo 900 text white text center" > <motion.div className="absolute inset 0 bg [url('https://images.unsplash.com/photo 1534796636912 3b95b3ab5986?ixlib=rb 4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2071&q=80')] bg cover bg center" style={{ y: backgroundY }} /> <div className="absolute inset 0 bg black opacity 50" /> <motion.div className="absolute inset 0 flex flex col items center justify center px 4" style={{ y: textY }} > <h1 className="text 4xl sm:text 6xl md:text 7xl font bold text center mb 8"> {words.map((word, index) => ( <motion.span key={index} className="inline block mx 2" initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: index * 0.1 }} style={{ WebkitTextStroke: "2px #FCD34D", color: index <= activeWordIndex ? "#FCD34D" : "transparent", transition: "color 0.3s ease in out", }} > {word} </motion.span> ))} </h1> <motion.button className="bg yellow 400 text purple 900 px 6 py 3 rounded full font semibold text lg hover:bg yellow 300 transition colors duration 300 focus:outline none focus:ring 2 focus:ring yellow 500 focus:ring opacity 50" whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }} onClick={() => alert("You clicked the magical button!")} > Explore the Story </motion.button> </motion.div> <motion.div className="absolute bottom 4 left 1/2 transform translate x 1/2 text white text 2xl animate bounce" initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 1, duration: 1 }} > <FaArrowDown /> </motion.div> </div> ); }; export default ScrollText; make the text white and bring it to the center of screen
