*, *::before, *::after {
box-sizing: border-box;
}
body {
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
margin: 0;
background: #020617;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.galaxy-container {
position: relative;
width: 100%;
height: 100vh;
}
#galaxy-canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
cursor: crosshair;
}
.galaxy-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 2;
text-align: center;
color: #ffffff;
pointer-events: none;
}
.galaxy-text h2 {
font-size: clamp(3rem, 6vw, 5rem);
margin: 0 0 10px 0;
letter-spacing: 2px;
text-shadow: 0 0 20px rgba(59, 130, 246, 0.8);
}
.galaxy-text p {
font-size: 1.25rem;
color: #94a3b8;
margin: 0;
}
const canvas = document.getElementById("galaxy-canvas");
const ctx = canvas.getContext("2d");
let width = window.innerWidth;
let height = window.innerHeight;
canvas.width = width;
canvas.height = height;
const particles = new Array();
const particleCount = 800;
const mouse = new Object();
mouse.x = width / 2;
mouse.y = height / 2;
window.addEventListener("mousemove", function(e) {
mouse.x = e.clientX;
mouse.y = e.clientY;
});
window.addEventListener("resize", function() {
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width;
canvas.height = height;
});
// Initialize the particle objects
for (let i = 0; i < particleCount; i++) {
const p = new Object();
p.angle = Math.random() * Math.PI * 2;
p.radius = Math.random() * (width / 1.5);
p.speed = (Math.random() * 0.005) + 0.001;
p.size = Math.random() * 2 + 0.5;
p.color = Math.random() > 0.5 ? "#3b82f6" : "#ec4899";
particles.push(p);
}
function draw() {
// Create a slight trailing effect by painting semi-transparent background
ctx.fillStyle = "rgba(2, 6, 23, 0.1)";
ctx.fillRect(0, 0, width, height);
particles.forEach(function(p) {
p.angle += p.speed;
// Determine target location based on angle and radius
const targetX = width / 2 + Math.cos(p.angle) * p.radius;
const targetY = height / 2 + Math.sin(p.angle) * p.radius;
// Check distance to mouse
const dx = mouse.x - targetX;
const dy = mouse.y - targetY;
const dist = Math.sqrt(dx * dx + dy * dy);
let offsetX = 0;
let offsetY = 0;
// Gently pull particles toward the mouse if they get close
if (dist < 250) {
const force = (250 - dist) / 250;
offsetX = dx * force * 0.1;
offsetY = dy * force * 0.1;
}
ctx.beginPath();
ctx.arc(targetX + offsetX, targetY + offsetY, p.size, 0, Math.PI * 2);
ctx.fillStyle = p.color;
ctx.shadowBlur = 10;
ctx.shadowColor = p.color;
ctx.fill();
});
window.requestAnimationFrame(draw);
}
draw();