Skip to content

Commit

Permalink
add typewrite-effect for title
Browse files Browse the repository at this point in the history
Signed-off-by: Amit Amrutiya <[email protected]>
  • Loading branch information
amitamrutiya committed Jun 13, 2024
1 parent ea6c62b commit 16464aa
Show file tree
Hide file tree
Showing 2 changed files with 221 additions and 2 deletions.
33 changes: 31 additions & 2 deletions frontend/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<main className="h-dvh overflow-auto">
<Spotlight className="-top-40 left-0 md:left-60 md:-top-20" />
Expand All @@ -17,8 +44,10 @@ export default function Home() {
<div
className={`min-h-10vh text-2xl sm:text-3xl md:text-4xl lg:text-5xl xl:text-6xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-purple-400 via-pink-500 to-red-500 cursor-pointer animate-fadeIn my-5`}
>
Miss <FlipWords words={words} />
? <br /> All in one Website for Meet
<p>
Miss <FlipWords words={words} />?
</p>
<TypewriterEffectSmooth words={typewords} />
</div>
<div className="flex flex-col-reverse lg:flex-row min-h-[80ovh]">
<section className="flex-grow lg:w-2/3 flex flex-wrap justify-center items-center">
Expand Down
190 changes: 190 additions & 0 deletions frontend/src/components/ui/typewriter-effect.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<motion.div ref={scope} className="inline">
{wordsArray.map((word, idx) => {
return (
<div key={`word-${idx}`} className="inline-block">
{word.text.map((char, index) => (
<motion.span
initial={{}}
key={`char-${index}`}
className={cn(
`dark:text-white text-black opacity-0 hidden`,
word.className
)}
>
{char}
</motion.span>
))}
&nbsp;
</div>
);
})}
</motion.div>
);
};
return (
<div
className={cn(
"text-base sm:text-xl md:text-3xl lg:text-5xl font-bold text-center",
className
)}
>
{renderWords()}
<motion.span
initial={{
opacity: 0,
}}
animate={{
opacity: 1,
}}
transition={{
duration: 0.8,
repeat: Infinity,
repeatType: "reverse",
}}
className={cn(
"inline-block rounded-sm w-[4px] h-4 md:h-6 lg:h-10 bg-blue-500",
cursorClassName
)}
></motion.span>
</div>
);
};

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 (
<div>
{wordsArray.map((word, idx) => {
return (
<div key={`word-${idx}`} className="inline-block">
{word.text.map((char, index) => (
<span
key={`char-${index}`}
className={cn(
`text-2xl sm:text-3xl md:text-4xl lg:text-5xl xl:text-6xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-purple-400 via-pink-500 to-red-500 `,
word.className
)}
>
{char}
</span>
))}
&nbsp;
</div>
);
})}
</div>
);
};

return (
<div className={cn("flex space-x-1 my-6", className)}>
<motion.div
className="overflow-hidden pb-2"
initial={{
width: "0%",
}}
whileInView={{
width: "fit-content",
}}
transition={{
duration: 2,
ease: "linear",
delay: 1,
}}
>
<div
className="text-xs sm:text-base md:text-xl lg:text:3xl xl:text-5xl font-bold"
style={{
whiteSpace: "nowrap",
}}
>
{renderWords()}{" "}
</div>{" "}
</motion.div>
<motion.span
initial={{
opacity: 0,
}}
animate={{
opacity: 1,
}}
transition={{
duration: 0.8,

repeat: Infinity,
repeatType: "reverse",
}}
className={cn(
"block rounded-sm w-[4px] h-4 sm:h-6 xl:h-12 bg-blue-500",
cursorClassName
)}
></motion.span>
</div>
);
};

0 comments on commit 16464aa

Please sign in to comment.