2024-11-28Bruno Fernandes

Gekkou

Like chasing after that moon

Image

Demo

1"use client";
2
3const backgroundLayerStars = 200;
4const middleLayerStars = 100;
5const foregroundLayerStars = 50;
6
7function createStars(n: number) {
8  return Array.from({ length: n })
9    .map(() => {
10      const x = Math.floor(Math.random() * 2000) - 2000 / 4;
11      const y = Math.floor(Math.random() * 2000) - 2000 / 4;
12      return `${x}px ${y}px 1px white`;
13    })
14    .join(",");
15}
16
17export default function Gekkou() {
18  const starLayers = [
19    {
20      stars: backgroundLayerStars,
21      size: "w-0.5 h-0.5",
22      speed: "40s",
23      zIndex: "z-10",
24    },
25    {
26      stars: middleLayerStars,
27      size: "w-1 h-1",
28      speed: "60s",
29      zIndex: "z-20",
30    },
31    {
32      stars: foregroundLayerStars,
33      size: "w-1.5 h-1.5",
34      speed: "80s",
35      zIndex: "z-30",
36    },
37  ];
38
39  return (
40    <div className="h-screen w-screen grid place-items-center bg-white saturate-200">
41      <div
42        className="w-[500px] h-[500px] bg-gradient-to-b from-[#0b042e] to-[#292465]
43      shadow-lg shadow-gray-900 relative overflow-hidden
44      "
45      >
46        {starLayers.map((layer) => (
47          <div
48            key={layer.zIndex}
49            style={{
50              boxShadow: createStars(layer.stars),
51              animation: `star-movement ${layer.speed} linear infinite`,
52              animationDelay: `-${parseFloat(layer.speed) / 2}s`,
53            }}
54            className={`${layer.size} ${layer.zIndex} rounded-full absolute`}
55          ></div>
56        ))}
57        <div className="h-full w-full grid place-items-center">
58          <div className="bg-black h-72 w-72 rounded-full z-40 shadow-lg shadow-white grid place-items-center">
59            <span className="[text-shadow:0_0_10px_white] text-4xl font-bold text-white">
60              月光
61            </span>
62          </div>
63          <div className="absolute z-50 bottom-0 left-1/2 rounded-full shadow-[0px_0px_200px_50px_#eeadb1,0px_0px_150px_#6354a2]" />
64        </div>
65      </div>
66      <style jsx>
67        {`
68          @keyframes star-movement {
69            0% {
70              transform: translate(800px, 800px);
71            }
72            100% {
73              transform: translate(-1200px, -1200px);
74            }
75          }
76        `}
77      </style>
78    </div>
79  );
80}
81