Full code of the above shooting star animation with the html css and javascript:
`<!DOCTYPE html>
Neon Shooting Stars to Center
<br> * { margin: 0; padding: 0; box-sizing: border-box; }<br> body {<br> background: black;<br> overflow: hidden;<br> height: 100vh;<br> width: 100vw;<br> }<br> canvas {<br> position: absolute;<br> top: 0;<br> left: 0;<br> }<br>
<script>
const canvas = document.getElementById("shootingCanvas");
const ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let shootingStars = [];
let bursts = [];
let particles = [];
class ShootingStar {
constructor() {
let edge = Math.floor(Math.random() * 4);
if (edge === 0) { // Left side
this.x = -50;
this.y = Math.random() * canvas.height;
} else if (edge === 1) { // Right side
this.x = canvas.width + 50;
this.y = Math.random() * canvas.height;
} else if (edge === 2) { // Top
this.x = Math.random() * canvas.width;
this.y = -50;
} else { // Bottom
this.x = Math.random() * canvas.width;
this.y = canvas.height + 50;
}
this.targetX = canvas.width / 2;
this.targetY = canvas.height / 2;
this.speed = Math.random() * 2 + 1;
this.opacity = 1;
this.tail = [];
this.burstTriggered = false;
this.visible = true;
}
update() {
if (!this.visible) return false;
let dx = this.targetX - this.x;
let dy = this.targetY - this.y;
let distance = Math.sqrt(dx * dx + dy * dy);
this.x += (dx / distance) * this.speed;
this.y += (dy / distance) * this.speed;
this.tail.push({ x: this.x, y: this.y });
if (this.tail.length > 10) this.tail.shift();
if (!this.burstTriggered && distance < 10) {
bursts.push(new Burst(this.x, this.y));
this.burstTriggered = true;
this.visible = false;
}
return true;
}
draw() {
if (!this.visible) return;
ctx.beginPath();
for (let i = 0; i < this.tail.length; i++) {
ctx.lineTo(this.tail[i].x, this.tail[i].y);
}
ctx.strokeStyle = `rgba(255, 255, 255, ${this.opacity})`;
ctx.lineWidth = 2;
ctx.stroke();
ctx.beginPath();
ctx.arc(this.x, this.y, 3, 0, Math.PI * 2);
ctx.fillStyle = "white";
ctx.fill();
}
}
class Burst {
constructor(x, y) {
this.x = x;
this.y = y;
this.particles = [];
for (let i = 0; i < 20; i++) {
this.particles.push(new Particle(x, y, true));
}
}
update() {
this.particles = this.particles.filter(particle => particle.update());
return this.particles.length > 0;
}
draw() {
this.particles.forEach(particle => particle.draw());
}
}
class Particle {
constructor(x, y, isBurst = false) {
this.x = x;
this.y = y;
this.angle = Math.random() * 2 * Math.PI;
this.speed = Math.random() * 2 + 0.5;
this.opacity = 1;
this.radius = Math.random() * 5 + 2;
this.isBurst = isBurst;
this.color = isBurst ? `hsl(${Math.random() * 360}, 100%, 70%)` : "rgba(255, 255, 255, 0.5)";
}
update() {
this.x += Math.cos(this.angle) * this.speed;
this.y += Math.sin(this.angle) * this.speed;
this.opacity -= 0.02;
return this.opacity > 0;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this.color;
ctx.globalAlpha = this.opacity;
ctx.fill();
ctx.globalAlpha = 1;
}
}
function createStars() {
let groupSize = Math.floor(Math.random() * 4) + 2;
for (let i = 0; i < groupSize; i++) {
shootingStars.push(new ShootingStar());
}
}
function createBackgroundParticles() {
for (let i = 0; i < 70; i++) {
particles.push(new Particle(Math.random() * canvas.width, Math.random() * canvas.height));
}
}
function updateParticles() {
particles.forEach(particle => {
particle.update();
if (particle.opacity <= 0) {
particle.x = Math.random() * canvas.width;
particle.y = Math.random() * canvas.height;
particle.opacity = 1;
}
});
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
updateParticles();
particles.forEach(particle => particle.draw());
shootingStars = shootingStars.filter(star => {
if (star.update()) {
star.draw();
return true;
}
return false;
});
bursts = bursts.filter(burst => {
if (burst.update()) {
burst.draw();
return true;
}
return false;
});
requestAnimationFrame(animate);
}
setInterval(createStars, 1500);
createBackgroundParticles();
animate();
</script>
`
Top comments (1)
This shooting stars animation is absolutely mesmerizing! I've been fascinated by these kinds of dynamic visual effects lately. Creating CSS animations via AI is interesting too - I was checking out r6 sens calculator yesterday and was blown away by the shooting mouse effect they implemented. The way the cursor leaves trails and creates interactive elements is so engaging. I wonder if there's a way to combine your shooting stars concept with AI tools to create similar interactive cursor effects? Would love to see a tutorial on that next!