Skip to content

Commit 02845a2

Browse files
committed
feat: change icon gaman and add motion frame
1 parent dffa105 commit 02845a2

File tree

7 files changed

+106
-99
lines changed

7 files changed

+106
-99
lines changed

public/img/new/1.png

48.2 KB
Loading

public/img/new/2.png

45.7 KB
Loading

public/img/new/3.png

47.1 KB
Loading

public/img/new/4.png

49.9 KB
Loading

src/components/Navbar.astro

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ import { navbar } from "../utils/content";
1212
class="max-w-[95rem] mx-auto flex items-center justify-between px-4 py-3"
1313
>
1414
<!-- Logo -->
15-
<a href="/" class="text-xl font-bold text-gray-800">
16-
<img class="h-14" src="/img/gaman-logo.png" alt="GamanJS" />
15+
<a href="/" class="text-xl font-bold flex items-center gap-x-2">
16+
<img class="h-14" src="/img/new/2.png" alt="GamanJS" />
17+
<h1 class="text-3xl bg-gradient-to-r from-white to-pink-400 bg-clip-text text-transparent">GamanJS</h1>
1718
</a>
1819

1920
<!-- Hamburger -->
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { useEffect, useState } from "react";
2+
import {
3+
motion,
4+
useScroll,
5+
useTransform,
6+
useMotionValueEvent,
7+
useSpring,
8+
useMotionValue,
9+
} from "framer-motion";
10+
11+
export default function HeroSection() {
12+
const { scrollYProgress, scrollY } = useScroll();
13+
const [direction, setDirection] = useState<"up" | "down">("down");
14+
15+
// ? Deteksi arah scroll
16+
useMotionValueEvent(scrollY, "change", (latest) => {
17+
setDirection((prev) => {
18+
const diff = latest - scrollY.getPrevious()!;
19+
if (diff > 0) return "down";
20+
if (diff < 0) return "up";
21+
return prev;
22+
});
23+
});
24+
25+
// ? Gerakan horizontal (jalan)
26+
const x = useTransform(scrollYProgress, [0, 0.3], ["10vw", "-100vw"]);
27+
const opacity = useTransform(scrollYProgress, [0, 0.1], [0, 1]);
28+
29+
// ? flip gambar pas scroll ke atas
30+
const flip = direction === "up" ? -1 : 1;
31+
32+
// ? Animasi ngangguk (naik-turun kecil)
33+
const y = useMotionValue(0);
34+
35+
useEffect(() => {
36+
let frame: number;
37+
const animate = (t: number) => {
38+
const amplitude = 3; // ? tinggi ngangguk
39+
const speed = 0.005; // ? kecepatan ngangguk
40+
y.set(Math.sin(t * speed) * amplitude);
41+
frame = requestAnimationFrame(animate);
42+
};
43+
frame = requestAnimationFrame(animate);
44+
return () => cancelAnimationFrame(frame);
45+
}, [y]);
46+
47+
const smoothY = useSpring(y, { stiffness: 80, damping: 10 });
48+
49+
return (
50+
<section className="relative flex flex-col items-center justify-center text-center px-6 h-[100dvh] overflow-hidden">
51+
52+
<div className="absolute inset-0 bg-[url('/img/pattern.png')] bg-black/50 bg-blend-multiply before:absolute before:inset-0 before:bg-gradient-to-t before:from-black before:via-black/60 before:to-transparent after:absolute after:inset-0 after:bg-[radial-gradient(ellipse_at_center,_rgba(255,0,150,0.1),_transparent_70%)]" />
53+
54+
<div className="absolute -top-20 -left-32 w-96 h-96 bg-pink-500/20 rounded-full blur-[160px] animate-pulse" />
55+
<div className="absolute -top-20 right-0 w-[28rem] h-[28rem] bg-purple-600/20 rounded-full blur-[180px] animate-pulse delay-1000" />
56+
57+
<div className="relative z-10 flex flex-col items-center">
58+
<h1 className="text-5xl md:text-7xl font-extrabold leading-tight tracking-tight mb-6">
59+
Build{" "}
60+
<span className="bg-gradient-to-r from-pink-400 via-purple-400 to-pink-400 bg-clip-text text-transparent">
61+
Sweet Backends
62+
</span>{" "}
63+
Fast
64+
</h1>
65+
66+
<p className="text-lg md:text-xl md:max-w-3xl text-stone-300 leading-relaxed mb-10">
67+
GamanJS is a modern backend framework built for resilience,
68+
scalability, simplicity, and blazing performance — empowering
69+
developers to build beautiful APIs faster than ever.
70+
</p>
71+
72+
<a
73+
href="/docs"
74+
className="px-8 py-3 rounded-full bg-gradient-to-r from-pink-500 to-purple-500 text-white font-semibold shadow-lg shadow-pink-500/30 hover:shadow-pink-400/50 hover:scale-105 transition-all"
75+
>
76+
Get Started
77+
</a>
78+
</div>
79+
80+
<div className="absolute bottom-0 left-1/2 -translate-x-1/2 w-[90%] h-px bg-gradient-to-r from-transparent via-pink-500/40 to-transparent">
81+
<motion.img
82+
src="/img/new/3.png"
83+
alt="GamanJS Turtle"
84+
style={{
85+
x,
86+
y: smoothY,
87+
opacity,
88+
scaleX: flip, // ? flip arah
89+
}}
90+
transition={{
91+
type: "spring",
92+
stiffness: 60,
93+
damping: 15,
94+
}}
95+
className="absolute bottom-[8px] right-0 w-16 h-auto select-none pointer-events-none"
96+
/>
97+
</div>
98+
</section>
99+
);
100+
}

