canvas 鼠标与点之间连线


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .canvas {
        width: 100%;
        height: calc(100vh - 24px);
        border: 1px solid black;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <canvas class="canvas"></canvas>

    <script>
      /** @type {HTMLCanvasElement} */
      const canvas = document.querySelector('.canvas');
      const ctx = canvas.getContext('2d');

      const pointMap = new Map();

      canvas.width = canvas.clientWidth * window.devicePixelRatio;
      canvas.height = canvas.clientHeight * window.devicePixelRatio;

      canvas.addEventListener('mousemove', (e) => {
        const rect = canvas.getBoundingClientRect();
        let x = e.clientX - rect.left,
          y = e.clientY - rect.top;
        x = (x * window.devicePixelRatio).toFixed(2);
        y = (y * window.devicePixelRatio).toFixed(2);

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        renderPoints();
        computedPosition(x, y);
      });

      randomPoints(canvas.clientWidth, canvas.clientHeight, 20);
      renderPoints();

      // 计算鼠标与每个点(圆)的距离
      function computedPosition(x, y) {
        // console.log('x, y => ', x, y);
        for (const [key, { x: pointX, y: pointY, color }] of pointMap) {
          const distance = Math.sqrt((x - pointX) ** 2 + (y - pointY) ** 2);
          if (distance < 200) {
            // 点与鼠标的距离小于200,则连线
            ctx.beginPath();
            ctx.moveTo(x, y);
            ctx.lineTo(pointX, pointY);
            ctx.strokeStyle = color;
            ctx.stroke();
          }
        }
      }

      // 渲染点
      function renderPoints() {
        for (const { x, y, color } of pointMap.values()) {
          // console.log("point => ", point)
          drawCircle(x, y, color);
        }
      }

      // 生成随机点
      function randomPoints(boundWidth, boundHeight, count = 0) {
        if (!count) return;

        count = parseInt(count);

        const minWidth = 0,
          minHeight = 0,
          maxWidth = boundWidth,
          maxHeight = boundHeight;

        for (let i = 0; i < count; i++) {
          let x = randomPoint(minWidth, maxWidth),
            y = randomPoint(minHeight, maxHeight);

          x = Math.floor(x / 10) * 10;
          y = Math.floor(y / 10) * 10;

          pointMap.set(i, { x, y, color: randomColor() });
        }
      }

      // 生成随机点的坐标
      function randomPoint(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
      }

      // 生成随机颜色
      function randomColor() {
        const letters = '0123456789ABCDEF';
        let color = '#';
        for (let i = 0; i < 6; i++) {
          color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
      }

      // 绘制点(圆)
      function drawCircle(x, y, color = 'black') {
        ctx.beginPath();
        ctx.arc(x, y, 10, 0, 2 * Math.PI);
        ctx.fillStyle = color;
        ctx.fill();
      }
    </script>
  </body>
</html>
posted @ 2024-06-02 19:09  _clai  阅读(3)  评论(0编辑  收藏  举报