趣味Canvas之太极图☯️

1,638 阅读1分钟

我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!

最开始的时候,通过 document.querySelector("#canvas") 获取到页面的 canvas 元素。使用变量记录 canvas 的宽和高。通过 ctx.arc 来画圆。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>太极图</title>
  <style>
    * {
      padding: 0;
      margin: 0;
    }

    body {
      width: 100%;
      min-height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  </style>
</head>

<body>
  <canvas id="canvas" width="600" height="600"></canvas>
</body>
<script>
  let canvas = document.querySelector("#canvas")
  let ctx = canvas.getContext('2d')
  let cw = canvas.width
  let ch = canvas.height
  let hue = 200

  function SupremePole() {
    this.color_str = "hsla(" + hue + ",100%,5%,1)"
    //添加一个边框线
    ctx.lineWidth = 1;
    ctx.strokeStyle = '#999';
    ctx.beginPath();
    ctx.arc(0, 0, cw / 2 - 10, 0, Math.PI * 2, false);
    ctx.stroke();
    ctx.closePath();
  }

  SupremePole()
</script>

</html>

图片.png

有点丑?加上一个ctx.translate(cw / 2, ch / 2)

图片.png

// 画一个半圆(外部上半部分)
ctx.fillStyle = this.color_str;
ctx.beginPath();
ctx.arc(0, 0, cw / 2 - 10, 0, Math.PI, true);
ctx.fill();
ctx.closePath();

图片.png

//画一个半圆( 内部下半部分)
ctx.fillStyle = this.color_str;
ctx.beginPath();
ctx.arc(145, -0.6, 145, 0, Math.PI, false);
ctx.fill();
ctx.closePath();

图片.png

// 画一个半圆( 内部上半部分)
ctx.fillStyle = "white";
ctx.beginPath();
ctx.arc(-145, 0.6, 145, 0, Math.PI, true);
ctx.fill();
ctx.closePath();

图片.png

// 画一个整圆(有颜色)
ctx.fillStyle = this.color_str;
ctx.beginPath();
ctx.arc(-145, 0.6, 35, 0, Math.PI * 2, true);
ctx.fill();
ctx.closePath();

// 画一个整圆(无颜色)
ctx.fillStyle = "white";
ctx.beginPath();
ctx.arc(145, -0.6, 35, 0, Math.PI * 2, true);
ctx.fill();
ctx.closePath();

图片.png

太极都是动起来的 setInterval(SupremePole, 100)

ctx.translate(cw / 2, ch / 2)
ctx.rotate(angle)

// ...

// 更新一下angle,让太极图旋转起来
angle += speed

Jul-17-2022 09-10-58.gif

//重置画布的原点坐标
ctx.save();


// ...

// 重置一下
ctx.restore();

Jul-17-2022 09-14-29.gif

// 画一个遮罩层
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, cw, ch);
ctx.lineWidth = 10;

Jul-17-2022 09-17-21.gif

当鼠标放进去的时候,希望可以加快速度

  function windowPoint2Canvas(c, x, y) {
    let canvasBox = c.getBoundingClientRect();
    let canvas_x = Math.abs(x - canvasBox.left);
    let canvas_y = Math.abs(y - canvasBox.top);
    return {
      x: canvas_x,
      y: canvas_y
    };
  }

  canvas.addEventListener("mousemove", function (e) {
    // 把窗口坐标转换为画布坐标
    let canvasPoint = windowPoint2Canvas(canvas, e.clientX, e.clientY)

    console.log(canvasPoint)
  })

计算出鼠标距离原点的距离

let distance = Math.floor(Math.sqrt(Math.pow(mouse_x - cw / 2, 2) + Math.pow(mouse_y - ch / 2, 2)))
// 改变速度
speed = distance / 1000;

// 改变颜色
hue += 0.5;

图片.png

最后的最后,让我们来一下效果图吧

Jul-17-2022 09-53-40.gif

代码地址:

gitee.com/suiboyu/fro…