<canvas id="canvas"></canvas>
HTML
格式化
支持Emmet,输入 p 后按 Tab键试试吧!
<head> ... </head>
<body>
</body>
CSS
格式化
body {
margin: 0;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: black;
}
canvas {
border: 1px solid white;
}
JS
格式化
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const numParticles = 1500; // Increased to 3x
const particles = [];
const bubbles = [];
const plankton = [];
const jellyfish = [];
const lightShafts = [];
const mouse = { x: null, y: null };
const escapeRadius = 100;
// Particle setup
for (let i = 0; i < numParticles; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
vx: (Math.random() - 0.5) * 0.5,
vy: (Math.random() - 0.5) * 0.5,
originalVx: (Math.random() - 0.5) * 0.5,
originalVy: (Math.random() - 0.5) * 0.5,
radius: Math.random() * 3 + 1,
color: `rgba(${Math.random() * 50}, ${Math.random() * 50 + 50}, ${Math.random() * 150 + 100}, ${Math.random() * 0.5 + 0.5})`
});
}
// Bubble setup
for (let i = 0; i < 50; i++) {
bubbles.push({
x: Math.random() * canvas.width,
y: canvas.height + Math.random() * canvas.height,
vx: (Math.random() - 0.5) * 0.2, // Add horizontal movement
vy: Math.random() * 0.5 + 0.5,
radius: Math.random() * 5 + 2,
color: `rgba(255, 255, 255, 0.2)`
});
}
// Plankton setup
for (let i = 0; i < 100; i++) {
plankton.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
vx: (Math.random() - 0.5) * 0.2,
vy: (Math.random() - 0.5) * 0.2,
radius: Math.random() * 1 + 0.5,
color: `rgba(0, 255, 0, 0.8)`
});
}
// Jellyfish setup
for (let i = 0; i < 20; i++) {
jellyfish.push({
x: Math.random() * canvas.width,
y: canvas.height + Math.random() * canvas.height,
vx: (Math.random() - 0.5) * 0.5,
vy: (Math.random() * -0.5) - 0.2,
radius: Math.random() * 20 + 10,
color: `rgba(255, 0, 255, 0.2)`
});
}
// Light Shaft setup
for (let i = 0; i < 10; i++) {
lightShafts.push({
x: Math.random() * canvas.width,
width: Math.random() * 50 + 10,
speed: Math.random() * 0.2 + 0.1
});
}
function drawParticle(particle) {
ctx.beginPath();
ctx.arc(particle.x, particle.y, particle.radius, 0, Math.PI * 2);
ctx.fillStyle = particle.color;
ctx.fill();
}
function updateParticle(particle) {
const dx = particle.x - mouse.x;
const dy = particle.y - mouse.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < escapeRadius) {
const angle = Math.random() * Math.PI * 2;
const speed = Math.random() * 2 + 1; // Random speed
particle.vx = Math.cos(angle) * speed;
particle.vy = Math.sin(angle) * speed;
} else {
// Slowly return to original speed
particle.vx += (particle.originalVx - particle.vx) * 0.05;
particle.vy += (particle.originalVy - particle.vy) * 0.05;
}
particle.x += particle.vx;
particle.y += particle.vy;
if (particle.x < 0) particle.x = canvas.width;
if (particle.x > canvas.width) particle.x = 0;
if (particle.y < 0) particle.y = canvas.height;
if (particle.y > canvas.height) particle.y = 0;
}
function drawBubble(bubble) {
ctx.beginPath();
ctx.arc(bubble.x, bubble.y, bubble.radius, 0, Math.PI * 2);
ctx.fillStyle = bubble.color;
ctx.fill();
}
function updateBubble(bubble) {
bubble.x += bubble.vx;
bubble.y -= bubble.vy;
if (bubble.y < -bubble.radius) {
bubble.y = canvas.height + bubble.radius;
bubble.x = Math.random() * canvas.width;
}
if (bubble.x < 0) bubble.x = canvas.width;
if (bubble.x > canvas.width) bubble.x = 0;
}
function drawPlankton(plankton) {
ctx.beginPath();
ctx.arc(plankton.x, plankton.y, plankton.radius, 0, Math.PI * 2);
ctx.fillStyle = plankton.color;
ctx.fill();
}
function updatePlankton(plankton) {
plankton.x += plankton.vx;
plankton.y += plankton.vy;
if (plankton.x < 0) plankton.x = canvas.width;
if (plankton.x > canvas.width) plankton.x = 0;
if (plankton.y < 0) plankton.y = canvas.height;
if (plankton.y > canvas.height) plankton.y = 0;
}
function drawJellyfish(jellyfish) {
ctx.beginPath();
ctx.arc(jellyfish.x, jellyfish.y, jellyfish.radius, 0, Math.PI * 2);
ctx.fillStyle = jellyfish.color;
ctx.fill();
}
function updateJellyfish(jellyfish) {
jellyfish.x += jellyfish.vx;
jellyfish.y += jellyfish.vy;
if (jellyfish.x < 0) jellyfish.x = canvas.width;
if (jellyfish.x > canvas.width) jellyfish.x = 0;
if (jellyfish.y < -jellyfish.radius) {
jellyfish.y = canvas.height + jellyfish.radius;
jellyfish.x = Math.random() * canvas.width;
}
}
function drawLightShafts() {
ctx.save();
ctx.globalAlpha = 0.1;
ctx.filter = 'blur(5px)'; // Apply blur effect to light shafts
lightShafts.forEach(shaft => {
const gradient = ctx.createLinearGradient(shaft.x, 0, shaft.x + shaft.width, canvas.height);
gradient.addColorStop(0, 'rgba(255, 255, 255, 0.1)');
gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
ctx.fillStyle = gradient;
ctx.fillRect(shaft.x, 0, shaft.width, canvas.height);
shaft.x += shaft.speed;
if (shaft.x > canvas.width) {
shaft.x = -shaft.width;
}
});
ctx.restore();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawLightShafts();
particles.forEach(particle => {
updateParticle(particle);
drawParticle(particle);
});
bubbles.forEach(bubble => {
updateBubble(bubble);
drawBubble(bubble);
});
plankton.forEach(p => {
updatePlankton(p);
drawPlankton(p);
});
jellyfish.forEach(j => {
updateJellyfish(j);
drawJellyfish(j);
});
requestAnimationFrame(draw);
}
draw();
canvas.addEventListener('mousemove', (event) => {
mouse.x = event.clientX;
mouse.y = event.clientY;
});
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});