81 lines
2.8 KiB
TypeScript
81 lines
2.8 KiB
TypeScript
"use client";
|
|
import { motion } from "framer-motion";
|
|
import { useState } from "react";
|
|
|
|
export default function ObservatoryBackground() {
|
|
const [stars] = useState(() =>
|
|
Array.from({ length: 120 }).map((_, i) => ({
|
|
id: i,
|
|
left: `${Math.random() * 100}%`,
|
|
top: `${Math.random() * 70}%`,
|
|
size: Math.random() * 2 + 1,
|
|
duration: 3 + Math.random() * 4,
|
|
delay: Math.random() * 5,
|
|
}))
|
|
);
|
|
|
|
const [skyline] = useState(() => {
|
|
const colors = ['#0b1420ff', '#0d1015ff', '#020408'];
|
|
const neons = ['#22d3ee', '#fb7185', '#60a5fa', '#ffffff', '#c084fc'];
|
|
|
|
return Array.from({ length: 65 }).map((_, i) => ({
|
|
id: i,
|
|
width: `${1.2 + Math.random() * 2.5}%`,
|
|
height: `${8 + Math.random() * 30}%`,
|
|
color: colors[i % colors.length],
|
|
neon: neons[Math.floor(Math.random() * neons.length)],
|
|
hasWindow: Math.random() > 0.4,
|
|
}));
|
|
});
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-[-1] bg-[#02040a] overflow-hidden">
|
|
|
|
<div
|
|
className="absolute bottom-[-20%] left-1/2 -translate-x-1/2 w-[120%] h-[80%] opacity-50"
|
|
style={{
|
|
background: 'radial-gradient(circle at center bottom, #1e3a8a 0%, #050a24 50%, transparent 80%)',
|
|
filter: 'blur(40px)'
|
|
}}
|
|
/>
|
|
|
|
{stars.map((star) => (
|
|
<motion.div
|
|
key={star.id}
|
|
className="absolute bg-white rounded-full shadow-[0_0_3px_rgba(255,255,255,0.8)]"
|
|
style={{ top: star.top, left: star.left, width: star.size, height: star.size }}
|
|
animate={{ opacity: [0.2, 0.7, 0.2] }}
|
|
transition={{ duration: star.duration, repeat: Infinity, delay: star.delay }}
|
|
/>
|
|
))}
|
|
|
|
<div
|
|
className="absolute bottom-0 w-full h-[30%] flex items-end justify-center px-4"
|
|
style={{
|
|
WebkitMaskImage: 'linear-gradient(to right, transparent 0%, black 15%, black 85%, transparent 100%)',
|
|
maskImage: 'linear-gradient(to right, transparent 0%, black 15%, black 85%, transparent 100%)'
|
|
}}
|
|
>
|
|
{skyline.map((b) => (
|
|
<div
|
|
key={b.id}
|
|
className="relative flex-shrink-0"
|
|
style={{
|
|
width: b.width,
|
|
height: b.height,
|
|
backgroundColor: b.color,
|
|
backgroundImage: `repeating-linear-gradient(transparent, transparent 3px, rgba(255,255,255,0.01) 3px, rgba(255,255,255,0.01) 4px)`,
|
|
}}
|
|
>
|
|
<div
|
|
className="absolute top-0 left-0 w-full h-[1px] opacity-30"
|
|
style={{ backgroundColor: b.neon, boxShadow: `0 0 8px ${b.neon}` }}
|
|
/>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<div className="absolute bottom-0 w-full h-16 bg-gradient-to-t from-[#02040a] to-transparent" />
|
|
</div>
|
|
);
|
|
} |