"use client"; import { cn } from "@/lib/utils"; import { motion, stagger, useAnimate, useInView } from "motion/react"; import { useEffect } from "react"; export const TypewriterEffect = ({ words, className, cursorClassName, }: { words: { text: string; className?: string; }[]; className?: string; cursorClassName?: string; }) => { // split text inside of words into array of characters const wordsArray = words.map((word) => { return { ...word, text: word.text.split(""), }; }); const [scope, animate] = useAnimate(); const isInView = useInView(scope); useEffect(() => { if (isInView) { animate( "span", { display: "inline-block", opacity: 1, width: "fit-content", }, { duration: 0.3, delay: stagger(0.1), ease: "easeInOut", } ); } }, [isInView]); const renderWords = () => { return ( {wordsArray.map((word, idx) => { return (
{word.text.map((char, index) => ( {char} ))}  
); })}
); }; return (
{renderWords()}
); }; export const TypewriterEffectSmooth = ({ words, className, cursorClassName, }: { words: { text: string; className?: string; }[]; className?: string; cursorClassName?: string; }) => { // split text inside of words into array of characters const wordsArray = words.map((word) => { return { ...word, text: word.text.split(""), }; }); const renderWords = () => { return (
{wordsArray.map((word, idx) => { return (
{word.text.map((char, index) => ( {char} ))}  
); })}
); }; return (
{renderWords()}{" "}
{" "}
); };