星空模拟器:在网页上漫步星空 -- day 2
一、具体调整
- 增加星星的动态效果 可以让星星有不同的运动轨迹,而不仅仅是闪烁。在 script.js 中,为每个星星添加了一个随机的运动角度和速度,并使用 requestAnimationFrame 函数实现了星星的动态运动。
- 优化性能 减少不必要的重排和重绘,提高动画的流畅度。使用 requestAnimationFrame 函数来实现动画,避免了不必要的重排和重绘,提高了动画的流畅度。
二、效果展示
三、实现步骤
1. 创建星空容器(HTML)
第一步是构建我们的星空容器。我们需要一个简单的 HTML 结构,包含一个用于呈现星空的主要容器。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>星空模拟器</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="starfield"></div>
<script src="script.js"></script>
</body>
</html>
2. 设置样式(CSS)
接下来,我们使用 CSS 来打造具有美感的星空背景和星星样式。背景将使用黑蓝色的渐变,星星则会在不同的位置和大小闪烁。
body {
margin: 0;
overflow: hidden; /* 隐藏滚动条 */
height: 100vh; /* 占据整个屏幕高度 */
background: linear-gradient(to bottom, #000428, #004e92); /* 深邃的背景渐变 */
}
.starfield {
position: relative; /* 相对定位,方便星星定位 */
width: 100%;
height: 100%;
overflow: hidden; /* 防止星星超出容器 */
}
.star {
position: absolute; /* 绝对定位,星星自由移动 */
border-radius: 50%; /* 圆形星星 */
background: white; /* 星星颜色 */
opacity: 0.8; /* 稍微透明,更自然 */
animation: twinkle 2s linear infinite; /* 添加闪烁动画 */
}
/* 定义闪烁动画 */
@keyframes twinkle {
0% {
opacity: 0.6;
}
50% {
opacity: 1;
}
100% {
opacity: 0.6;
}
}
3. 控制星星的闪烁与移动(JavaScript)
最后,我们通过 JavaScript 控制星星的创建、闪烁和移动。每个星星会在随机位置生成,并模拟闪烁效果。
const starfield = document.querySelector(".starfield");
const numberOfStars = 200; // 增加星星数量
const nebulaCount = 5; // 星云数量
// 创建星星
for (let i = 0; i < numberOfStars; i++) {
const star = document.createElement("div");
star.classList.add("star");
// 设置星星的随机位置和大小
const size = Math.random() * 2 + 1; // 星星随机大小,范围缩小,更真实
star.style.width = `${size}px`;
star.style.height = `${size}px`;
star.style.left = `${Math.random() * 100}vw`;
star.style.top = `${Math.random() * 100}vh`;
star.style.animationDelay = `${Math.random() * 2}s`; // 随机动画延迟,避免所有星星同步闪烁
// 增加星星的动态运动
const angle = Math.random() * 360;
const speed = Math.random() * 0.1;
star.dataset.angle = angle;
star.dataset.speed = speed;
starfield.appendChild(star);
}
// 星星运动动画
function moveStars() {
const stars = document.querySelectorAll(".star");
stars.forEach((star) => {
let angle = parseFloat(star.dataset.angle);
let speed = parseFloat(star.dataset.speed);
let x = parseFloat(star.style.left.replace("vw", ""));
let y = parseFloat(star.style.top.replace("vh", ""));
x += speed * Math.cos(angle * (Math.PI / 1800));
y += speed * Math.sin(angle * (Math.PI / 1800));
if (x < 0) x = 100;
if (x > 100) x = 0;
if (y < 0) y = 100;
if (y > 100) y = 0;
star.style.left = `${x}vw`;
star.style.top = `${y}vh`;
star.dataset.angle = (angle + 1) % 360;
});
requestAnimationFrame(moveStars);
}
moveStars();
// 监听窗口大小变化,重新调整星星
window.addEventListener("resize", () => {
adjustStarDensity(0.8); // 默认密度,可根据需求调整
});