Відповіді:
Створіть шлях за допомогою 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();
з 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>
cxt.save();
cxt.fillStyle = "#FF000";
cxt.fill();
cxt.restore();
Ви можете заповнити форму.
var angle = i * 2 * Math.PI / shape.currentSides + rotation
додані до значень cos та sin працювали для мене ... ще раз спасибі
sin
і cos
виклики і зміни Ycenter +
в Ycenter -
обох місцях (залишаючи його у вигляді суми , а не різниці значень в результаті це починається з точки внизу результуючої фігури). Я не розумний чоловік, коли справа доходить до тригеру, тож візьміть із зерном солі; але це досягло того, що я хотів щонайменше.
//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();
for
метод ванільного JavaScript . Цей рядок коду настільки спростив ситуацію. Зазвичай я використовую jQuery, .each()
але його додаток набагато менш універсальний.
var
, у наведеному вище коді item
забруднюється глобальний простір імен. Все на одному рядку, що зменшує читабельність. Якщо ви не дбаєте про читабельність, тоді ви можете також видалити фігурні дужки.
//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');
Ось функція, яка навіть підтримує креслення за годинниковою стрілкою / проти годинникової стрілки, щоб контролювати заливки за допомогою ненульового правила обмотки.
Ось повна стаття про те, як це працює, та багато іншого.
// 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();
Ви можете використовувати метод lineTo () так само, як: 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();
якщо ви не хочете заповнювати багатокутник, використовуйте метод stroke () замість fill ()
Ви також можете перевірити наступне: http://www.authorcode.com/draw-and-fill-a-polygon-and-triangle-in-html5/
Дякую
На додаток до @canvastag, використовуйте while
цикл із, на shift
мою думку, більш стислим:
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();
Щоб зробити простий шестикутник без необхідності циклу, Просто використовуйте функцію beginPath (). Переконайтеся, що ваш canvas.getContext ('2d') дорівнює ctx, якщо ні, він не буде працювати.
Мені також подобається додавати змінну, яка називається times, яку я можу використати для масштабування об'єкта, якщо мені це потрібно. Це те, що мені не потрібно змінювати кожне число.
// 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();
Для людей, які шукають правильні багатокутники:
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);
}
Використання:
//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();