随机生成不同大小和亮度的星星
星星会缓慢闪烁,模拟真实星空效果
星星带有微弱的颜色(白色、淡黄色、淡蓝色、淡红色)
流星效果:
流星随机从屏幕左侧或顶部边缘出现
流星缓慢划过屏幕,速度可调节
流星带有渐变的拖尾效果,增强视觉体验
设置功能:
右上角设置图标,点击展开/收起设置面板
可以调整星星数量、流星频率、流星速度和星星闪烁速度
所有参数实时生效响应式设计:当窗口大小改变时,Canvas会自动调整大小并重新生成星星
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>星辰与流星</title> <style> body { margin: 0; overflow: hidden; background-color: #000; font-family: 'Arial', sans-serif; } canvas { display: block; } /* 设置图标样式 */ .settings-icon { position: absolute; top: 20px; right: 20px; color: white; font-size: 24px; cursor: pointer; z-index: 100; background: rgba(0, 0, 0, 0.5); border-radius: 50%%; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; transition: all 0.3s; } .settings-icon:hover { transform: rotate(45deg); background: rgba(0, 0, 0, 0.7); } /* 设置面板样式 */ .settings-panel { position: absolute; top: 70px; right: 20px; background: rgba(0, 0, 0, 0.8); color: white; padding: 20px; border-radius: 10px; width: 250px; display: none; z-index: 100; box-shadow: 0 0 15px rgba(255, 255, 255, 0.2); } .settings-panel h3 { margin-top: 0; border-bottom: 1px solid rgba(255, 255, 255, 0.3); padding-bottom: 10px; } .setting-group { margin-bottom: 15px; } .setting-group label { display: block; margin-bottom: 5px; font-size: 14px; } .setting-group input[type="range"] { width: 100%%; } .setting-value { font-size: 12px; color: #aaa; float: right; } </style> </head> <body> <div>⚙️</div> <div> <h3>星空设置</h3> <div> <label>星星数量 <span id="starCountValue">500</span></label> <input type="range" id="starCount" min="100" max="1000" value="500" step="50"> </div> <div> <label>流星频率 <span id="meteorFrequencyValue">0.01</span></label> <input type="range" id="meteorFrequency" min="0.001" max="0.05" value="0.01" step="0.001"> </div> <div> <label>流星速度 <span id="meteorSpeedValue">5</span></label> <input type="range" id="meteorSpeed" min="2" max="15" value="5" step="1"> </div> <div> <label>星星闪烁速度 <span id="twinkleSpeedValue">0.5</span></label> <input type="range" id="twinkleSpeed" min="0.1" max="2" value="0.5" step="0.1"> </div> </div> <canvas id="starCanvas"></canvas> <script> // 获取Canvas元素和上下文 const canvas = document.getElementById('starCanvas'); const ctx = canvas.getContext('2d'); const settingsIcon = document.querySelector('.settings-icon'); const settingsPanel = document.querySelector('.settings-panel'); // 设置Canvas大小为窗口大小 canvas.width = window.innerWidth; canvas.height = window.innerHeight; // 配置参数 let config = { starCount: 500, meteorFrequency: 0.01, meteorSpeed: 5, twinkleSpeed: 0.5 }; // 星星数组 let stars = []; // 流星数组 let meteors = []; // 星星类 class Star { constructor() { this.x = Math.random() * canvas.width; this.y = Math.random() * canvas.height; this.size = Math.random() * 2 + 0.1; // 给星星添加微弱的颜色 this.color = this.getRandomStarColor(); this.brightness = 0.2 + Math.random() * 0.8; this.speed = config.twinkleSpeed * 0.001; this.phase = Math.random() * Math.PI * 2; } // 获取随机的星星颜色(主要是白色,但带有微弱色调) getRandomStarColor() { const colors = [ {r: 255, g: 255, b: 255}, // 白色 {r: 255, g: 255, b: 220}, // 淡黄色 {r: 220, g: 220, b: 255}, // 淡蓝色 {r: 255, g: 220, b: 220} // 淡红色 ]; return colors[Math.floor(Math.random() * colors.length)]; } update() { this.speed = config.twinkleSpeed * 0.001; this.phase += this.speed; this.brightness = 0.7 + 0.3 * Math.sin(this.phase); } draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); ctx.fillStyle = `rgba(${this.color.r}, ${this.color.g}, ${this.color.b}, ${this.brightness})`; ctx.fill(); } } // 流星类 class Meteor { constructor() { this.reset(); } reset() { // 流星从屏幕左侧或顶部边缘开始 const fromLeft = Math.random() > 0.5; if (fromLeft) { this.x = 0; this.y = Math.random() * canvas.height * 0.3; } else { this.x = Math.random() * canvas.width * 0.3; this.y = 0; } // 流星角度(向右下方向) this.angle = Math.atan2(canvas.height, canvas.width) + (Math.random() - 0.5) * 0.4; this.speed = config.meteorSpeed; this.size = 1 + Math.random() * 2; this.length = 20 + Math.random() * 50; this.trail = []; this.active = true; } update() { this.speed = config.meteorSpeed; this.x += Math.cos(this.angle) * this.speed * 0.3; // 降低速度因子 this.y += Math.sin(this.angle) * this.speed * 0.3; // 降低速度因子 // 添加当前位置到轨迹 this.trail.push({x: this.x, y: this.y}); // 保持轨迹长度 if (this.trail.length > this.length) { this.trail.shift(); } // 如果流星离开屏幕,重置它 if (this.x > canvas.width || this.y > canvas.height) { this.active = false; } } draw() { if (this.trail.length < 2) return; // 绘制流星轨迹(渐变效果) for (let i = 0; i < this.trail.length - 1; i++) { const point = this.trail[i]; const nextPoint = this.trail[i + 1]; const progress = i / this.trail.length; const alpha = progress * 0.8; const width = this.size * progress; ctx.beginPath(); ctx.moveTo(point.x, point.y); ctx.lineTo(nextPoint.x, nextPoint.y); ctx.strokeStyle = `rgba(255, 255, 255, ${alpha})`; ctx.lineWidth = width; ctx.stroke(); } // 绘制流星头部 ctx.beginPath(); ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); ctx.fillStyle = 'rgba(255, 255, 255, 0.8)'; ctx.fill(); } } // 初始化星星 function initStars() { stars = []; for (let i = 0; i < config.starCount; i++) { stars.push(new Star()); } } // 动画循环 function animate() { // 清除画布 ctx.fillStyle = 'rgba(0, 0, 0, 0.2)'; ctx.fillRect(0, 0, canvas.width, canvas.height); // 更新和绘制星星 stars.forEach(star => { star.update(); star.draw(); }); // 随机添加流星 if (Math.random() < config.meteorFrequency && meteors.length < 5) { meteors.push(new Meteor()); } // 更新和绘制流星 meteors.forEach((meteor, index) => { if (meteor.active) { meteor.update(); meteor.draw(); } else { // 移除不活动的流星 meteors.splice(index, 1); } }); requestAnimationFrame(animate); } // 窗口大小调整时重置Canvas window.addEventListener('resize', () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; initStars(); }); // 设置图标点击事件 settingsIcon.addEventListener('click', () => { settingsPanel.style.display = settingsPanel.style.display === 'block' ? 'none' : 'block'; }); // 初始化设置滑块 document.getElementById('starCount').addEventListener('input', function() { config.starCount = parseInt(this.value); document.getElementById('starCountValue').textContent = this.value; initStars(); }); document.getElementById('meteorFrequency').addEventListener('input', function() { config.meteorFrequency = parseFloat(this.value); document.getElementById('meteorFrequencyValue').textContent = this.value; }); document.getElementById('meteorSpeed').addEventListener('input', function() { config.meteorSpeed = parseInt(this.value); document.getElementById('meteorSpeedValue').textContent = this.value; }); document.getElementById('twinkleSpeed').addEventListener('input', function() { config.twinkleSpeed = parseFloat(this.value); document.getElementById('twinkleSpeedValue').textContent = this.value; }); // 初始化并开始动画 initStars(); animate(); </script> </body> </html>
本文最后更新时间 2025-09-18
文章链接地址:https://xzlo.blog/index.php/archives/66/
本站文章除注明[转载|引用|原文]出处外,均为本站原生内容,转载前请注明出处