Làm cách nào để vẽ đa giác trên canvas HTML5?


95

Tôi cần biết cách vẽ đa giác trên canvas. Mà không cần sử dụng jQuery hoặc bất cứ thứ gì tương tự.


10
Thật tốt khi nhớ rằng bất cứ điều gì có thể được thực hiện mà không cần thư viện của bên thứ ba, thường nên được thực hiện như vậy.
Rodrigo

Câu trả lời:


165

Tạo đường dẫn với moveTolineTo( bản trình diễn trực tiếp ):

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();

100
@Gio Borje: AFAIK, jsFiddle không quan tâm đến canvas, đó là trình duyệt của bạn. jsFiddle chỉ cung cấp lại HTML / CSS / JS cho bạn.
mu quá ngắn

2
Giải pháp tuyệt vời. Mã rất gọn gàng. cảm ơn bạn @phihag. Một cái gì đó mà tôi có thể hiểu!
dõi

1
bạn có thể thay thế c2 bằng ctx? Tôi nghĩ rằng nó được sử dụng phổ biến hơn cho bối cảnh canvas. Câu trả lời rất lớn bằng cách này
gididaf

@ user1893354 Cảm ơn bạn rất nhiều vì đã thông báo. Thật vậy, dường như có vấn đề với jsfiddle ở đó - thông báo lỗi hoàn toàn không liên quan đến canvas. Được thay thế bằng một trang demo trực tiếp rất đơn giản.
phihag

34
//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();

Đây là lý do tại sao tôi ước mình có thể hiểu về cơ bản forphương pháp vanilla của JavaScript . Một dòng mã đó đã đơn giản hóa mọi thứ rất nhiều. Tôi thường sử dụng jQuery .each()nhưng ứng dụng của nó kém linh hoạt hơn nhiều.
Alexander Dixon

7
@AlexanderDixon Đoạn javascript ở trên thực sự không phải là một ví dụ điển hình. Tất cả các biến cần thiết var, trong đoạn mã trên itemlà gây ô nhiễm không gian tên toàn cầu. Mọi thứ đều nằm trên một dòng, điều này làm giảm khả năng đọc. Nếu bạn không quan tâm đến khả năng đọc thì bạn cũng có thể loại bỏ các dấu ngoặc nhọn.
AnnanFay

@canvastag Làm việc tốt, công việc năng động. Câu trả lời này tốt hơn từ câu trả lời được chấp nhận cho tôi. Tôi không hiểu "Truy vấn .each ()" ... đây là một hàm ma thuật nào đó chiếm bộ nhớ. Cũng đối với không gian tên toàn cục;) vui đây chỉ là ví dụ làm cho nó giống như lớp nếu bạn muốn điều đó.
Nikola Lukic

34

từ http://www.scienceprimer.com/drawing-regular-polygons-javascript-canvas :

Đoạn mã sau sẽ vẽ một hình lục giác. Thay đổi số cạnh để tạo đa giác đều khác nhau.

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>


3
Điều này cũng rất tuyệt, rất thanh lịch, nếu bạn thêm: cxt.save(); cxt.fillStyle = "#FF000"; cxt.fill(); cxt.restore(); Bạn có thể điền vào hình dạng.
samuelkobe

điều này thật tuyệt - tôi đã ngồi chơi với nó, nhưng không thể tìm ra cách tôi sẽ xoay đa giác đã chọn - bạn có ý kiến ​​gì không?
eskimomatt

1
Có một số cách để đạt được những gì bạn muốn. Một tùy chọn là sử dụng phương thức cxt.rotate () tích hợp sẵn [cùng với cxt.save () và cxt.restore ()] để xoay các phần của canvas. Ngoài ra, việc thêm một giá trị nhất quán vào các hàm cos và sin cũng sẽ hoạt động. Xem jsfiddle này để trình diễn: jsfiddle.net/kwyhn3ba
Andrew Staroscik

cảm ơn vì điều đó - tôi đã tìm ra giải pháp tương tự sau khi đọc qua logic trên liên kết sơ bộ khoa học mà bạn cung cấp. var angle = i * 2 * Math.PI / shape.currentSides + rotationthêm vào cos và các giá trị sin làm việc cho tôi ... nhờ một lần nữa
eskimomatt

