<!DOCTYPE html>
<html>
<head>
    <title>渐显白色流星群</title>
    <style>
        body { margin: 0; overflow: hidden; background: #000; }
        canvas { display: block; }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <script>
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        class Meteor {
            constructor() {
                this.reset(true);
            }

            reset() {
                this.x = canvas.width/2;
                this.y = canvas.height/2;
                this.angle = Math.random() * Math.PI * 2;
                this.speed = Math.random() * 1.2 + 0.3;      // 更慢的速度范围
                this.size = Math.random() * 2 + 1;
                this.trail = [];
                this.trailLength = Math.floor(Math.random() * 25 + 15); // 更长尾迹
                this.maxDistance = Math.max(canvas.width, canvas.height) / 2; // 动态最大距离
            }

            update() {
                // 记录轨迹点
                this.trail.push({ x: this.x, y: this.y })
                if(this.trail.length > this.trailLength) this.trail.shift()

                // 计算新位置
                this.x += Math.cos(this.angle) * this.speed;
                this.y += Math.sin(this.angle) * this.speed;

                // 基于距离计算透明度
                const dx = this.x - canvas.width/2;
                const dy = this.y - canvas.height/2;
                const distance = Math.sqrt(dx*dx + dy*dy);
                this.alpha = Math.min(distance / this.maxDistance, 1); // 距离渐显

                // 重置条件(仅位置判断)
                if(this.x < 0 || this.x > canvas.width || 
                   this.y < 0 || this.y > canvas.height) {
                    this.reset();
                }
            }

            draw() {
                // 绘制尾迹
                this.trail.forEach((pos, index) => {
                    const ratio = index/this.trailLength;
                    ctx.beginPath();
                    ctx.arc(pos.x, pos.y, this.size * ratio, 0, Math.PI*2);
                    ctx.fillStyle = `rgba(255, 255, 255, ${ratio * 0.6 * this.alpha})`; // 复合透明度
                    ctx.fill();
                });

                // 绘制头部
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.size, 0, Math.PI*2);
                ctx.fillStyle = `rgba(255, 255, 255, ${this.alpha})`;
                ctx.fill();
            }
        }

        const meteors = Array(150).fill().map(() => new Meteor());

        function animate() {
            ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';  // 更淡的尾迹残留
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            meteors.forEach(meteor => {
                meteor.update();
                meteor.draw();
            });

            requestAnimationFrame(animate);
        }

        window.addEventListener('resize', () => {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
            meteors.forEach(meteor => meteor.reset());
        });

        animate();
    </script>
</body>
</html>