Skip to content

Commit

Permalink
feat: add initial screen
Browse files Browse the repository at this point in the history
  • Loading branch information
bnleft committed Oct 31, 2024
1 parent be690fa commit 36d89d8
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 4 deletions.
113 changes: 113 additions & 0 deletions app/components/bruh.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { useEffect, useRef, useState } from "react";

export default function Bruh() {
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
const [currentPosition, setCurrentPosition] = useState({ x: 0, y: 0 });
const [isBlinking, setIsBlinking] = useState(false);
const animationFrameRef = useRef<number>();

useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
const x = (e.clientX / window.innerWidth) * 100;
const y = (e.clientY / window.innerHeight) * 100;
setMousePosition({ x, y });
};

window.addEventListener("mousemove", handleMouseMove);
return () => window.removeEventListener("mousemove", handleMouseMove);
}, []);

useEffect(() => {
const blinkInterval = setInterval(() => {
setIsBlinking(true);
setTimeout(() => setIsBlinking(false), 300);
}, 6000);

return () => clearInterval(blinkInterval);
}, []);

// Smooth animation loop
useEffect(() => {
const animate = () => {
setCurrentPosition((prev) => {
// Spring-like movement
const springStrength = 0.08; // Lower = more delay and smoothing
const dx = (mousePosition.x - prev.x) * springStrength;
const dy = (mousePosition.y - prev.y) * springStrength;

return {
x: prev.x + dx,
y: prev.y + dy,
};
});

animationFrameRef.current = requestAnimationFrame(animate);
};

animationFrameRef.current = requestAnimationFrame(animate);

return () => {
if (animationFrameRef.current) {
cancelAnimationFrame(animationFrameRef.current);
}
};
}, [mousePosition]);

const calculatePosition = () => {
const moveX = (currentPosition.x - 50) / 15;
const moveY = (currentPosition.y - 50) / 15;
const maxMove = 4;
const scale = 30;
return {
x: Math.min(Math.max(moveX, -maxMove), maxMove) * scale,
y: Math.min(Math.max(moveY, -maxMove), maxMove) * scale,
};
};

const { x, y } = calculatePosition();

return (
<div className="relative">
<svg
width="60"
height="60"
viewBox="0 0 600 600"
className="overflow-visible"
>
{/* Face */}
<circle cx="300" cy="300" r="300" className="fill-royal-yellow" />

{/* Eyes */}
{[198, 401].map((cx, index) => (
<g key={index} transform={`translate(${x} ${y})`}>
<ellipse
cx={cx}
cy="218"
rx="40"
ry={isBlinking ? 4 : 10}
className="fill-bruh-eye"
>
<animate
attributeName="ry"
values="5;1;5"
dur="0.3s"
begin={isBlinking ? "0s" : "indefinite"}
/>
</ellipse>
</g>
))}

{/* Mouth */}
<g transform={`translate(${x} ${y})`}>
<ellipse
cx="307"
cy="378"
rx="120"
ry="10"
className="fill-bruh-mouth"
/>
</g>
</svg>
</div>
);
}
18 changes: 18 additions & 0 deletions app/components/input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { cn } from "@/lib/utils";

export default function Input() {
return (
<div>
<input
type="text"
className={cn(
"w-full rounded-full py-2 px-4",
"text-[#E1E1E1] text-sm placeholder:text-[#9C9890]",
"bg-[#262626] border border-[#363636]",
"focus:outline-none focus:border-[#464646]",
)}
placeholder="Talk to Bruh..."
/>
</div>
);
}
4 changes: 2 additions & 2 deletions app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import "@/root.css";

export default function App() {
return (
<html lang="en">
<html lang="en" className="h-full">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body>
<body className="h-full overscroll-none font-neon">
<Outlet />
<Scripts />
</body>
Expand Down
11 changes: 9 additions & 2 deletions app/routes/_index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Bruh from "@/components/bruh";
import Input from "@/components/input";
import type { MetaFunction } from "@remix-run/node";

export const meta: MetaFunction = () => {
Expand All @@ -6,8 +8,13 @@ export const meta: MetaFunction = () => {

export default function Index() {
return (
<div>
<h1 className="text-red-500 text-3xl">Index</h1>
<div className="h-full flex flex-col bg-[#1d1d1d]">
<div className="flex-[4] flex justify-center items-center">
<Bruh />
</div>
<div className="flex-[1] flex justify-center items-center">
<Input />
</div>
</div>
);
}

0 comments on commit 36d89d8

Please sign in to comment.