TheJackBright's picture
Deploy GitHub root master to Space
c296d62
import { useEffect, useRef } from "react";
type Star = {
x: number;
y: number;
z: number;
size: number;
speed: number;
};
function createStars(count: number): Star[] {
return Array.from({ length: count }, () => ({
x: Math.random() * 2 - 1,
y: Math.random() * 2 - 1,
z: Math.random(),
size: Math.random() * 1.4 + 0.25,
speed: Math.random() * 0.00055 + 0.00018,
}));
}
function StarCanvas() {
const canvasRef = useRef<HTMLCanvasElement | null>(null);
useEffect(() => {
const canvas = canvasRef.current;
const context = canvas?.getContext("2d");
if (!canvas || !context) return undefined;
let animationFrame = 0;
let width = 0;
let height = 0;
let centerX = 0;
let centerY = 0;
const stars = createStars(680);
const resize = () => {
const pixelRatio = Math.min(window.devicePixelRatio || 1, 2);
width = window.innerWidth;
height = window.innerHeight;
centerX = width / 2;
centerY = height / 2;
canvas.width = Math.floor(width * pixelRatio);
canvas.height = Math.floor(height * pixelRatio);
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
};
const draw = () => {
context.clearRect(0, 0, width, height);
context.globalCompositeOperation = "lighter";
stars.forEach((star) => {
star.z -= star.speed;
if (star.z <= 0.02) {
star.x = Math.random() * 2 - 1;
star.y = Math.random() * 2 - 1;
star.z = 1;
}
const perspective = 1 / star.z;
const x = centerX + star.x * perspective * centerX;
const y = centerY + star.y * perspective * centerY;
const opacity = Math.max(0, Math.min(1, 1.15 - star.z));
const radius = star.size * perspective * 0.85;
context.beginPath();
context.fillStyle = `rgba(210, 246, 255, ${opacity})`;
context.arc(x, y, radius, 0, Math.PI * 2);
context.fill();
});
animationFrame = window.requestAnimationFrame(draw);
};
resize();
draw();
window.addEventListener("resize", resize);
return () => {
window.removeEventListener("resize", resize);
window.cancelAnimationFrame(animationFrame);
};
}, []);
return <canvas ref={canvasRef} />;
}
export default function MetaverseBackdrop() {
return (
<div className="metaverse-backdrop" aria-hidden="true">
<video className="blackhole-video" autoPlay muted loop playsInline preload="auto">
<source src="/blackhole.webm" type="video/webm" />
</video>
<div className="stars-canvas">
<StarCanvas />
</div>
<div className="nebula-orb orb-one" />
<div className="nebula-orb orb-two" />
<div className="nebula-grid" />
<div className="cosmic-vignette" />
</div>
);
}