From 16464aabd75fdfc05367626db638619de5f54630 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Thu, 13 Jun 2024 16:42:50 +0530 Subject: [PATCH] add typewrite-effect for title Signed-off-by: Amit Amrutiya --- frontend/src/app/page.tsx | 33 ++- .../src/components/ui/typewriter-effect.tsx | 190 ++++++++++++++++++ 2 files changed, 221 insertions(+), 2 deletions(-) create mode 100644 frontend/src/components/ui/typewriter-effect.tsx diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 3e0897d..28a5771 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -5,9 +5,36 @@ import Navbar from "@/components/Navbar"; import { FlipWords } from "@/components/ui/filp-word"; import GlobeSection from "@/components/Globe"; import { Spotlight } from "@/components/ui/spot-light"; +import { TypewriterEffectSmooth } from "@/components/ui/typewriter-effect"; export default function Home() { const words = ["Omegal", "Google Meet", "Whatsapp"]; + const typewords = [ + { + text: "All", + }, + { + text: "in", + }, + { + text: "one", + }, + { + text: "Website", + }, + { + text: "for", + }, + { + text: "Meet", + }, + { + text: "and", + }, + { + text: "Chat", + } + ]; return (
@@ -17,8 +44,10 @@ export default function Home() {
- Miss - ?
All in one Website for Meet +

+ Miss ? +

+
diff --git a/frontend/src/components/ui/typewriter-effect.tsx b/frontend/src/components/ui/typewriter-effect.tsx new file mode 100644 index 0000000..084325d --- /dev/null +++ b/frontend/src/components/ui/typewriter-effect.tsx @@ -0,0 +1,190 @@ +"use client"; + +import { cn } from "@/lib/utils"; +import { motion, stagger, useAnimate, useInView } from "framer-motion"; +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()}{" "} +
{" "} +
+ +
+ ); +};