星空模拟器:在网页上漫步星空 – day 2

152 阅读2分钟

星空模拟器:在网页上漫步星空 -- day 2

一、具体调整

  1. 增加星星的动态效果 可以让星星有不同的运动轨迹,而不仅仅是闪烁。在 script.js 中,为每个星星添加了一个随机的运动角度和速度,并使用 requestAnimationFrame 函数实现了星星的动态运动。
  2. 优化性能 减少不必要的重排和重绘,提高动画的流畅度。使用 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); // 默认密度,可根据需求调整
});