2014-02-12 17 views
7

enter image description hereenter image description hereHTML5-Canvas erhalten Koordinaten nach Zoom und

HINTERGRUND übersetzen: Ich habe eine Leinwand HTML5 und ich habe ein Bild auf sie gezogen. Jetzt, wenn das Bild zum ersten Mal geladen wird, wird es in einem Maßstab von 100% geladen. Das Bild ist 5000 x 5000. Und die Leinwandgröße ist 600 x 600. So onload, ich sehe nur die ersten 600 x-Pixel und 600 Y-Pixel. Ich habe die Möglichkeit, das Bild auf der Leinwand zu skalieren und zu übersetzen.

MEIN PROBLEM: Ich versuche einen Algorithmus zu finden, der die Pixelkoordinaten eines Mausklicks relativ zum Bild zurückgibt, nicht die Leinwand, während Skalierung und Übersetzung berücksichtigt werden. Ich weiß, dass es schon viele Themen dazu gibt, aber nichts, was ich gesehen habe, hat funktioniert. Mein Problem ist, wenn ich mehrere Übersetzungen und Skalierungen habe. Ich kann einmal zoomen und bekomme die richtigen Koordinaten, und dann kann ich skalieren und die richtigen Koordinaten wieder holen, aber sobald ich mehr als einmal zoome oder skaliere, sind die Koordinaten ausgeschaltet.

Hier ist was ich bisher habe.

//get pixel coordinates from canvas mousePos.x, mousePos.y 
(mousePos.x - x_translation)/scale //same for mousePos.y 

annotationCanvas.addEventListener('mouseup',function(evt){ 
        dragStart = null; 
        if (!dragged) { 
         var mousePos = getMousePos(canvas, evt); 
         var message1 = " mouse x: " + (mousePos.x) + ' ' + "mouse y: " + (mousePos.y); 
         var message = " x: " + ((mousePos.x + accX)/currentZoom*currentZoom) + ' ' + "y: " + ((mousePos.y + accY)/currentZoom); 
         console.log(message); 
         console.log(message1); 
         console.log("zoomAcc = " + zoomAcc); 
         console.log("currentZoom = " + currentZoom); 
         ctx.fillStyle="#FF0000"; 
         ctx.fillRect((mousePos.x + accX)/currentZoom, (mousePos.y + accY)/currentZoom, -5, -5); 

        } 
      },true); 
//accX and accY are the cumulative shift for x and y respectively, and xShift and xShift yShift are the incremental shifts of x and y respectively 

wobei der aktuelle Zoom der kumulative Zoom ist. und zoomAcc ist die einzige Iteration des Zooms an diesem Punkt. In diesem Fall, wenn ich heranzoome, ist zoomAcc immer 1,1 und currentZoom = currentZoom * zoomAcc.

Warum ist das falsch? Wenn jemand mir bitte zeigen kann, wie man diese Transformationen verfolgt und sie dann auf mousePos.x und mousePos.y anwendet, wäre ich dankbar.

dank

UPDATE:

Im Bild der grüne Punkt ist, wo ich der rote Punkt geklickt wird, wo meine Berechnung dieses Punktes berechnet wird, Markes Methode. Die m-Werte sind die Matrixwerte in der Methode von markE.

+0

: Wie haben Sie endlich Ihr Problem gelöst ... Ich bin auf gleiche Problem hochnäsig :( – AkshayJ

Antwort

9

Wenn Sie den zu übersetzenden und zu skalierenden Kontext steuern, werden diese als Zeichenumwandlungen bezeichnet.

Leinwand Transformationen werden auf einer Matrix basiert, die von 6 Array-Elemente dargestellt werden kann:

// an array representing the canvas affine transformation matrix 
var matrix=[1,0,0,1,0,0]; 

Wenn Sie context.translate oder context.scale tun und die Matrix gleichzeitig aktualisieren auch, dann können Sie die Matrix verwenden um nicht transformierte X/Y-Koordinaten (wie Mausereignisse) in transformierte Bildkoordinaten zu konvertieren.

context.translate:

Sie können in der Matrix, wie dies gleichzeitig tun, dass die Translation context.translate (x, y) und verfolgen:

// do the translate 
// but also save the translate in the matrix 
function translate(x,y){ 
    matrix[4] += matrix[0] * x + matrix[2] * y; 
    matrix[5] += matrix[1] * x + matrix[3] * y; 
    ctx.translate(x,y); 
} 

context.scale:

Sie können gleichzeitig Kontext tun.Skala (x, y) und verfolgen, dass die Matrix wie diese Skalierung:

// do the scale 
// but also save the scale in the matrix 
function scale(x,y){ 
    matrix[0] *= x; 
    matrix[1] *= x; 
    matrix[2] *= y; 
    matrix[3] *= y;  
    ctx.scale(x,y); 
} 

Converting Mauskoordinaten zu transformierenden Bildkoordinaten

Das Problem ist der Browser, dass Sie Ihre Leinwand Koordinatensystem transformiert haben nicht bewusst ist, und der Browser gibt Mauskoordinaten relativ zum Browserfenster zurück - nicht relativ zur transformierten Leinwand.

Zum Glück hat die Transformationsmatrix alle Ihre akkumulierten Übersetzungen und Skalierungen verfolgt.

Sie das Fenster des Browsers umwandeln kann, um transformierte Koordinaten wie diese Koordinaten:

// convert mouseX/mouseY coordinates 
// into transformed coordinates 

function getXY(mouseX,mouseY){ 
    newX = mouseX * matrix[0] + mouseY * matrix[2] + matrix[4]; 
    newY = mouseX * matrix[1] + mouseY * matrix[3] + matrix[5]; 
    return({x:newX,y:newY}); 
} 
+0

MARKE, danke Ich habe Ihre Anweisungen befolgt, und noch einmal, Das erste Mal, wenn ich zoome, bekomme ich die richtigen Koordinaten, aber wenn ich nach diesem Zoom verschiebe, ist es aus. Ich habe ein Bild zu meiner Frage hinzugefügt – flash

+0

Sie vermissen die automatische Skalierung aufgrund der canvas ''width' und' height' Attribute Ich denke, das sollte behoben werden, indem das Verhältnis von tatsächlicher Breite und Höhe zu Leinwandbreite und -höhe hinzugefügt wird – Domi

+0

Auch, bitte nicht dass bestimmte Dinge die interne Transformationsmatrix der Arbeitsfläche zurücksetzen. Z.B. wenn Sie 'canvas.width' oder' height' einstellen. Stellen Sie sicher, dass Sie Ihre Matrix danach zurücksetzen. – Domi

Verwandte Themen