pages/src/js/animation/starBackground.js

81 lines
1.7 KiB
JavaScript
Raw Normal View History

2025-10-20 15:09:39 +02:00
import Star from "./Star.js";
import Meteor from "./Meteor.js";
const starInstances = [];
const meteorInstances = [];
function createStars() {
const stars = document.getElementById("stars");
const count = 400;
2025-10-20 15:09:39 +02:00
stars.innerHTML = "";
starInstances.length = 0;
for (let i = 0; i < count; i++) {
const star = new Star(stars);
starInstances.push(star);
}
}
function injectStarCSS() {
const style = document.createElement("style");
style.textContent = `
.star {
position: absolute;
border-radius: 50%;
animation: twinkle ease-in-out infinite;
}
@keyframes twinkle {
0%, 100% { opacity: 1; }
50% { opacity: 0.3; }
}
`;
document.head.appendChild(style);
}
function trySpawnMeteor() {
const spawnChance = 0.12;
2025-10-20 15:09:39 +02:00
if (Math.random() < spawnChance) {
const stars = document.getElementById("stars");
const newMeteor = new Meteor(stars);
meteorInstances.push(newMeteor);
}
}
function animateStars() {
starInstances.forEach((star) => star.update());
// Update meteors and remove dead ones
for (let i = meteorInstances.length - 1; i >= 0; i--) {
if (!meteorInstances[i].update()) {
meteorInstances.splice(i, 1);
}
}
requestAnimationFrame(animateStars);
}
function createMeteorBurst() {
for (let i = 0; i < 3; i++) {
setTimeout(() => {
const stars = document.getElementById("stars");
const newMeteor = new Meteor(stars);
meteorInstances.push(newMeteor);
}, i * 200);
}
}
function init() {
injectStarCSS();
createStars();
animateStars();
setInterval(trySpawnMeteor, 2000);
setInterval(createMeteorBurst, 15000);
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}