Canvas实例篇:十二星座之天秤座

Canvas实例篇:十二星座之天秤座

前言

星座总给人浪漫而神秘的感觉,如何用代码还原星空中的浪漫?本文将通过 Canvas 技术,讲述如何实现一个可交互的天秤座星空图,包含星星闪烁、星座连线、动态效果控制等功能。

效果预览

天秤座星空图

代码实现

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>天秤座星空图</title>
    <style>
      body,
      html {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
        overflow: hidden;
        background-color: #000;
      }

      canvas {
        display: block;
        position: absolute;
        top: 0;
        left: 0;
      }

      .constellation-info {
        position: absolute;
        bottom: 20px;
        left: 20px;
        color: #fff;
        font-family: Arial, sans-serif;
        background: rgba(0, 0, 0, 0.5);
        padding: 10px;
        border-radius: 5px;
      }

      .controls {
        position: absolute;
        top: 20px;
        right: 20px;
        color: white;
        font-family: Arial, sans-serif;
      }

      button {
        background: rgba(255, 255, 255, 0.1);
        color: white;
        border: 1px solid rgba(255, 255, 255, 0.3);
        padding: 5px 10px;
        margin: 5px;
        cursor: pointer;
        border-radius: 3px;
      }

      button:hover {
        background: rgba(255, 255, 255, 0.2);
      }
    </style>
  </head>
  <body>
    <canvas id="starCanvas"></canvas>
    <div class="constellation-info">
      <h3>天秤座 (9月23日 ~ 10月23日)</h3>
      <p>黄道十二宫之一</p>
      <p>象征平衡与正义的星座</p>
    </div>
    <div class="controls">
      <button id="toggleLines">显示/隐藏连线</button>
      <button id="toggleNames">显示/隐藏星名</button>
      <button id="toggleAnimation">暂停/继续动画</button>
    </div>

    <script>
      // 获取Canvas元素和绘图上下文
      const canvas = document.getElementById('starCanvas');
      const ctx = canvas.getContext('2d');

      // 设置Canvas尺寸为窗口大小
      function resizeCanvas() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
      }

      resizeCanvas();
      window.addEventListener('resize', resizeCanvas);

      // 存储星星的数组
      const stars = [];

      // 天秤座主星数据
      const libraStars = [{
          name: "氐宿四",
          x: 0.43,
          y: 0.3,
          magnitude: 2.7,
          color: "#FFFFC3"
        },{
          name: "氐宿一",
          x: 0.53,
          y: 0.45,
          magnitude: 3.9,
          color: "#42A5F5"
        },{
          name: "氐宿三",
          x: 0.35,
          y: 0.4,
          magnitude: 2.6,
          color: "#FFA726"
        },{
          name: "氐宿增一",
          x: 0.5,
          y: 0.62,
          magnitude: 4.6,
          color: "#FFF59D"
        },{
          name: "折威七",
          x: 0.53,
          y: 0.66,
          magnitude: 4.4,
          color: "#64B5F6"
        },{
          name: "氐宿二",
          x: 0.38,
          y: 0.51,
          magnitude: 4.0,
          color: "#FFCCBC"
        },{
          name: "氐宿五",
          x: 0.365,
          y: 0.575,
          magnitude: 4.3,
          color: "#FFCC80"
        },{
          name: "氐宿增五",
          x: 0.35,
          y: 0.64,
          magnitude: 4.8,
          color: "#E6EE9C"
        }
      ];

      // 天秤座星座连线
      const starConnections = [
        // 秤杆
        [0 ,1],
        [1, 2],
        [2, 0],
        // 秤盘
        [1, 3],
        [3, 4],
        [2,5],
        [5,6],
        [6,7]
      ];

      // 初始化随机星星
      function initStars(count) {
        for (let i = 0; i < count; i++) {
          stars.push({
            x: Math.random(),
            y: Math.random(),
            size: Math.random() * 2,
            brightness: Math.random(),
            twinkleSpeed: Math.random() * 0.01
          });
        }

        // 添加星座星星
        libraStars.forEach(star => {
          stars.push({
            x: star.x,
            y: star.y,
            size: star.magnitude,
            brightness: 1,
            isConstellation: true,
            name: star.name,
            color: star.color
          });
        });
      }

      // 绘制星空
      function drawStars() {
        // 清空画布
        ctx.fillStyle = '#000a1a';
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        // 绘制背景星星
        stars.forEach(star => {
          if (!star.isConstellation) {
            // 让星星闪烁
            const twinkle = Math.sin(Date.now() * star.twinkleSpeed) * 0.5 + 0.5;
            const alpha = star.brightness * twinkle;

            ctx.fillStyle = `rgba(255, 255, 255, ${alpha})`;
            ctx.beginPath();
            ctx.arc(
              star.x * canvas.width,
              star.y * canvas.height,
              star.size,
              0,
              Math.PI * 2
            );
            ctx.fill();
          }
        });

        // 绘制星座连线
        if (showLines) {
          ctx.strokeStyle = 'rgb(255, 255, 255)';
          ctx.lineWidth = 3;

          starConnections.forEach(connection => {
            const startIndex = connection[0];
            const endIndex = connection[1];

            // 确保索引有效
            if (startIndex < libraStars.length && endIndex < libraStars.length) {
              const start = stars[stars.length - libraStars.length + startIndex];
              const end = stars[stars.length - libraStars.length + endIndex];

              ctx.beginPath();
              // 判断画布
              if (canvas.width > canvas.height) {
                ctx.moveTo(start.x * canvas.width, start.y * canvas.height);
                ctx.lineTo(end.x * canvas.width, end.y * canvas.height);
              } else {
                ctx.moveTo(start.y * canvas.width, (start.x + 0.1) * canvas.height);
                ctx.lineTo(end.y * canvas.width, (end.x + 0.1) * canvas.height);
              }

              ctx.stroke();
            }
          });
        }

        // 绘制星座星星
        libraStars.forEach((star, index) => {
          const starObj = stars[stars.length - libraStars.length + index];

          ctx.fillStyle = starObj.color;
          ctx.beginPath();
          // 判断画布
          if (canvas.width > canvas.height) {
            ctx.arc(
              starObj.x * canvas.width,
              starObj.y * canvas.height,
              starObj.size + 0.5,
              0,
              Math.PI * 2
            );
          } else {
            ctx.arc(
              starObj.y * canvas.width,
              (starObj.x + 0.1) * canvas.height,

              starObj.size + 0.5,
              0,
              Math.PI * 2
            );
          }

          ctx.fill();

          // 添加星名
          if (showNames) {
            ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
            ctx.font = '12px Arial';
            if (canvas.width > canvas.height) {
              ctx.fillText(
                starObj.name,
                starObj.x * canvas.width + 8,
                starObj.y * canvas.height - 8
              );
            } else {
              ctx.fillText(
                starObj.name,
                starObj.y * canvas.width + 8,
                (starObj.x + 0.1) * canvas.height + 8
              );
            }

          }
        });
      }

      // 动画循环
      function animate() {
        if (animationRunning) {
          requestAnimationFrame(animate);
        }
        drawStars();
      }

      // 控制变量
      let showLines = true;
      let showNames = true;
      let animationRunning = true;

      // 初始化
      initStars(2000);
      animate();

      // 添加按钮事件
      document.getElementById('toggleLines').addEventListener('click', () => {
        showLines = !showLines;
      });

      document.getElementById('toggleNames').addEventListener('click', () => {
        showNames = !showNames;
      });

      document.getElementById('toggleAnimation').addEventListener('click', () => {
        animationRunning = !animationRunning;
        if (animationRunning) {
          animate();
        }
      });
    </script>
  </body>
