Skip to content

Commit 32bd747

Browse files
authored
Redesign home page with hero section (#19)
2 parents 874e930 + 91c4749 commit 32bd747

File tree

4 files changed

+98
-15
lines changed

4 files changed

+98
-15
lines changed

src/app/home.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { AppGitHubReadme } from "@/components/libresplit/AppGitHubReadme";
2+
import { AppHero } from "@/components/libresplit/AppHero";
23

34
export function Home() {
45
return (
5-
<div>
6+
<div className="flex flex-col items-center justify-center">
7+
<AppHero />
68
<AppGitHubReadme />
79
</div>
810
);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { TextScramble } from "../ui/text-scramble";
2+
3+
export function AppHero() {
4+
return (
5+
<div className="flex flex-col items-center justify-center">
6+
<img
7+
src="https://raw.githubusercontent.com/LibreSplit/LibreSplit/refs/heads/main/assets/libresplit.svg"
8+
alt="LibreSplit"
9+
className="w-64"
10+
/>
11+
<p className="text-bold text-6xl">LibreSplit</p>
12+
<TextScramble characterSet="_" speed={28}>
13+
Free speedrun timer with auto splitting and load removal for Linux.
14+
</TextScramble>
15+
</div>
16+
);
17+
}

src/components/libresplit/AppNav.tsx

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,23 @@ export function AppNav() {
1515
<LeftNav />
1616
</div>
1717

18-
<NavigationMenu>
19-
<NavigationMenuList>
20-
<NavigationMenuItem>
21-
<NavigationMenuLink asChild>
22-
<Link to="/">Home</Link>
23-
</NavigationMenuLink>
24-
</NavigationMenuItem>
18+
<div className="absolute left-1/2 -translate-x-1/2">
19+
<NavigationMenu>
20+
<NavigationMenuList>
21+
<NavigationMenuItem>
22+
<NavigationMenuLink asChild>
23+
<Link to="/">Home</Link>
24+
</NavigationMenuLink>
25+
</NavigationMenuItem>
2526

26-
<NavigationMenuItem>
27-
<NavigationMenuLink asChild>
28-
<Link to="/converter">Converter</Link>
29-
</NavigationMenuLink>
30-
</NavigationMenuItem>
31-
</NavigationMenuList>
32-
</NavigationMenu>
27+
<NavigationMenuItem>
28+
<NavigationMenuLink asChild>
29+
<Link to="/converter">Converter</Link>
30+
</NavigationMenuLink>
31+
</NavigationMenuItem>
32+
</NavigationMenuList>
33+
</NavigationMenu>
34+
</div>
3335

3436
<div className="flex items-center">
3537
<RightNav />
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
"use client";
2+
3+
import { useEffect, useState } from "react";
4+
5+
import { motion } from "framer-motion";
6+
7+
interface TextScrambleProps {
8+
children: string;
9+
speed?: number;
10+
characterSet?: string;
11+
className?: string;
12+
}
13+
14+
const DEFAULT_CHARS =
15+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
16+
17+
function getRandomChar(charSet: string) {
18+
return charSet[Math.floor(Math.random() * charSet.length)];
19+
}
20+
21+
export const TextScramble = ({
22+
children,
23+
speed = 50,
24+
characterSet = DEFAULT_CHARS,
25+
className,
26+
...motionProps
27+
}: TextScrambleProps) => {
28+
const [text, setText] = useState(children);
29+
30+
useEffect(() => {
31+
let step = 0;
32+
const interval = setInterval(() => {
33+
let scrambled = "";
34+
35+
for (let i = 0; i < children.length; i++) {
36+
if (i < step) {
37+
scrambled += children[i];
38+
} else if (children[i] === " ") {
39+
scrambled += " ";
40+
} else {
41+
scrambled += getRandomChar(characterSet);
42+
}
43+
}
44+
45+
setText(scrambled);
46+
step++;
47+
48+
if (step > children.length) {
49+
clearInterval(interval);
50+
setText(children);
51+
}
52+
}, speed);
53+
54+
return () => clearInterval(interval);
55+
}, [children, speed, characterSet]);
56+
57+
return (
58+
<motion.span className={className} {...motionProps}>
59+
{text}
60+
</motion.span>
61+
);
62+
};

0 commit comments

Comments
 (0)