src/pages/index.astro

Lines changed: 3 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Contributors from "../components/Contributors.tsx";
44
import GamanLivePreview from "../components/GamanLivePreview.tsx";
55
import Footer from "../components/Footer.astro";
66
import Navbar from "../components/Navbar.astro";
7+
import HeroSection from "../components/sections/HeroSection.tsx";
78
import "../styles/global.css";
89
import { features, plugins } from "../utils/content";
910
---
@@ -14,108 +15,13 @@ import { features, plugins } from "../utils/content";
1415
<meta charset="UTF-8" />
1516
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
1617
<title>GamanJS - Backend Framework</title>
17-
<link rel="shortcut icon" href="/img/gaman-big.png" type="image/png" />
18+
<link rel="shortcut icon" href="/img/new/1.png" type="image/png" />
1819
</head>
1920
<body class="bg-black text-pink-100 relative overflow-x-hidden">
2021
<Navbar />
2122

2223
<main class="backdrop-blur-[2px]">
23-
<section
24-
class="relative flex flex-col items-center justify-center text-center px-6 h-[100dvh] overflow-hidden"
25-
>
26-
<div
27-
class="absolute inset-0 bg-[url('/img/pattern.png')] bg-black/50 bg-blend-multiply
28-
before:absolute before:inset-0 before:bg-gradient-to-t before:from-black before:via-black/60 before:to-transparent
29-
after:absolute after:inset-0 after:bg-[radial-gradient(ellipse_at_center,_rgba(255,0,150,0.1),_transparent_70%)]"
30-
>
31-
</div>
32-
33-
<div
34-
class="absolute -top-20 -left-32 w-96 h-96 bg-pink-500/20 rounded-full blur-[160px] animate-pulse"
35-
>
36-
</div>
37-
<div
38-
class="absolute -top-20 right-0 w-[28rem] h-[28rem] bg-purple-600/20 rounded-full blur-[180px] animate-pulse delay-1000"
39-
>
40-
</div>
41-
<div class="relative z-10 flex flex-col items-center">
42-
<h1
43-
class="text-5xl md:text-7xl font-extrabold leading-tight tracking-tight mb-6"
44-
>
45-
Build <span
46-
class="bg-gradient-to-r from-pink-400 via-purple-400 to-pink-400 bg-clip-text text-transparent"
47-
>Sweet Backends</span
48-
> Fast
49-
</h1>
50-
51-
<p
52-
class="text-lg md:text-xl md:max-w-3xl text-stone-300 leading-relaxed mb-10"
53-
>
54-
GamanJS is a modern backend framework built for resilience,
55-
scalability, simplicity, and blazing performance — empowering
56-
developers to build beautiful APIs faster than ever.
57-
</p>
58-
59-
<div class="flex flex-col gap-4 justify-center items-center">
60-
<a
61-
href="/docs"
62-
class="md:w-xs px-8 py-3 rounded-full bg-gradient-to-r from-pink-500 to-purple-500 text-white font-semibold shadow-lg shadow-pink-500/30 hover:shadow-pink-400/50 hover:scale-105 transition-all"
63-
>
64-
Get Started
65-
</a>
66-
<div
67-
class="md:w-xs relative inline-flex items-center justify-between gap-3 px-4 py-2 text-sm font-mono text-stone-200 bg-white/10 border border-white/10 rounded-md backdrop-blur-md hover:bg-white/15 transition shadow-lg shadow-white/10"
68-
>
69-
<span id="command-text" class="select-all"
70-
>{"$"} npm create gaman@latest</span
71-
>
72-
73-
<button
74-
id="copy-btn"
75-
class="px-2 py-0.5 text-xs rounded-md border border-white/20 bg-white/10 hover:bg-white/20 transition"
76-
>
77-
Copy
78-
</button>
79-
</div>
80-
81-
<script>
82-
const copyBtn = document.getElementById("copy-btn");
83-
const cmd = document.getElementById("command-text");
84-
85-
copyBtn?.addEventListener("click", async () => {
86-
try {
87-
const text = cmd?.innerText.replace("$", "").trim();
88-
await navigator.clipboard.writeText(text!);
89-
copyBtn.innerText = "Copied!";
90-
setTimeout(() => (copyBtn.innerText = "Copy"), 1500);
91-
} catch (err) {
92-
console.error("Copy failed:", err);
93-
}
94-
});
95-
</script>
96-
97-
<style>
98-
.transition {
99-
transition: all 0.2s ease-in-out;
100-
}
101-
102-
.backdrop-blur-md {
103-
backdrop-filter: blur(10px);
104-
-webkit-backdrop-filter: blur(10px);
105-
}
106-
107-
.select-all {
108-
user-select: all;
109-
}
110-
</style>
111-
</div>
112-
</div>
113-
114-
<div
115-
class="absolute bottom-0 left-1/2 -translate-x-1/2 w-[90%] h-px bg-gradient-to-r from-transparent via-pink-500/40 to-transparent"
116-
>
117-
</div>
118-
</section>
24+
<HeroSection client:load/>
11925

12026
<!-- END: Hero Content -->
12127

0 commit comments

Comments
 (0)