</html>

代码说明

星座特定星

// 天秤座主星数据
const libraStars = [{
  name: "氐宿四",
  x: 0.43,
  y: 0.3,
  magnitude: 2.7,
  color: "#FFFFC3"
}, {
  name: "氐宿一",
  x: 0.53,
  y: 0.45,
  magnitude: 3.9,
  color: "#42A5F5"
}, {
  name: "氐宿三",
  x: 0.35,
  y: 0.4,
  magnitude: 2.6,
  color: "#FFA726"
}, {
  name: "氐宿增一",
  x: 0.5,
  y: 0.62,
  magnitude: 4.6,
  color: "#FFF59D"
}, {
  name: "折威七",
  x: 0.53,
  y: 0.66,
  magnitude: 4.4,
  color: "#64B5F6"
}, {
  name: "氐宿二",
  x: 0.38,
  y: 0.51,
  magnitude: 4.0,
  color: "#FFCCBC"
}, {
  name: "氐宿五",
  x: 0.365,
  y: 0.575,
  magnitude: 4.3,
  color: "#FFCC80"
}, {
  name: "氐宿增五",
  x: 0.35,
  y: 0.64,
  magnitude: 4.8,
  color: "#E6EE9C"
}];

// 天秤座星座连线
const starConnections = [
  // 秤杆
  [0, 1],
  [1, 2],
  [2, 0],
  // 秤盘
  [1, 3],
  [3, 4],
  [2, 5],
  [5, 6],
  [6, 7]
];

结语

本文主要讲解了如何通过Canvas绘制天秤座星座图,后续会继续使用Canvas绘制其余星座。对于文章中错误的地方或者有任何问题,欢迎在评论区留言分享!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值