Implement this :"import React, { useRef, useEffect } from 'react';
export function SpaceBackground({ className = '' }) { const canvasRef = useRef(null);
useEffect(() => { const canvas = canvasRef.current; const ctx = canvas.getContext('2d');
// Set canvas dimensions to fill the viewport.
let width = (canvas.width = window.innerWidth);
let height = (canvas.height = window.innerHeight);
let centerX = width / 2;
let centerY = height / 2;
// ------------------------------
// 3D + Perspective + Star Field
// ------------------------------
const focalLength = 400; // Controls how strongly near/far stars appear in perspective.
// Number of stars to render. You can reduce for a sparser sky or increase for denser.
const numStars = 600;
// 3D distribution of stars:
// We'll place them in a sphere of this radius, then rotate that sphere.
const sphereRadius = 500;
// Z offset ensures stars are in front of the camera (camera at z=0, star sphere in front).
const zOffset = 600;
// Generate an array of stars at random positions in a sphere.
const stars = [];
for (let i = 0; i < numStars; i++) {
// Generate random spherical coordinates for uniform distribution.
const u = Math.random();
const v = Math.random();
const theta = 2 * Math.PI * u;
const phi = Math.acos(2 * v - 1);
// Radius in [0..sphereRadius], using cube root for uniform distribution in a sphere.
const r = sphereRadius * Math.cbrt(Math.random());
const x = r * Math.sin(phi) * Math.cos(theta);
const y = r * Math.sin(phi) * Math.sin(theta);
const z = r * Math.cos(phi);
stars.push({ x, y, z });
}
// ------------------------------
// Rotation Parameters
// ------------------------------
let rotationX = 0;
let rotationY = 0;
// **Adjust these rotation speeds to make the stars spin slower/faster.**
// The smaller the values, the slower the rotation.
const rotationSpeedX = 0.0001;
const rotationSpeedY = 0.0002;
// A small, fixed Z-axis tilt for a more pleasing orbit angle.
const fixedRotationZ = Math.PI / 4;
let lastTime = performance.now();
function animate(time) {
const delta = time - lastTime;
lastTime = time;
// Update rotation angles over time (the "spin").
rotationX += rotationSpeedX * delta;
rotationY += rotationSpeedY * delta;
// Clear the previous frame, keeping the gradient behind it visible.
ctx.clearRect(0, 0, width, height);
// For each star, apply 3D rotation, perspective transform, then draw it.
for (let i = 0; i < stars.length; i++) {
let { x, y, z } = stars[i];
// --- 1) 3D Rotation Transformations ---
// Rotate around the X-axis:
const y1 = y * Math.cos(rotationX) - z * Math.sin(rotationX);
const z1 = y * Math.sin(rotationX) + z * Math.cos(rotationX);
// Rotate around the Y-axis:
const x2 = x * Math.cos(rotationY) + z1 * Math.sin(rotationY);
const z2 = -x * Math.sin(rotationY) + z1 * Math.cos(rotationY);
// Fixed rotation around the Z-axis:
const x3 = x2 * Math.cos(fixedRotationZ) - y1 * Math.sin(fixedRotationZ);
const y3 = x2 * Math.sin(fixedRotationZ) + y1 * Math.cos(fixedRotationZ);
const z3 = z2;
// Shift the star forward so it's in front of the camera (camera near z=0).
const zFinal = z3 + zOffset;
// --- 2) Perspective Projection ---
// The scale factor: bigger if zFinal is small, smaller if zFinal is large.
const scale = focalLength / zFinal;
const screenX = x3 * scale + centerX;
const screenY = y3 * scale + centerY;
// Base star size, scaled by perspective so nearer stars appear larger.
const baseSize = 2;
const starSize = baseSize * scale;
// --- 3) Draw Star as White Circle ---
// Here we use a small radial gradient from white to transparent for a soft glow.
const gradient = ctx.createRadialGradient(
screenX,
screenY,
0,
screenX,
screenY,
starSize
);
gradient.addColorStop(0, 'rgba(255,255,255,1)'); // Bright white center
gradient.addColorStop(1, 'rgba(255,255,255,0)'); // Fade to transparent
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(screenX, screenY, starSize, 0, Math.PI * 2);
ctx.fill();
}
// Request the next frame for a smooth animation loop.
requestAnimationFrame(animate);
}
animate(performance.now());
// Keep canvas full-screen on window resize.
const handleResize = () => {
width = (canvas.width = window.innerWidth);
height = (canvas.height = window.innerHeight);
centerX = width / 2;
centerY = height / 2;
};
window.addEventListener('resize', handleResize);
// Cleanup on unmount.
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return (
<div className={fixed inset-0 z-0 ${className}
}>
{/* Keep the same blue-to-black gradient background /}
<div className="absolute inset-0 bg-gradient-to-b from-blue-900 via-black to-black" />
{/ The Canvas that draws our stars */}
<canvas
ref={canvasRef}
style={{ display: 'block', position: 'relative', zIndex: 1 }}
/>
</div>
);
}"
I'll implement the SpaceBackground component for you using React and Next.js. This component creates a beautiful starry night sky effect with rotating stars. Let's break it down and implement it step by step.
understand the code and implement:"import React, { useRef, useEffect } from 'react';
export function SpaceBackground({ className = '' }) { const canvasRef = useRef(null);
useEffect(() => { const canvas = canvasRef.current; const ctx = canvas.getContext('2d');
// Set canvas dimensions to fill the viewport
let width = (canvas.width = window.innerWidth);
let height = (canvas.height = window.innerHeight);
let centerX = width / 2;
let centerY = height / 2;
// ------------------------------
// KEY CHANGES / NEW PARAMETERS:
// ------------------------------
const focalLength = 400; // Perspective factor for near/far size changes.
const numStars = 300; // Decreased star density
const sphereRadius = 1200; // INCREASED sphere radius for bigger coverage
const zOffset = 800; // Shift stars forward so they remain in front of camera
const baseSize = 1; // Decreased star size for a smaller dot appearance
// 3D Rotation speeds:
// Slower rotation for a calm effect
const rotationSpeedX = 0.00005;
const rotationSpeedY = 0.00007;
const fixedRotationZ = Math.PI / 4; // Slight tilt around Z
// ------------------------------
// Generate an array of stars at random positions in a 3D sphere
// with uniform distribution. This includes corners and edges because
// the sphere radius is now larger than the screen size.
// ------------------------------
const stars = [];
for (let i = 0; i < numStars; i++) {
// Random spherical coordinates for uniform distribution:
const u = Math.random();
const v = Math.random();
const theta = 2 * Math.PI * u;
const phi = Math.acos(2 * v - 1);
// Random radius in [0..sphereRadius] (cube root for uniform interior)
const r = sphereRadius * Math.cbrt(Math.random());
const x = r * Math.sin(phi) * Math.cos(theta);
const y = r * Math.sin(phi) * Math.sin(theta);
const z = r * Math.cos(phi);
stars.push({ x, y, z });
}
let rotationX = 0;
let rotationY = 0;
let lastTime = performance.now();
function animate(time) {
const delta = time - lastTime;
lastTime = time;
// Update rotation angles
rotationX += rotationSpeedX * delta;
rotationY += rotationSpeedY * delta;
// Clear previous frame
ctx.clearRect(0, 0, width, height);
// Draw each star with 3D rotation + perspective
for (let i = 0; i < stars.length; i++) {
let { x, y, z } = stars[i];
// Rotate around X
const y1 = y * Math.cos(rotationX) - z * Math.sin(rotationX);
const z1 = y * Math.sin(rotationX) + z * Math.cos(rotationX);
// Rotate around Y
const x2 = x * Math.cos(rotationY) + z1 * Math.sin(rotationY);
const z2 = -x * Math.sin(rotationY) + z1 * Math.cos(rotationY);
// Fixed rotation around Z for a slight tilt
const x3 = x2 * Math.cos(fixedRotationZ) - y1 * Math.sin(fixedRotationZ);
const y3 = x2 * Math.sin(fixedRotationZ) + y1 * Math.cos(fixedRotationZ);
const z3 = z2;
// Shift forward so it's in front of the camera (zOffset)
const zFinal = z3 + zOffset;
// Perspective scale factor (larger if zFinal is small, i.e., closer)
const scale = focalLength / zFinal;
const screenX = x3 * scale + centerX;
const screenY = y3 * scale + centerY;
// Star size adjusted by perspective
const starSize = baseSize * scale;
// "Glossy white" radial gradient:
// - A bright white center
// - Slight fade to a more transparent edge
const gradient = ctx.createRadialGradient(
screenX,
screenY,
0,
screenX,
screenY,
starSize
);
gradient.addColorStop(0, 'rgba(255, 255, 255, 1)'); // Intense white center
gradient.addColorStop(0.5, 'rgba(255, 255, 255, 0.9)'); // Slight fade
gradient.addColorStop(1, 'rgba(255, 255, 255, 0)'); // Fully transparent at edge
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(screenX, screenY, starSize, 0, Math.PI * 2);
ctx.fill();
}
// Animate next frame
requestAnimationFrame(animate);
}
animate(performance.now());
// Keep canvas full-screen on resize
const handleResize = () => {
width = (canvas.width = window.innerWidth);
height = (canvas.height = window.innerHeight);
centerX = width / 2;
centerY = height / 2;
};
window.addEventListener('resize', handleResize);
// Cleanup event listener on unmount
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return (
<div className={fixed inset-0 z-0 ${className}
}>
{/* Blue-to-black gradient background /}
<div className="absolute inset-0 bg-gradient-to-b from-blue-900 via-black to-black" />
{/ Canvas for stars */}
<canvas
ref={canvasRef}
style={{ display: 'block', position: 'relative', zIndex: 1 }}
/>
</div>
);
}"
I'll explain the code and then implement it as a React component in a Next.js project. This code creates a beautiful, animated starry background with a 3D effect.
Now, let's implement this component in a Next.js project: