A yellow and purple gradient, with hexagon shape highlights background, with the words 'How to draw any regular shape with one JavaScript function' and the date May 26, 2023

如何只用一个 JavaScript 函数绘制任何规则图形

作者头像Ruth John阅读时间:4 分钟

好的,我知道我用了标题党,但请耐心听我讲。我想分享一个我用了很久的函数。我最初编写它是为了绘制六边形——六边形很酷,很多六边形更好,而密铺的六边形是最好的。所以我写了一个函数来绘制一个,然后我可以重复它。

在这样做的过程中,我开始修改六边形以能够绘制一些基于几个参数的形状。让我们从我对六边形所做的开始,然后从那里开始。

使用 JavaScript 绘制六边形

六边形有六条相等边。如果我们将起点想象成六边形的中心,我们可以围绕这个点移动六次,在移动时连接每个点以形成边。

让我们首先创建一个具有2d 绘图上下文<canvas>。在本例中,我们将画布大小固定为 400 x 200 像素,并将中心点设置为(200, 100)

html
<canvas></canvas>
js
const canvas = document.querySelector("canvas");
canvas.width = 400;
canvas.height = 200;

const ctx = canvas.getContext("2d");
const cx = 200;
const cy = 100;

现在我们需要确定围绕中心的点的 x(水平)和 y(垂直)位置,当用线连接时,将形成六条相等边。为此,我们使用从中心到点的测量值(我们称之为半径)和从中心的指向方向的角度。

由于完整旋转中有 360 度,而我们想要创建 6 个点,我们可以将 360/6 除以,并且知道我们将每 60 度创建一个点。但是,这有一个小小的警告——JavaScript 使用弧度而不是。我始终记得的一件事是,弧度中的值pi为 180 度,或半个圆。所以(Math.PI*2)/6将给我们每个弧度的旋转更简单的Math.PI/3

接下来,我们需要添加一些三角函数来找到每个点的 x 和 y 位置。对于 x 位置,我们可以使用半径乘以cos(角度)的和,对于 y 位置,使用半径乘以sin(角度)。让我们把它们放在一起,添加到我们上面的 JavaScript 代码中

js
// set the radius of the hexagon
const radius = 50;

// move the canvas to the center position
ctx.translate(cx, cy);

for (let i = 0; i < 6; i++) {
  // calculate the rotation
  const rotation = (Math.PI / 3) * i;

  // for the first point move to
  if (i === 0) {
    ctx.moveTo(radius * Math.cos(rotation), radius * Math.sin(rotation));
  } else {
    // for the rest draw a line
    ctx.lineTo(radius * Math.cos(rotation), radius * Math.sin(rotation));
  }
}

// close path and stroke it
ctx.closePath();
ctx.stroke();

绘制任意边数的图形

假设我们想绘制一个三角形、一个正方形或一个八边形。在上面用于绘制六边形的函数中,我们只需要修改在for循环中绘制线条的次数和每个点的角度。

让我们将其转换为一个函数,该函数将中心点、半径和边数作为参数

js
function drawShape(x, y, r, sides) {
  // move the canvas to the center position
  ctx.translate(x, y);

  for (let i = 0; i < sides; i++) {
    // calculate the rotation
    const rotation = ((Math.PI * 2) / sides) * i;

    // for the first point move to
    if (i === 0) {
      ctx.moveTo(r * Math.cos(rotation), r * Math.sin(rotation));
    } else {
      // for the rest draw a line
      ctx.lineTo(r * Math.cos(rotation), r * Math.sin(rotation));
    }
  }

  // close path and stroke it
  ctx.closePath();
  ctx.stroke();

  // reset the translate position
  ctx.resetTransform();
}

现在我们可以通过调整sides参数来绘制不同的形状

js
drawShape(100, 100, 50, 3);
drawShape(225, 100, 50, 7);
drawShape(350, 100, 50, 4);

总结

这是一个关于在网页上绘制的<canvas>元素以及您可以用来绘制形状的一些方法的简要介绍。如果您想更深入地了解所有部分是如何工作的,这里是对我们使用内容的回顾

为了计算每个点的位置,我们使用了一些数学和三角函数

要获得更多关于您可以使用<canvas>元素做什么的灵感,请查看Canvas 教程,该教程从基础开始,然后涵盖更高级的主题,如动画和像素操作。

您可以通过多种方式扩展此基本形状函数。我喜欢包含一个内半径,这样您就可以创建菱形和星星。我还尝试了一些曲线而不是直线——随意自己尝试。或者尝试一些密铺,这总是很有趣的!

An image of colorful hexagons and diamonds in a tessellated pattern

如果您尝试使用此函数,并且如果您像我一样喜欢它,请告诉我。与往常一样,请随时在GitHub 讨论中留下任何反馈,或加入我们在 MDN Web Docs Discord 服务器上的聊天。

关注 MDN

获取 MDN 电子邮件通讯,不错过关于最新 Web 开发趋势、技巧和最佳实践的任何更新。