Nếu (như trong trường hợp của tôi), bạn chỉ muốn điểm khởi đầu là top giữa của đa giác chứ không phải là quyền giữa, lật sincoscuộc gọi và thay đổi Ycenter +đến Ycenter -trên cả hai nơi (để lại nó dưới dạng tổng chứ không phải là một sự khác biệt của các giá trị kết quả là nó bắt đầu bằng một điểm ở dưới cùng của hình dạng kết quả). Tôi không phải là một người thông minh khi nói đến đồ trang trí, vì vậy hãy mang theo một hạt muối; nhưng điều này đã đạt được những gì tôi muốn ít nhất.
Joseph Marikle

9
//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');

Thật thú vị ... Thực sự là một bước Tới VÀ một dòng Tới điểm đầu tiên ... nhưng bây giờ tôi nghĩ về nó ... ai quan tâm?
James Newton

3

Đây là một chức năng thậm chí hỗ trợ vẽ theo chiều kim đồng hồ / ngược chiều kim đồng hồ mà bạn kiểm soát điền bằng quy tắc cuộn dây khác 0.

Đây là một bài viết đầy đủ về cách nó hoạt động và hơn thế nữa.

// 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();

Bài báo đó khá dài để nói rằng "bạn vẽ một hình tròn với ít cạnh hơn". Bạn có thể muốn lưu kết quả vào bộ nhớ cache để tránh gọi cos và sin quá nhiều (tha thứ cho tôi nếu nó đã làm điều đó rồi, tôi không phải là một lập trình viên JavaScript).
QuantumKarl

1

Bạn có thể sử dụng phương thức lineTo () giống như: var objctx = canvas.getContext ('2d');

        objctx.beginPath();
        objctx.moveTo(75, 50);
        objctx.lineTo(175, 50);
        objctx.lineTo(200, 75);
        objctx.lineTo(175, 100);
        objctx.lineTo(75, 100);
        objctx.lineTo(50, 75);
        objctx.closePath();
        objctx.fillStyle = "rgb(200,0,0)";
        objctx.fill();

nếu bạn không muốn điền vào đa giác, hãy sử dụng phương thức stroke () ở vị trí của fill ()

Bạn cũng có thể kiểm tra phần sau: http://www.authorcode.com/draw-and-fill-a-polygon-and-triangle-in-html5/

cảm ơn


1

Ngoài @canvastag, sử dụng whilevòng lặp với shifttôi nghĩ là ngắn gọn hơn:

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

var poly = [5, 5, 100, 50, 50, 100, 10, 90];

// copy array
var shape = poly.slice(0);

ctx.fillStyle = '#f00'
ctx.beginPath();
ctx.moveTo(shape.shift(), shape.shift());
while(shape.length) {
  ctx.lineTo(shape.shift(), shape.shift());
}
ctx.closePath();
ctx.fill();

0

Để tạo một hình lục giác đơn giản mà không cần vòng lặp, Chỉ cần sử dụng hàm beginPath (). Đảm bảo canvas.getContext ('2d') của bạn bằng với ctx nếu không nó sẽ không hoạt động.

Tôi cũng muốn thêm một biến có tên là times mà tôi có thể sử dụng để mở rộng đối tượng nếu cần. Đây là những gì tôi không cần thay đổi từng số.

     // Times Variable 

     var times = 1;

    // Create a shape

    ctx.beginPath();
    ctx.moveTo(99*times, 0*times);
    ctx.lineTo(99*times, 0*times);
    ctx.lineTo(198*times, 50*times);
    ctx.lineTo(198*times, 148*times);
    ctx.lineTo(99*times, 198*times);
    ctx.lineTo(99*times, 198*times);
    ctx.lineTo(1*times, 148*times);
    ctx.lineTo(1*times,57*times);
    ctx.closePath();
    ctx.clip();
    ctx.stroke();

0

Đối với những người đang tìm kiếm đa giác thông thường:

function regPolyPath(r,p,ctx){ //Radius, #points, context
  //Azurethi was here!
  ctx.moveTo(r,0);
  for(i=0; i<p+1; i++){
    ctx.rotate(2*Math.PI/p);
    ctx.lineTo(r,0);
  }
  ctx.rotate(-2*Math.PI/p);
}

Sử dụng:

//Get canvas Context
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

ctx.translate(60,60);    //Moves the origin to what is currently 60,60
//ctx.rotate(Rotation);  //Use this if you want the whole polygon rotated
regPolyPath(40,6,ctx);   //Hexagon with radius 40
//ctx.rotate(-Rotation); //remember to 'un-rotate' (or save and restore)
ctx.stroke();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.