meteor-shower-effect.js 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // Meteor Shower Effect - Balanced Density
  2. function initMeteorShowerEffect() {
  3. const canvas = document.getElementById('meteorShowerCanvas');
  4. const ctx = canvas.getContext('2d');
  5. let width = window.innerWidth;
  6. let height = window.innerHeight;
  7. canvas.width = width;
  8. canvas.height = height;
  9. const meteors = [];
  10. const maxMeteors = 50;
  11. const spawnChance = 0.08;
  12. function createMeteor() {
  13. return {
  14. x: Math.random() * width,
  15. y: -20,
  16. length: 40 + Math.random() * 30,
  17. speed: 2 + Math.random() * 1.5,
  18. opacity: 0.2 + Math.random() * 0.4,
  19. width: 1 + Math.random() * 1
  20. };
  21. }
  22. function animate() {
  23. ctx.clearRect(0, 0, width, height);
  24. if (meteors.length < maxMeteors && Math.random() < spawnChance) {
  25. meteors.push(createMeteor());
  26. }
  27. for (let i = 0; i < meteors.length; i++) {
  28. const meteor = meteors[i];
  29. meteor.y += meteor.speed;
  30. ctx.beginPath();
  31. ctx.moveTo(meteor.x, meteor.y);
  32. ctx.lineTo(meteor.x, meteor.y - meteor.length);
  33. ctx.strokeStyle = `rgba(255, 255, 255, ${meteor.opacity})`;
  34. ctx.lineWidth = meteor.width;
  35. ctx.stroke();
  36. if (meteor.y > height + 100) {
  37. meteors.splice(i, 1);
  38. i--;
  39. }
  40. }
  41. requestAnimationFrame(animate);
  42. }
  43. animate();
  44. window.addEventListener('resize', () => {
  45. width = window.innerWidth;
  46. height = window.innerHeight;
  47. canvas.width = width;
  48. canvas.height = height;
  49. });
  50. }
  51. window.addEventListener('DOMContentLoaded', () => {
  52. initMeteorShowerEffect();
  53. });