-
-
Notifications
You must be signed in to change notification settings - Fork 173
Replace old hero with minimal star animations #1122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ea010d8
99d3e14
f67cbef
3f47964
382575f
e52c462
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,140 +1,239 @@ | ||||||||||||||||||||||||||||||||||||||||||
| "use client"; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| import { useState } from "react"; | ||||||||||||||||||||||||||||||||||||||||||
| import "atropos/css"; | ||||||||||||||||||||||||||||||||||||||||||
| import Atropos from "atropos/react"; | ||||||||||||||||||||||||||||||||||||||||||
| import Image from "next/image"; | ||||||||||||||||||||||||||||||||||||||||||
| import space from "public/images/home/space.jpg"; | ||||||||||||||||||||||||||||||||||||||||||
| import rocketman from "public/images/home/rocketman.png"; | ||||||||||||||||||||||||||||||||||||||||||
| import moon from "public/images/home/moon.png"; | ||||||||||||||||||||||||||||||||||||||||||
| import React, { useState, useEffect } from "react"; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| export default function Hero() { | ||||||||||||||||||||||||||||||||||||||||||
| const [rocketLoaded, setRocketLoaded] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||
| const [moonLoaded, setMoonLoaded] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||
| const [starsLoaded, setStarsLoaded] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const isReady = rocketLoaded && moonLoaded && starsLoaded; | ||||||||||||||||||||||||||||||||||||||||||
| const CoduLogo = ({ className }: { className?: string }) => { | ||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||
| <svg | ||||||||||||||||||||||||||||||||||||||||||
| xmlns="http://www.w3.org/2000/svg" | ||||||||||||||||||||||||||||||||||||||||||
| width="463" | ||||||||||||||||||||||||||||||||||||||||||
| height="150" | ||||||||||||||||||||||||||||||||||||||||||
| fill="none" | ||||||||||||||||||||||||||||||||||||||||||
| viewBox="0 0 463 150" | ||||||||||||||||||||||||||||||||||||||||||
| className={className} | ||||||||||||||||||||||||||||||||||||||||||
| aria-label="Codú logo" | ||||||||||||||||||||||||||||||||||||||||||
| role="img" | ||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||
| <path | ||||||||||||||||||||||||||||||||||||||||||
| fill="#fff" | ||||||||||||||||||||||||||||||||||||||||||
| fillRule="evenodd" | ||||||||||||||||||||||||||||||||||||||||||
| d="M187 150a50 50 0 1 0 0-100 50 50 0 0 0 0 100Zm0-18a32 32 0 1 0 0-64 32 32 0 0 0 0 64Z" | ||||||||||||||||||||||||||||||||||||||||||
| clipRule="evenodd" | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
| <path | ||||||||||||||||||||||||||||||||||||||||||
| fill="#fff" | ||||||||||||||||||||||||||||||||||||||||||
| d="M415.75 6.36a9 9 0 0 1 12.73 12.73l-18.39 18.39a9 9 0 0 1-12.73-12.73l18.39-18.39Z" | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
| <path | ||||||||||||||||||||||||||||||||||||||||||
| fill="#fff" | ||||||||||||||||||||||||||||||||||||||||||
| fillRule="evenodd" | ||||||||||||||||||||||||||||||||||||||||||
| d="M341 0a9 9 0 0 0-9 9v52.58A50 50 0 1 0 350 100V9a9 9 0 0 0-9-9Zm-9 100a32 32 0 1 0-64 0 32 32 0 0 0 64 0Z" | ||||||||||||||||||||||||||||||||||||||||||
| clipRule="evenodd" | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
| <path | ||||||||||||||||||||||||||||||||||||||||||
| fill="#fff" | ||||||||||||||||||||||||||||||||||||||||||
| d="M121.46 121.88c3.5 3.53 3.5 9.28-.42 12.33a75 75 0 1 1-.05-118.45c3.93 3.05 3.93 8.8.44 12.33-3.5 3.53-9.17 3.5-13.2.6a57 57 0 1 0 .03 92.6c4.04-2.9 9.7-2.94 13.2.59ZM363 59a9 9 0 1 1 18 0v41a32 32 0 0 0 64 0V59a9 9 0 1 1 18 0v82a9 9 0 1 1-18 0v-2.58A50 50 0 0 1 363 100V59Z" | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
| </svg> | ||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const handleScroll = (id: string) => { | ||||||||||||||||||||||||||||||||||||||||||
| const element = document.getElementById(id); | ||||||||||||||||||||||||||||||||||||||||||
| if (element) { | ||||||||||||||||||||||||||||||||||||||||||
| element.scrollIntoView({ behavior: "smooth" }); | ||||||||||||||||||||||||||||||||||||||||||
| const NightSky = () => { | ||||||||||||||||||||||||||||||||||||||||||
| const styles = ` | ||||||||||||||||||||||||||||||||||||||||||
| @keyframes twinkle { | ||||||||||||||||||||||||||||||||||||||||||
| 0%, 100% { opacity: 0.3; } | ||||||||||||||||||||||||||||||||||||||||||
| 50% { opacity: 0.7; } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| @keyframes gentleMove1 { | ||||||||||||||||||||||||||||||||||||||||||
| 0%, 100% { transform: translate(0, 0); } | ||||||||||||||||||||||||||||||||||||||||||
| 50% { transform: translate(3px, 2px); } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| @keyframes gentleMove2 { | ||||||||||||||||||||||||||||||||||||||||||
| 0%, 100% { transform: translate(0, 0); } | ||||||||||||||||||||||||||||||||||||||||||
| 50% { transform: translate(-2px, 4px); } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| @keyframes gentleMove3 { | ||||||||||||||||||||||||||||||||||||||||||
| 0%, 100% { transform: translate(0, 0); } | ||||||||||||||||||||||||||||||||||||||||||
| 50% { transform: translate(4px, -3px); } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| @keyframes shootingStar { | ||||||||||||||||||||||||||||||||||||||||||
| 0% { transform: translate(0, 0); opacity: 1; } | ||||||||||||||||||||||||||||||||||||||||||
| 100% { transform: translate(300px, 300px); opacity: 0; } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| .twinkle { animation: twinkle 4s ease-in-out infinite; } | ||||||||||||||||||||||||||||||||||||||||||
| .gentle-move1 { animation: gentleMove1 25s ease-in-out infinite; } | ||||||||||||||||||||||||||||||||||||||||||
| .gentle-move2 { animation: gentleMove2 30s ease-in-out infinite; } | ||||||||||||||||||||||||||||||||||||||||||
| .gentle-move3 { animation: gentleMove3 35s ease-in-out infinite; } | ||||||||||||||||||||||||||||||||||||||||||
| .shooting-star { | ||||||||||||||||||||||||||||||||||||||||||
| position: absolute; | ||||||||||||||||||||||||||||||||||||||||||
| width: 4px; | ||||||||||||||||||||||||||||||||||||||||||
| height: 4px; | ||||||||||||||||||||||||||||||||||||||||||
| background: white; | ||||||||||||||||||||||||||||||||||||||||||
| border-radius: 50%; | ||||||||||||||||||||||||||||||||||||||||||
| top: -4px; | ||||||||||||||||||||||||||||||||||||||||||
| left: -4px; | ||||||||||||||||||||||||||||||||||||||||||
| animation: shootingStar 1.5s linear; | ||||||||||||||||||||||||||||||||||||||||||
| animation-iteration-count: 1; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| `; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const [shootingStars, setShootingStars] = useState<number[]>([]); | ||||||||||||||||||||||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||||||||||||||||||||||
| const createShootingStar = () => { | ||||||||||||||||||||||||||||||||||||||||||
| const id = Date.now(); | ||||||||||||||||||||||||||||||||||||||||||
| setShootingStars((prev) => [...prev, id]); | ||||||||||||||||||||||||||||||||||||||||||
| setTimeout(() => { | ||||||||||||||||||||||||||||||||||||||||||
| setShootingStars((prev) => prev.filter((starId) => starId !== id)); | ||||||||||||||||||||||||||||||||||||||||||
| }, 1500); // Match the duration of the shooting star animation | ||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const interval = setInterval(() => { | ||||||||||||||||||||||||||||||||||||||||||
| if (Math.random() < 0.3) { | ||||||||||||||||||||||||||||||||||||||||||
| // 30% chance every 3 seconds | ||||||||||||||||||||||||||||||||||||||||||
| createShootingStar(); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| }, 3000); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| return () => clearInterval(interval); | ||||||||||||||||||||||||||||||||||||||||||
| }, []); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const starPositions = [ | ||||||||||||||||||||||||||||||||||||||||||
| { x: 10, y: 15 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 25, y: 30 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 40, y: 10 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 60, y: 40 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 75, y: 20 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 5, y: 50 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 30, y: 70 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 50, y: 85 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 80, y: 60 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 90, y: 35 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 15, y: 25 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 35, y: 45 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 55, y: 15 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 70, y: 55 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 85, y: 30 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 20, y: 65 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 45, y: 80 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 65, y: 5 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 95, y: 45 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 8, y: 90 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 28, y: 18 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 48, y: 38 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 68, y: 78 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 88, y: 22 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 12, y: 72 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 32, y: 92 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 52, y: 62 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 72, y: 42 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 92, y: 82 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 18, y: 52 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 38, y: 32 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 58, y: 72 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 78, y: 12 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 98, y: 58 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 3, y: 83 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 23, y: 3 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 43, y: 93 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 63, y: 33 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 83, y: 73 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 7, y: 37 }, | ||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const seededRandom = (function () { | ||||||||||||||||||||||||||||||||||||||||||
| const seed = 12345; // You can change this seed to get a different, but consistent, pattern | ||||||||||||||||||||||||||||||||||||||||||
| let state = seed; | ||||||||||||||||||||||||||||||||||||||||||
| return function () { | ||||||||||||||||||||||||||||||||||||||||||
| state = (state * 1664525 + 1013904223) % 4294967296; | ||||||||||||||||||||||||||||||||||||||||||
| return state / 4294967296; | ||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||
| })(); | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+143
to
+150
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Move Seeded Random Function Outside Component to Avoid Re-initialization The Consider moving the - const NightSky = () => {
- const seededRandom = (function () {
+ // Simple pseudo-random number generator
+ const seededRandom = (function () {
const seed = 12345; // You can change this seed to get a different, but consistent, pattern
let state = seed;
return function () {
state = (state * 1664525 + 1013904223) % 4294967296;
return state / 4294967296;
};
})();
+ const NightSky = () => {
// ... rest of the componentThis change ensures that the random number generator maintains its state between renders, leading to consistent star patterns. 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const generateStars = () => { | ||||||||||||||||||||||||||||||||||||||||||
| return starPositions.map((pos, i) => ( | ||||||||||||||||||||||||||||||||||||||||||
| <circle | ||||||||||||||||||||||||||||||||||||||||||
| key={i} | ||||||||||||||||||||||||||||||||||||||||||
| cx={pos.x} | ||||||||||||||||||||||||||||||||||||||||||
| cy={pos.y} | ||||||||||||||||||||||||||||||||||||||||||
| r={seededRandom() * 0.15 + 0.05} | ||||||||||||||||||||||||||||||||||||||||||
| fill="white" | ||||||||||||||||||||||||||||||||||||||||||
| opacity={seededRandom() * 0.5 + 0.3} | ||||||||||||||||||||||||||||||||||||||||||
| className={seededRandom() > 0.7 ? "twinkle" : ""} | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
| )); | ||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const generateAnimatedStars = () => { | ||||||||||||||||||||||||||||||||||||||||||
| const animatedStarPositions = [ | ||||||||||||||||||||||||||||||||||||||||||
| { x: 20, y: 20 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 45, y: 55 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 70, y: 30 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 85, y: 75 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 15, y: 80 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 55, y: 25 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 35, y: 65 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 65, y: 50 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 10, y: 40 }, | ||||||||||||||||||||||||||||||||||||||||||
| { x: 90, y: 10 }, | ||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||
| return animatedStarPositions.map((pos, i) => ( | ||||||||||||||||||||||||||||||||||||||||||
| <circle | ||||||||||||||||||||||||||||||||||||||||||
| key={`animated-${i}`} | ||||||||||||||||||||||||||||||||||||||||||
| cx={pos.x} | ||||||||||||||||||||||||||||||||||||||||||
| cy={pos.y} | ||||||||||||||||||||||||||||||||||||||||||
| r={seededRandom() * 0.2 + 0.1} | ||||||||||||||||||||||||||||||||||||||||||
| fill="white" | ||||||||||||||||||||||||||||||||||||||||||
| opacity={seededRandom() * 0.5 + 0.5} | ||||||||||||||||||||||||||||||||||||||||||
| className={`gentle-move${(i % 3) + 1}`} | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
| )); | ||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||
| <main className="relative"> | ||||||||||||||||||||||||||||||||||||||||||
| <Atropos | ||||||||||||||||||||||||||||||||||||||||||
| rotateXMax={0.4} | ||||||||||||||||||||||||||||||||||||||||||
| rotateYMax={0.4} | ||||||||||||||||||||||||||||||||||||||||||
| stretchX={1} | ||||||||||||||||||||||||||||||||||||||||||
| stretchY={0.2} | ||||||||||||||||||||||||||||||||||||||||||
| stretchZ={0.3} | ||||||||||||||||||||||||||||||||||||||||||
| highlight={false} | ||||||||||||||||||||||||||||||||||||||||||
| className="relative h-[calc(100vh_-_100px)] max-h-[calc(100svh_-_100px)] w-full overflow-hidden sm:h-[900px] [&>span.atropos-scale]:pointer-events-none [&_span.atropos-rotate]:pointer-events-auto" | ||||||||||||||||||||||||||||||||||||||||||
| <div className="night-sky-container relative h-full w-full"> | ||||||||||||||||||||||||||||||||||||||||||
| <style>{styles}</style> | ||||||||||||||||||||||||||||||||||||||||||
| <svg | ||||||||||||||||||||||||||||||||||||||||||
| xmlns="http://www.w3.org/2000/svg" | ||||||||||||||||||||||||||||||||||||||||||
| viewBox="0 0 100 100" | ||||||||||||||||||||||||||||||||||||||||||
| preserveAspectRatio="xMidYMid slice" | ||||||||||||||||||||||||||||||||||||||||||
| style={{ background: "transparent", width: "100%", height: "100%" }} | ||||||||||||||||||||||||||||||||||||||||||
| className="absolute inset-0" | ||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||
| <Image | ||||||||||||||||||||||||||||||||||||||||||
| placeholder="blur" | ||||||||||||||||||||||||||||||||||||||||||
| className="absolute -z-10 h-full w-full object-cover" | ||||||||||||||||||||||||||||||||||||||||||
| src={space} | ||||||||||||||||||||||||||||||||||||||||||
| data-atropos-offset="-2" | ||||||||||||||||||||||||||||||||||||||||||
| alt="Realistic space sky which is black with stars scattered across." | ||||||||||||||||||||||||||||||||||||||||||
| onLoad={() => { | ||||||||||||||||||||||||||||||||||||||||||
| setStarsLoaded(true); | ||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| <div className="absolute -bottom-28 left-0 right-0 -z-10 mx-auto max-h-[480px] max-w-[480px] sm:-bottom-60 sm:max-h-[800px] sm:max-w-[600px] md:-bottom-96 md:max-h-[800px] md:max-w-[800px]"> | ||||||||||||||||||||||||||||||||||||||||||
| <div className="relative mx-auto brightness-75"> | ||||||||||||||||||||||||||||||||||||||||||
| <Image | ||||||||||||||||||||||||||||||||||||||||||
| src={moon} | ||||||||||||||||||||||||||||||||||||||||||
| data-atropos-offset="1" | ||||||||||||||||||||||||||||||||||||||||||
| alt="Photograph of the moon" | ||||||||||||||||||||||||||||||||||||||||||
| sizes="100vw" | ||||||||||||||||||||||||||||||||||||||||||
| style={{ | ||||||||||||||||||||||||||||||||||||||||||
| width: "100%", | ||||||||||||||||||||||||||||||||||||||||||
| height: "auto", | ||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||
| onLoad={() => { | ||||||||||||||||||||||||||||||||||||||||||
| setMoonLoaded(true); | ||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||
| <div className="absolute right-0 top-10 h-[240px] w-[240px] md:-right-28 md:h-[350px] md:w-[350px]"> | ||||||||||||||||||||||||||||||||||||||||||
| <Image | ||||||||||||||||||||||||||||||||||||||||||
| height={350} | ||||||||||||||||||||||||||||||||||||||||||
| width={350} | ||||||||||||||||||||||||||||||||||||||||||
| src={rocketman} | ||||||||||||||||||||||||||||||||||||||||||
| data-atropos-offset="8" | ||||||||||||||||||||||||||||||||||||||||||
| alt="3D claymation style model of a astronaut on a rocket" | ||||||||||||||||||||||||||||||||||||||||||
| sizes="100vw" | ||||||||||||||||||||||||||||||||||||||||||
| style={{ | ||||||||||||||||||||||||||||||||||||||||||
| width: "100%", | ||||||||||||||||||||||||||||||||||||||||||
| height: "auto", | ||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||
| onLoad={() => { | ||||||||||||||||||||||||||||||||||||||||||
| setRocketLoaded(true); | ||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||
| {generateStars()} | ||||||||||||||||||||||||||||||||||||||||||
| {generateAnimatedStars()} | ||||||||||||||||||||||||||||||||||||||||||
| </svg> | ||||||||||||||||||||||||||||||||||||||||||
| {shootingStars.map((id) => ( | ||||||||||||||||||||||||||||||||||||||||||
| <div key={id} className="shooting-star" /> | ||||||||||||||||||||||||||||||||||||||||||
| ))} | ||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| <div | ||||||||||||||||||||||||||||||||||||||||||
| data-atropos-offset="0" | ||||||||||||||||||||||||||||||||||||||||||
| className="flex h-full flex-col justify-center" | ||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||
| <Image | ||||||||||||||||||||||||||||||||||||||||||
| width={340} | ||||||||||||||||||||||||||||||||||||||||||
| height={200} | ||||||||||||||||||||||||||||||||||||||||||
| src="/images/codu.svg" | ||||||||||||||||||||||||||||||||||||||||||
| alt="Codú logo" | ||||||||||||||||||||||||||||||||||||||||||
| className={`mx-auto w-[240px] object-contain transition duration-500 sm:w-[340px] ${ | ||||||||||||||||||||||||||||||||||||||||||
| isReady ? "opacity-100" : "opacity-0" | ||||||||||||||||||||||||||||||||||||||||||
| }`} | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
| export default function Hero() { | ||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||
| <div className="relative w-full bg-neutral-950"> | ||||||||||||||||||||||||||||||||||||||||||
| <div className="absolute inset-0 bg-gradient-to-b from-black via-transparent to-black"></div> | ||||||||||||||||||||||||||||||||||||||||||
| <section | ||||||||||||||||||||||||||||||||||||||||||
| className="relative mx-auto h-[500px] max-w-5xl overflow-hidden rounded sm:h-[600px]" | ||||||||||||||||||||||||||||||||||||||||||
| aria-labelledby="hero-heading" | ||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||
| <NightSky /> | ||||||||||||||||||||||||||||||||||||||||||
| <div className="absolute left-1/2 top-1/2 z-10 w-full max-w-3xl -translate-x-1/2 -translate-y-1/2 transform space-y-4 px-4 text-center sm:px-6 lg:px-8"> | ||||||||||||||||||||||||||||||||||||||||||
| <CoduLogo className="mx-auto mb-8 h-16 sm:h-20" aria-hidden="true" /> | ||||||||||||||||||||||||||||||||||||||||||
| <h1 | ||||||||||||||||||||||||||||||||||||||||||
| className={`mt-8 text-center text-5xl font-extrabold tracking-tight text-white drop-shadow-2xl duration-500 sm:text-7xl ${ | ||||||||||||||||||||||||||||||||||||||||||
| isReady ? "opacity-100" : "opacity-0" | ||||||||||||||||||||||||||||||||||||||||||
| }`} | ||||||||||||||||||||||||||||||||||||||||||
| id="hero-heading" | ||||||||||||||||||||||||||||||||||||||||||
| className="text-2xl font-semibold text-white sm:text-4xl md:text-4xl" | ||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||
| A{" "} | ||||||||||||||||||||||||||||||||||||||||||
| <span className="bg-gradient-to-r from-orange-400 to-pink-600 bg-clip-text text-transparent"> | ||||||||||||||||||||||||||||||||||||||||||
| space | ||||||||||||||||||||||||||||||||||||||||||
| </span>{" "} | ||||||||||||||||||||||||||||||||||||||||||
| for coders | ||||||||||||||||||||||||||||||||||||||||||
| The <span className="font-extrabold text-pink-600">free</span> web | ||||||||||||||||||||||||||||||||||||||||||
| developer community | ||||||||||||||||||||||||||||||||||||||||||
| </h1> | ||||||||||||||||||||||||||||||||||||||||||
| <div className="mt-12 flex justify-center"> | ||||||||||||||||||||||||||||||||||||||||||
| <button | ||||||||||||||||||||||||||||||||||||||||||
| aria-label="Scroll to call to action" | ||||||||||||||||||||||||||||||||||||||||||
| className="focus-style-rounded animate-bounce rounded-full border-2 bg-neutral-900 bg-opacity-60 p-4" | ||||||||||||||||||||||||||||||||||||||||||
| onClick={() => handleScroll("cta")} | ||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||
| <svg | ||||||||||||||||||||||||||||||||||||||||||
| xmlns="http://www.w3.org/2000/svg" | ||||||||||||||||||||||||||||||||||||||||||
| fill="none" | ||||||||||||||||||||||||||||||||||||||||||
| viewBox="0 0 24 24" | ||||||||||||||||||||||||||||||||||||||||||
| strokeWidth={1.5} | ||||||||||||||||||||||||||||||||||||||||||
| stroke="#ffffff" | ||||||||||||||||||||||||||||||||||||||||||
| className="h-8 w-8" | ||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||
| <path | ||||||||||||||||||||||||||||||||||||||||||
| strokeLinecap="round" | ||||||||||||||||||||||||||||||||||||||||||
| strokeLinejoin="round" | ||||||||||||||||||||||||||||||||||||||||||
| d="M19.5 5.25l-7.5 7.5-7.5-7.5m15 6l-7.5 7.5-7.5-7.5" | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
| </svg> | ||||||||||||||||||||||||||||||||||||||||||
| </button> | ||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||
| <p className="mx-auto max-w-2xl text-sm text-neutral-300 sm:text-base md:text-lg"> | ||||||||||||||||||||||||||||||||||||||||||
| {`Codú's community offers hundreds of tutorials, an online community, and answers | ||||||||||||||||||||||||||||||||||||||||||
| questions on a wide range of web development topics. Sign up for a free account today | ||||||||||||||||||||||||||||||||||||||||||
| and join the community.`} | ||||||||||||||||||||||||||||||||||||||||||
| </p> | ||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||
| <div | ||||||||||||||||||||||||||||||||||||||||||
| className="absolute bottom-0 h-20 w-full bg-gradient-to-t from-black" | ||||||||||||||||||||||||||||||||||||||||||
| data-atropos-offset="-2" | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
| <div | ||||||||||||||||||||||||||||||||||||||||||
| className="absolute top-0 h-20 w-full bg-gradient-to-b from-black" | ||||||||||||||||||||||||||||||||||||||||||
| data-atropos-offset="-2" | ||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||
| </Atropos> | ||||||||||||||||||||||||||||||||||||||||||
| </main> | ||||||||||||||||||||||||||||||||||||||||||
| </section> | ||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider Moving Inline Styles to External CSS
The
stylesvariable contains CSS defined as a template literal and is injected into a<style>tag within the component. While this approach works, it can make the code harder to maintain and can lead to duplication if multiple components need similar styles.Consider moving these styles to an external CSS file, a CSS module, or using a CSS-in-JS solution like styled-components or Emotion. This will improve code organization, enable reuse, and make it easier to manage styles across the project.