如何在 HTML5 画布上绘制多边形?

IT技术 javascript css html canvas
2021-03-02 10:27:37

我需要知道如何在画布上绘制多边形。不使用 jQuery 或类似的东西。

6个回答

使用moveTo创建路径lineTo现场演示):

var ctx = canvas.getContext('2d');
ctx.fillStyle = '#f00';
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(100,50);
ctx.lineTo(50, 100);
ctx.lineTo(0, 90);
ctx.closePath();
ctx.fill();
优秀的解决方案。非常整洁的代码。谢谢你@phihag。我能理解的东西!
2021-04-17 10:27:37
@Gio Borje:AFAIK,jsFiddle 不关心画布,那是你的浏览器。jsFiddle 只是将您的 HTML/CSS/JS 反馈给您。
2021-04-26 10:27:37
@user1893354 非常感谢您的通知。确实,那里的 jsfiddle 似乎存在问题 - 错误消息与画布完全无关。替换为一个非常简单的现场演示站点。
2021-04-30 10:27:37
你能用ctx代替c2吗?我认为它更常用于画布上下文。顺便说一句很好的答案
2021-05-04 10:27:37

来自http://www.scienceprimer.com/drawing-regular-polygons-javascript-canvas

下面的代码将绘制一个六边形。更改边数以创建不同的正多边形。

var ctx = document.getElementById('hexagon').getContext('2d');

// hexagon
var numberOfSides = 6,
    size = 20,
    Xcenter = 25,
    Ycenter = 25;

ctx.beginPath();
ctx.moveTo (Xcenter +  size * Math.cos(0), Ycenter +  size *  Math.sin(0));          

for (var i = 1; i <= numberOfSides;i += 1) {
  ctx.lineTo (Xcenter + size * Math.cos(i * 2 * Math.PI / numberOfSides), Ycenter + size * Math.sin(i * 2 * Math.PI / numberOfSides));
}

ctx.strokeStyle = "#000000";
ctx.lineWidth = 1;
ctx.stroke();
#hexagon { border: thin dashed red; }
<canvas id="hexagon"></canvas>

感谢您 - 在阅读您提供的科学入门链接上的逻辑后,我遇到了相同的解决方案。var angle = i * 2 * Math.PI / shape.currentSides + rotation添加到 cos 和 sin 值对我有用...再次感谢
2021-04-21 10:27:37
如果(在我的情况下)您只希望起点是多边形的中间顶部而不是中间右侧,请翻转sincos调用并在两个位置更改Ycenter +Ycenter -(将其保留为总和而不是值的差)导致它从合成形状底部的一个点开始)。说到trig,我不是一个聪明的人,所以请谨慎对待;但这至少达到了我想要的。
2021-04-25 10:27:37
有几种方法可以得到你想要的东西。一种选择是使用内置的 cxt.rotate() 方法 [连同 cxt.save() 和 cxt.restore()] 来旋转画布的一部分。或者,向 cos 和 sin 函数添加一致的值也可以。请参阅此 jsfiddle 进行演示:jsfiddle.net/kwyhn3ba
2021-04-30 10:27:37
这很棒,非常优雅,此外,如果您添加: cxt.save(); cxt.fillStyle = "#FF000"; cxt.fill(); cxt.restore(); 您可以填充形状。
2021-05-08 10:27:37
这很棒 - 我一直在玩它,但不知道如何让选定的多边形旋转 - 有什么想法吗?
2021-05-13 10:27:37
//poly [x,y, x,y, x,y.....];
var poly=[ 5,5, 100,50, 50,100, 10,90 ];
var canvas=document.getElementById("canvas")
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#f00';

ctx.beginPath();
ctx.moveTo(poly[0], poly[1]);
for( item=2 ; item < poly.length-1 ; item+=2 ){ctx.lineTo( poly[item] , poly[item+1] )}

ctx.closePath();
ctx.fill();
@canvastag 不错的动态工作。这个答案比我接受的答案更好。我不明白“Query .each()”……这是一些占用内存的神奇函数。同样对于全局命名空间 ;) 有趣的是,这只是一个例子,如果你想要的话,让它像类一样。
2021-04-21 10:27:37
这就是为什么我希望我能从根本上理解 JavaScript vanillafor方法。那一行代码大大简化了事情。我通常使用 jQuery,.each()但它的应用程序的通用性要差得多。
2021-04-24 10:27:37
@AlexanderDixon 上面的 javascript 真的不是一个很好的例子。所有变量都需要var,在上面的代码中item是一个污染全局的命名空间。一切都在一行上,这降低了可读性。如果您不关心可读性,那么您不妨删除大括号。
2021-04-26 10:27:37
//create and fill polygon
CanvasRenderingContext2D.prototype.fillPolygon = function (pointsArray, fillColor,     strokeColor) {
    if (pointsArray.length <= 0) return;
    this.moveTo(pointsArray[0][0], pointsArray[0][1]);
    for (var i = 0; i < pointsArray.length; i++) {
        this.lineTo(pointsArray[i][0], pointsArray[i][1]);
    }
    if (strokeColor != null && strokeColor != undefined)
        this.strokeStyle = strokeColor;

    if (fillColor != null && fillColor != undefined) {
        this.fillStyle = fillColor;
        this.fill();
    }
}
//And you can use this method as 
var polygonPoints = [[10,100],[20,75],[50,100],[100,100],[10,100]];
context.fillPolygon(polygonPoints, '#F00','#000');
有趣......实际上第一点做了一个 moveTo 和一个 lineTo ......但现在我想起来......谁在乎?
2021-05-04 10:27:37

这是一个甚至支持顺时针/逆时针绘图的功能,您可以使用非零缠绕规则控制填充。

这是一篇关于它是如何工作的以及更多内容的完整文章。

// Defines a path for any regular polygon with the specified number of sides and radius, 
// centered on the provide x and y coordinates.
// optional parameters: startAngle and anticlockwise

function polygon(ctx, x, y, radius, sides, startAngle, anticlockwise) {
  if (sides < 3) return;
  var a = (Math.PI * 2)/sides;
  a = anticlockwise?-a:a;
  ctx.save();
  ctx.translate(x,y);
  ctx.rotate(startAngle);
  ctx.moveTo(radius,0);
  for (var i = 1; i < sides; i++) {
    ctx.lineTo(radius*Math.cos(a*i),radius*Math.sin(a*i));
  }
  ctx.closePath();
  ctx.restore();
}

// Example using the function.
// Define a path in the shape of a pentagon and then fill and stroke it.
context.beginPath();
polygon(context,125,125,100,5,-Math.PI/2);
context.fillStyle="rgba(227,11,93,0.75)";
context.fill();
context.stroke();
那篇文章很长,说“你画了一个边缘较少的圆”。您可能想要缓存结果以避免过多地调用 cos 和 sin(如果已经这样做了,请原谅我,我不是 JavaScript 程序员)。
2021-04-26 10:27:37