2014-02-12 43 views
7

enter image description hereenter image description hereHTML5画布得到放大后的坐标和翻译

背景:我有一个HTML5的画布和我有它绘制的图像。现在,当图像第一次加载时,它以100%的比例加载。图像是5000 x 5000.画布大小是600 x 600.所以onload,我只看到第一个600 x像素和600 y像素。我可以选择缩放和翻译画布上的图像。

我的问题:我试图找出一种算法,返回的是相对于图像的鼠标点击的像素坐标,而不是画布,同时考虑到缩放和翻译。 我知道这方面已经有很多话题了,但我见过的东西都没有奏效。我的问题是当我有多个翻译和缩放。我可以缩放一次并获得正确的坐标,然后我可以再次缩放并获得正确的坐标,但是一旦我缩放或缩放多次,坐标就会关闭。

这是我到目前为止。

//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 

其中当前缩放是累积缩放。而zoomAcc是该点的单次缩放迭代。所以在这种情况下,当我放大时,zoomAcc总是1.1,currentZoom = currentZoom * zoomAcc。

为什么这是错的?如果有人可以告诉我如何跟踪这些转换,然后将它们应用到mousePos.x和mousePos.y,我将不胜感激。

感谢

UPDATE:

在图像中,绿点是我点击,红点是在我的那点的计算是计算的,使用坊间的方法。 m值是markE方法中的矩阵值。

+0

:那你是如何最终解决了您的问题...我在同样的问题:( – AkshayJ

回答

9

当您命令上下文进行平移和缩放时,这些被称为画布转换。

帆布转换是基于可以通过6的数组元素所表示的矩阵:

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

如果这样做context.translate或context.scale并且也同时更新矩阵,则可以使用矩阵将未转换的X/Y坐标(如鼠标事件)转换为已转换的图像坐标。

context.translate:

可以同时做context.translate(X,Y)和跟踪这样的矩阵翻译:

// 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:

你可以同时做上下文。规模(X,Y)和跟踪缩放这样的矩阵:

​​

转换鼠标坐标变换图像坐标

的问题是,浏览器是不知道你已经改变了你的画布坐标系浏览器将返回相对于浏览器窗口的鼠标坐标 - 而不是相对于转换后的画布。

幸运的是,转换矩阵一直在跟踪您所有的累计翻译和缩放。

您可以将浏览器的窗口坐标转换后的坐标如下:

// 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

坊间卡住了,谢谢我已经按照你的指示,再次,我第一次放大我得到正确的坐标,但当我在变焦后,它已经关闭了,我已经添加了一张图片到我的问题 – flash

+0

你错过了自动缩放由于画布“宽度”和“高度”属性,我想这应该通过添加实际宽度和高度与画布宽度和高度的比率来解决。 – Domi

+0

此外,请不要te某些东西会重置画布的内部变换矩阵。例如。当设置'canvas.width'或'height'时。确保之后重置您的矩阵。 – Domi