2016-12-02 6 views
1

Angenommen, ich habe eine 400x200 Canvas. Ich möchte in einem Koordinatensystem arbeiten, wo (0, 0) ist genau in der Mitte der Leinwand und positiv y bedeutet, up und positive x bedeutet richtig.Canvas-Transformation verhält sich nicht wie erwartet

Also, habe ich die Transformation wie folgt:

var ctx = document.getElementById("canvas").getContext("2d"); 
 
ctx.setTransform(1, 0, 0, -1, 200, 100); 
 
ctx.fillRect(-20, -20, 40, 40);
<canvas id="canvas" style="width: 400px; height: 200px"></canvas>

Also, wenn ich das Rechteck wie im Snippet oben füllen, würde ich erwarten, ein Quadrat in der Mitte zentriert zu sehen das Leinwandelement Beim Ausführen des obigen Snippets (im neuesten Chrome) ist das Quadrat jedoch nachweislich nicht zentriert. Warum ist das? Verarsche ich etwas über die Transformationsmatrix? Wenn ja, wie kann ich mein Ziel erreichen?

Antwort

3

Die Größe für das Leinenelement nicht richtig eingestellt, die die Leinwand standardmäßig auf 150 Pixel in der Höhe bedeutet, die dann gestreckt wird, mit CSS aus. Dies gibt die Illusion, dass das Objekt versetzt ist.

Um sein Attribut Leinwandgröße anstelle von CSS richtig eingestellt:

<canvas id="canvas" width=400 height=200></canvas> 

auch bewusst sein, dass die Y-Achse jetzt umgedreht wird, so dass jeder Text und Bilder upside-down als auch gezogen werden, . Diese müssen lokal korrekt transformiert werden.

+0

Ah, verstehe ich vollständig. Ich war mir nicht bewusst, dass es einen Unterschied zwischen den CSS-Attributen und den "nativen" Canvas-Attributen gab. Vielen Dank! – cemulate

1

Das Problem scheint zu sein, dass die Abmessungen in style ignoriert werden und standardmäßig die Standardabmessungen 300×150. So setzte sie richtig mit

<canvas id="canvas" width="400" height="200"></canvas> 

Unabhängig davon, kann es eine gute Idee, um nicht auf hartcodierte Dimensionen zu verlassen, vor allem wenn man ohnehin ein lokales Koordinatensystem verwenden will.

My Schnipsel Modifikationen:

  • die tatsächlichen Abmessungen und Leinwand Skala verwenden, so dass die lokalen Koordinaten noch mindestens das Quadrat (-100,100)×(-100,100) enthalten.

  • Fügen Sie vor dem Festlegen der Transformation ein Koordinatenkreuz hinzu, das zeigt, dass das Quadrat selbst dann, wenn die Leinwand "falsch" ist, am Koordinatenursprung liegt.

  • Nach der Transformation fügen Sie einen Kreis bei positiver y Position hinzu, um zu zeigen, dass "up" wirklich aktiv ist.

var cnv = document.getElementById("canvas"); 
 
var w = cnv.width, h = cnv.height; 
 
var ctx = cnv.getContext("2d"); 
 
ctx.beginPath(); 
 
ctx.moveTo(0,h/2); ctx.lineTo(w,h/2); 
 
ctx.moveTo(w/2,0); ctx.lineTo(w/2,h); 
 
ctx.closePath(); ctx.stroke(); 
 

 
var scale = Math.min(w,h)/200.0; 
 

 
ctx.setTransform(scale, 0, 0, -scale, w/2, h/2); 
 

 
ctx.moveTo(0,50); ctx.arc(0,50,10,0,2*Math.PI); ctx.stroke(); 
 

 
ctx.fillRect(-20, -20, 40, 40);
<canvas id="canvas" width="450" height="250"></canvas>

Verwandte Themen