2011-01-29 1 views
63

Ho bisogno di sapere come disegnare poligoni su una tela. Senza usare jQuery o qualcosa del genere.Come disegnare poligoni su una tela HTML5?

+3

È bene ricordare che tutto ciò che può essere fatto senza una libreria di terze parti, di solito dovrebbe essere fatto così. – Rodrigo

risposta

126

creare un percorso con moveTo e lineTo (live demo):

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

+1, non avevo idea che jsFiddle supportasse le tele HTML5. –

+90

@Gio Borje: AFAIK, jsFiddle non si preoccupa della tela, questo è il tuo browser. jsFiddle ti restituisce il tuo HTML/CSS/JS. –

+0

Ottima soluzione. Codice molto pulito grazie @ phhihag. Qualcosa che posso capire! – sparkle

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

Questo è il motivo per cui vorrei poter comprendere fondamentalmente il metodo JavaScript per 'van. Quella riga di codice ha semplificato così tanto le cose. Di solito uso jQuery '.each()' ma l'applicazione è molto meno versatile. –

+2

@AlexanderDixon Il javascript sopra non è davvero un buon esempio.* Tutte le variabili * hanno bisogno di 'var', nel codice precedente' item' è un inquinante spazio dei nomi globale. Tutto è su un'unica riga, che riduce la leggibilità. Se non ti interessa la leggibilità, allora puoi anche rimuovere le parentesi graffe. – Annan

24

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

Il seguente codice disegnare un esagono. Cambia il numero di lati per creare diversi poligoni regolari.

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

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

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

cxt.strokeStyle = "#000000"; 
cxt.lineWidth = 1; 
cxt.stroke(); 
+2

Questo è stato grande, molto elegante, anche, se si aggiunge: 'cxt.save();' 'cxt.fillStyle =" # FF000 ";' 'cxt.fill();' 'cxt.restore (); È possibile riempire la forma. – samuelkobe

+0

questo è fantastico - sono stato seduto a giocare con esso, ma non riesco a capire come avrei fatto ruotare il poligono scelto - qualche idea? – eskimomatt

+1

Ci sono alcuni modi per ottenere quello che vuoi. Un'opzione è usare il metodo built in cxt.rotate() [insieme a cxt.save() e cxt.restore()] per ruotare le parti del canvas. In alternativa, anche l'aggiunta di un valore coerente alle funzioni cos e sin funzionerà. Vedi questo jsfiddle per una dimostrazione: http://jsfiddle.net/kwyhn3ba/ –

1

È possibile utilizzare il metodo lineTo() stessa: 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(); 

se non si vuole riempire il poligono di utilizzare il metodo corsa() al posto di riempimento()

È inoltre possibile controllare il seguente: http://www.authorcode.com/draw-and-fill-a-polygon-and-triangle-in-html5/

grazie

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

Ecco una funzione che supporta anche il disegno in senso orario/antiorario per controllare i riempimenti con la regola dell'avvolgimento diverso da zero.

Here is a full article on how it works and more.

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

Questo articolo è piuttosto lungo per dire "il tuo disegnare un cerchio con meno spigoli". Potresti voler memorizzare nella cache i risultati per evitare di chiamare cos e sin così tanto (perdonami se lo fa già, non sono un programmatore JavaScript). – QuantumKarl

1

Oltre a @canvastag, utilizzare un ciclo while con shift credo sia più conciso:

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

di fare un semplice esagono senza la necessità di un ciclo, Just utilizzare la funzione beginPath(). Assicurati che il tuo canvas.getContext ('2d') sia uguale a ctx se non funziona.

Mi piace anche aggiungere una variabile chiamata times che posso utilizzare per ridimensionare l'oggetto se necessario.Questo non è necessario modificare ogni numero.

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