随机生成不同大小和亮度的星星
星星会缓慢闪烁,模拟真实星空效果
星星带有微弱的颜色(白色、淡黄色、淡蓝色、淡红色)
流星效果:
流星随机从屏幕左侧或顶部边缘出现
流星缓慢划过屏幕,速度可调节
流星带有渐变的拖尾效果,增强视觉体验
设置功能:
右上角设置图标,点击展开/收起设置面板
可以调整星星数量、流星频率、流星速度和星星闪烁速度
所有参数实时生效响应式设计:当窗口大小改变时,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 class="settings-icon">⚙️</div>
<div class="settings-panel">
<h3>星空设置</h3>
<div class="setting-group">
<label>星星数量 <span class="setting-value" id="starCountValue">500</span></label>
<input type="range" id="starCount" min="100" max="1000" value="500" step="50">
</div>
<div class="setting-group">
<label>流星频率 <span class="setting-value" 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 class="setting-group">
<label>流星速度 <span class="setting-value" id="meteorSpeedValue">5</span></label>
<input type="range" id="meteorSpeed" min="2" max="15" value="5" step="1">
</div>
<div class="setting-group">
<label>星星闪烁速度 <span class="setting-value" 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.addEventListener('click', (e) => {
if (!settingsPanel.contains(e.target) && e.target !== settingsIcon) {
settingsPanel.style.display = 'none';
}
});
// 初始化设置滑块
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-10-01
文章链接地址:https://xzlo.blog/index.php/archives/66/
本站文章除注明[转载|引用|原文]出处外,均为本站原生内容,转载前请注明出处