Skip to content

Commit

Permalink
feat: update animation and text place
Browse files Browse the repository at this point in the history
  • Loading branch information
amir-abxn committed Dec 18, 2024
1 parent 866c903 commit 3075324
Showing 1 changed file with 59 additions and 73 deletions.
132 changes: 59 additions & 73 deletions components/landing/animated-headline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,21 @@ import { motion } from "framer-motion"
import { useEffect, useMemo, useState } from "react"
import { PageSection } from "../page-section"

type letters = "F" | "R" | "K" | "N"

const animation = {
initial: { width: 0 },
animate: { width: "auto" },
transition: { duration: 1, ease: "easeInOut" },
style: {
overflow: "hidden",
display: "inline-block",
whiteSpace: "nowrap",
},
}

export function AnimatedHeadline() {
const words: Record<"F" | "R" | "K" | "N", string[]> = useMemo(
const words: Record<letters, string[]> = useMemo(
() => ({
F: [
"Freedom",
Expand All @@ -24,85 +37,58 @@ export function AnimatedHeadline() {
[],
)

const [currentIndex, setCurrentIndex] = useState(0)
const [currentWords, setCurrentWords] = useState({
F: words.F[0],
R: words.R[0],
K: words.K[0],
N: words.N[0],
})

const keysDict: Record<letters, Array<letters>> = {
F: ["R", "K", "N"],
R: ["F", "K", "N"],
K: ["F", "R", "N"],
N: ["F", "R", "K"],
}

const [lastKey, setLastKey] = useState<keyof typeof keysDict>("F")

useEffect(() => {
const interval = setInterval(() => {
setCurrentIndex((prev) => (prev + 1) % words.F.length)
}, 3000)
return () => clearInterval(interval)
}, [words.F.length])
const randomKey = keysDict[lastKey][
Math.floor(Math.random() * keysDict[lastKey].length)
] as letters

const animations = useMemo(
() => [
{
initial: { width: 0 },
animate: { width: "auto" },
transition: { duration: 1, ease: "easeInOut" },
style: {
overflow: "hidden",
display: "inline-block",
whiteSpace: "nowrap",
},
},
{
initial: { opacity: 0, x: -20 },
animate: { opacity: 1, x: 0 },
transition: { duration: 0.5 },
style: {},
},
{
initial: { scale: 0 },
animate: { scale: 1 },
transition: { duration: 0.5 },
style: {},
},
{
initial: { opacity: 0 },
animate: { opacity: 1 },
transition: { duration: 0.5 },
style: {},
},
],
[],
)

const getRandomAnimation = () =>
animations[Math.floor(Math.random() * animations.length)]
const randomWord =
words[randomKey as keyof typeof words][
Math.floor(
Math.random() * words[randomKey as keyof typeof words].length,
)
]
setCurrentWords((prev) => ({ ...prev, [randomKey]: randomWord }))
setLastKey(randomKey)
}, 2000)
return () => clearInterval(interval)
}, [words, lastKey])

return (
<PageSection className="md:py-8">
<h2
className="w-fit mx-auto py-8 font-mono font-bold text-4xl"
style={{ minWidth: "200px", textAlign: "center" }}
>
FRKN:
<div className="flex flex-col items-center">
{["F", "R", "K", "N"].map((key, index) => {
const word =
words[key as keyof typeof words][
currentIndex % words[key as keyof typeof words].length
]
const animation = getRandomAnimation()

if (!animation) {
return null
}

return (
<motion.div
key={`${word}-${currentIndex}-${index}`}
initial={animation.initial}
animate={animation.animate}
transition={{ ...animation.transition, delay: index * 0.5 }}
style={animation.style}
>
{word}
</motion.div>
)
})}
</div>
</h2>
<div className="w-fit flex gap-3 mx-auto py-8 font-mono font-bold text-sm md:text-xl lg:text-3xl xl:text-4xl">
FRKN:{" "}
{["F", "R", "K", "N"].map((key, index) => {
return (
<motion.span
key={`${currentWords[key]}-${index}`}
initial={animation.initial}
animate={key === lastKey ? animation.animate : { width: "auto" }}
transition={animation.transition}
style={animation.style}
>
{`${currentWords[key]}${index !== 3 ? "," : ""}`}
</motion.span>
)
})}
</div>
</PageSection>
)
}

0 comments on commit 3075324

Please sign in to comment.