Muszę wiedzieć, jak narysować wielokąty na płótnie. Bez używania jQuery lub czegoś podobnego.
Odpowiedzi:
Utwórz ścieżkę za pomocą moveTo
i lineTo
( demo na żywo ):
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();
z http://www.scienceprimer.com/drawing-regular-polygons-javascript-canvas :
Poniższy kod narysuje sześciokąt. Zmień liczbę boków, aby utworzyć różne regularne wielokąty.
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();
Możesz wypełnić kształt.
var angle = i * 2 * Math.PI / shape.currentSides + rotation
dodane do wartości cos i sin zadziałały dla mnie ... jeszcze raz dziękuję
sin
i cos
wywołaj i zmień Ycenter +
na Ycenter -
w obu miejscach (pozostawiając to jako sumę, a nie różnicę wartości powoduje, że zaczyna się od punktu na dole powstałego kształtu). Nie jestem mądrym człowiekiem, jeśli chodzi o trygonometrię, więc bierz to z przymrużeniem oka; ale to osiągnęło to, co chciałem przynajmniej.
//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
metodę waniliową JavaScript . Ta jedna linia kodu tak bardzo uprościła sprawę. Zwykle używam jQuery, .each()
ale jego aplikacja jest znacznie mniej wszechstronna.
var
, w powyższym kodzie item
jest zanieczyszczenie globalnej przestrzeni nazw. Wszystko jest w jednej linii, co zmniejsza czytelność. Jeśli nie zależy Ci na czytelności, równie dobrze możesz usunąć nawiasy klamrowe.
//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');
Oto funkcja, która obsługuje nawet rysowanie zgodnie z ruchem wskazówek zegara / przeciwnie do ruchu wskazówek zegara, dzięki której kontrolujesz wypełnienia za pomocą niezerowej reguły nawijania.
Oto pełny artykuł o tym, jak to działa i nie tylko.
// 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();
Możesz użyć metody lineTo () tak samo jak: 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();
jeśli nie chcesz wypełniać wielokąta, użyj metody stroke () zamiast wypełnienia ()
Możesz również sprawdzić: http://www.authorcode.com/draw-and-fill-a-polygon-and-triangle-in-html5/
dzięki
Oprócz @canvastag użyj while
pętli, która shift
moim zdaniem jest bardziej zwięzła:
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();
Aby utworzyć prosty sześciokąt bez potrzeby tworzenia pętli, wystarczy użyć funkcji beginPath (). Upewnij się, że plik canvas.getContext ('2d') jest równy ctx, jeśli nie, to nie zadziała.
Lubię też dodawać zmienną o nazwie czasy, której mogę użyć do skalowania obiektu, jeśli zajdzie taka potrzeba, ale nie muszę zmieniać każdej liczby.
// 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();
Dla osób poszukujących regularnych wielokątów:
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);
}
Posługiwać się:
//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();