Skip to content

Commit

Permalink
Abstract into component and style updates
Browse files Browse the repository at this point in the history
  • Loading branch information
Winston-Hsiao committed Sep 7, 2024
1 parent d013d9f commit 0f7a0ab
Show file tree
Hide file tree
Showing 9 changed files with 234 additions and 143 deletions.
2 changes: 1 addition & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const App = () => {
<AuthenticationProvider>
<AlertQueueProvider>
<AlertQueue>
<div className="dark:bg-gray-800 dark:text-white min-h-screen flex flex-col">
<div className="dark:bg-black dark:text-white min-h-screen flex flex-col">
<Navbar />
<div className="flex-grow">
<Container>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const Footer = () => {
}

return (
<footer className="bg-gray-50 dark:bg-gray-800 text-sm py-20">
<footer className="bg-gray-50 dark:bg-gray-900 text-sm py-20">
<div className="flex flex-col gap-4 mx-12 sm:mx-36">
{/* Logo and Social Links */}
<div className="flex flex-row justify-between items-center mb-8">
Expand Down Expand Up @@ -75,7 +75,7 @@ const Footer = () => {
</div>

{/* Footer Links */}
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-12 sm:gap-4">
<div className="flex flex-col items-start gap-2 sm:gap-3">
<h2 className="text-base sm:text-lg font-bold mb-1">Company</h2>
<a
Expand Down
159 changes: 159 additions & 0 deletions frontend/src/components/landing/HeroASCIIArt.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { useEffect, useRef, useState } from "react";

import { useWindowSize } from "hooks/useWindowSize";

import { Meteors } from "components/ui/Meteors";

const HeroASCIIArt = () => {
const asciiRef = useRef<HTMLDivElement>(null);
const [startTime, setStartTime] = useState(0);
const [animationProgress, setAnimationProgress] = useState(0);
const { width: windowWidth, height: windowHeight } = useWindowSize();

useEffect(() => {
if (!asciiRef.current) return;

// Adjust these values to fine-tune the sizing
const charWidth = 7; // Approximate width of a character in pixels
const charHeight = 14; // Approximate height of a character in pixels
const initialPadding = -14; // Start with negative padding to make it larger
const finalPadding = 7; // End with the original padding

const getSize = (progress: number) => {
const currentPadding =
initialPadding + (finalPadding - initialPadding) * progress;
return {
width: Math.floor((windowWidth - currentPadding) / charWidth),
height: Math.floor((windowHeight - currentPadding) / charHeight),
};
};

const textStrings = [
"Meet Stompy Meet Stompy Meet Stompy",
"Program robots easily with K-Lang Program robots easily with K-Lang Program robots easily with K-Lang",
"Affordable and functional humanoid robots Affordable and functional humanoid robots Affordable and functional humanoid robots",
"Meet Stompy Mini Meet Stompy Mini Meet Stompy Mini",
"How to write a walking policy How to write a walking policy",
"How to build a robot How to build a robot",
"Run robot simulations in your browser Run robot simulations in your browser",
"K-Scale has the best robot developer ecosystem K-Scale has the best robot developer ecosystem",
"Download kernel images, robot models, and more Download kernel images, robot models, and more",
"Download URDFs Download URDFs Download URDFs",
"Download Mujoco models Download Mujoco models Download Mujoco models",
"View OnShape models View OnShape models View OnShape models",
"AI-POWERED ROBOTS AI-POWERED ROBOTS AI-POWERED ROBOTS",
"Future of Automation Future of Automation",
"Developing with K-Lang is the easiest way to program robots",
"K-Scale is the best place to learn about robots",
"K-Scale's robot development platform is the best in the world",
"How to train your own robot models How to train your own robot models",
"How to train your own robot policies How to train your own robot policies",
"How to build your own robot How to build your own robot",
"Buy a fully functional humanoid robot Buy a fully functional humanoid robot",
"Stompy can walk and talk Stompy can walk and talk",
"You can control and train Stompy with K-Lang",
"Stompy is the first functional and affordable humanoid robot availble to the public",
];

const kScaleLabsLogo = [
" ",
" ██╗ ██╗ ███████╗ ██████╗ █████╗ ██╗ ███████╗ ██╗ █████╗ ██████╗ ███████╗ ",
" ██║ ██╔╝ ██╔════╝██╔════╝██╔══██╗██║ ██╔════╝ ██║ ██╔══██╗██╔══██╗██╔════╝ ",
" █████╔╝ █████╗███████╗██║ ███████║██║ █████╗ ██║ ███████║██████╔╝███████╗ ",
" ██╔═██╗ ╚════╝╚════██║██║ ██╔══██║██║ ██╔══╝ ██║ ██╔══██║██╔══██╗╚════██║ ",
" ██║ ██╗ ███████║╚██████╗██║ ██║███████╗███████╗ ███████╗██║ ██║██████╔╝███████║ ",
" ╚═╝ ╚═╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝╚══════╝╚══════╝ ╚══════╝╚═╝ ╚═╝╚═════╝ ╚══════╝ ",
" ",
];

const { width, height } = getSize(1);
const logoHeight = kScaleLabsLogo.length;
const logoWidth = kScaleLabsLogo[0].length;
const logoY = Math.floor((height - logoHeight) / 2);
const logoX = Math.floor((width - logoWidth) / 2);

const animate = (timestamp: number) => {
if (!startTime) setStartTime(timestamp);
const elapsed = timestamp - startTime;
const progress = Math.min(1, elapsed / 1500); // 1.5-second animation
setAnimationProgress(progress);

const { width, height } = getSize(progress);

const a = 0.0005 * elapsed * progress;
const logoStabilizationTime = 5000;

let result = "";
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
if (
y >= logoY &&
y < logoY + logoHeight &&
x >= logoX &&
x < logoX + logoWidth
) {
const logoChar = kScaleLabsLogo[y - logoY][x - logoX];
if (elapsed < logoStabilizationTime) {
const t = Math.min(1, elapsed / logoStabilizationTime);
const randomChar = String.fromCharCode(
33 + Math.floor(Math.random() * 94),
);
result += Math.random() < t ? logoChar : randomChar;
} else {
result += logoChar;
}
} else {
const s = 1 - (2 * y) / height;
const o = (2 * x) / width - 1;
const d = Math.sqrt(o * o + s * s);
const l = (0.15 * a) / Math.max(0.1, d);
const f = Math.sin(l);
const b = Math.cos(l);
const u = o * f - s * b;
const m = Math.round(((o * b + s * f + 1) / 2) * width);
const h =
Math.round(((u + 1) / 2) * textStrings.length) %
textStrings.length;
const char =
m < 0 || m >= width || h < 0 || h >= textStrings.length
? " "
: textStrings[h][m] || " ";
result += char;
}
}
result += "\n";
}

// Update the result with responsive sizing
if (asciiRef.current) {
const fontSize = Math.max(
8,
Math.min(12, Math.floor(windowWidth / 100)),
);
asciiRef.current.style.fontSize = `${fontSize}px`;
asciiRef.current.style.lineHeight = "1";
asciiRef.current.textContent = result;
}

requestAnimationFrame(animate);
};

requestAnimationFrame(animate);
}, [windowWidth, windowHeight]);

return (
<div className="relative rounded-lg w-full overflow-hidden">
<div
ref={asciiRef}
className="font-mono text-xs whitespace-pre overflow-hidden mx-2 sm:mx-6 max-w-full max-h-[80vh] bg-gray-900/50 rounded-3xl"
style={{
transform: `scale(${1 + 0.05 * (1 - animationProgress)})`, // Start larger, end at normal size
transition: "transform 0.3s ease-out",
}}
/>
<Meteors />
</div>
);
};

export default HeroASCIIArt;
6 changes: 3 additions & 3 deletions frontend/src/components/landing/LandingCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const LandingCard: React.FC<LandingCardProps> = ({
}) => {
return (
<div
className="bg-white dark:bg-gray-700 rounded-lg shadow-md overflow-hidden cursor-pointer transition-transform hover:scale-105"
className="bg-white dark:bg-gray-900 rounded-lg shadow-md overflow-hidden cursor-pointer transition-transform hover:scale-[1.01] hover:shadow-lg"
onClick={onClick}
>
<img
Expand All @@ -28,12 +28,12 @@ const LandingCard: React.FC<LandingCardProps> = ({
/>
<div className="p-4">
<div className="flex justify-between items-center mb-2">
<h3 className="text-lg font-semibold text-gray-800 dark:text-white">
<h3 className="text-base sm:text-lg font-semibold text-gray-800 dark:text-white">
{title}
</h3>
<Icon className="text-gray-600 dark:text-gray-300" />
</div>
<p className="text-sm text-gray-600 dark:text-gray-300">
<p className="text-xs sm:text-sm text-gray-600 dark:text-gray-300">
{description}
</p>
</div>
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/components/nav/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { useAuthentication } from "hooks/useAuth";
// import { useDarkMode } from "hooks/useDarkMode";
import Sidebar from "components/nav/Sidebar";

const ICON_SIZE = 18;
const ICON_SIZE = 20;

const Navbar = () => {
const [showSidebar, setShowSidebar] = useState<boolean>(false);
Expand All @@ -23,7 +23,7 @@ const Navbar = () => {

return (
<>
<nav className="fixed w-full z-30 top-0 start-0 bg-white/80 dark:bg-gray-800/80 backdrop-blur-sm">
<nav className="fixed w-full z-30 top-0 start-0 bg-white/80 dark:bg-black/80 backdrop-blur-sm">
<div className="flex flex-wrap items-center justify-between p-4">
<a
className="flex items-center active cursor-pointer"
Expand All @@ -46,17 +46,17 @@ const Navbar = () => {
<FaUserCircle size={ICON_SIZE} />
</button>
) : (
<div className="flex items-center gap-1">
<div className="flex items-center gap-2">
<button
onClick={() => navigate("/signup")}
className="flex items-center gap-2 justify-center py-2 px-4 ml-4 rounded-full bg-[#2C514C]/30 hover:bg-[#2C514C]/50 transition-colors tracking-wider"
className="flex items-center gap-2 justify-center py-2 px-4 rounded-full bg-[#2C514C]/30 hover:bg-[#2C514C]/50 transition-colors tracking-wider"
>
<FaUserPlus size={ICON_SIZE} className="text-[#487a73]" />{" "}
Sign Up
</button>
<button
onClick={() => navigate("/login")}
className="flex items-center gap-2 justify-center py-2 px-4 ml-4 rounded-full bg-[#894B6D]/30 hover:bg-[#894B6D]/50 transition-colors tracking-wider"
className="flex items-center gap-2 justify-center py-2 px-4 rounded-full bg-[#894B6D]/30 hover:bg-[#894B6D]/50 transition-colors tracking-wider"
>
<FaSignInAlt size={ICON_SIZE} className="text-[#894B6D]" />{" "}
Sign In
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/pages/BuyStompy.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const BuyStompy = () => {
return (
<section>
<div className="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16">
<div className="py-8 px-4 mx-auto min-h-screen max-w-screen-xl text-center lg:py-16">
<h1 className="mb-8 text-4xl font-extrabold tracking-tight leading-none md:text-5xl lg:text-6xl">
Buy Stompy (In Progress)
</h1>
Expand Down
Loading

0 comments on commit 0f7a0ab

Please sign in to comment.