HTML5 canvas在缩放和翻译后获取坐标 [英] HTML5 canvas get coordinates after zoom and translate

查看:2827
本文介绍了HTML5 canvas在缩放和翻译后获取坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

>



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



我的问题:我试图找出一个算法,返回鼠标点击相对于图像的像素坐标,而不是画布,同时考虑缩放和翻译。
我知道有很多话题已经在这,但没有我见过的工作。我的问题是当我有多个翻译和缩放。我可以放大一次并获得正确的坐标,然后我可以缩放和获得正确的坐标,但一旦我放大或缩放不止一次,坐标是关闭。



这里是我到目前为止。

  //从画布获取像素坐标mousePos.x,mousePos.y 
(mousePos.x - x_translation)/ scale //同样为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 );
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和accY分别是x和y的累积位移,xShift和xShift yShift分别是x和y的增量位移

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



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



感谢



更新:



图像,绿点是我点击的位置,红点是我计算该点的位置,使用markE的方法。 m值是markE方法中的矩阵值。

解决方案

当您命令上下文进行翻译和缩放时,这些被称为画布变换。



Canvas转换基于一个可以用6个数组元素表示的矩阵:

  // an表示画布仿射变换矩阵的数组
var matrix = [1,0,0,1,0,0];

如果你做context.translate或context.scale并同时更新矩阵,该矩阵将未转换的X / Y坐标(如鼠标事件)转换为转换的图像坐标。



context.translate: b
$ b

您可以同时执行context.translate(x,y)并在矩阵中跟踪该翻译,如下所示:

  // do the translate 
//但也保存在矩阵中的转换
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:

您可以同时执行context.scale(x,y)并跟踪缩放矩阵如下:

  //执行缩放
//但也保存在矩阵中的比例
function scale(x,y){
matrix [0] * = x;
matrix [1] * = x;
matrix [2] * = y;
matrix [3] * = y;
ctx.scale(x,y);
}

将鼠标坐标转换为转换后的图像坐标 p>

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



幸运的是,转换矩阵已经跟踪您所有累积的翻译和缩放。



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

  //将mouseX / mouseY坐标转换为变换坐标

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});
}


BACKGROUND: I have an HTML5 canvas and I have an image drawn on it. Now when the image is first loaded, it is loaded at a scale of 100%. The image is 5000 x 5000. And the canvas size is 600 x 600. So onload, I only see the first 600 x-pixels and 600 y-pixels. I have the option of scaling and translating the image on the canvas.

MY ISSUE: I am trying to figure out an algorithm that return the pixel coordinates of a mouse click relative to the image, not the canvas while taking into account scaling and translating. I know there are a lot of topics already on this, but nothing I've seen has worked. My issue is when I have multiple translations and scaling. I can zoom once and get the correct coordinates, and I can then scale and get the right coordinates again, but once I zoom or scale more than once, the coordinates are off.

Here is what I have so far.

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

where current zoom is the accumulative zoom. and zoomAcc is the single iteration of zoom at that point. So in this case, when I zoom in, zoomAcc is always 1.1, and currentZoom = currentZoom*zoomAcc.

Why is this wrong? if someone can please show me how to track these transformations and then apply them to mousePos.x and mousePos.y I would be grateful.

thanks

UPDATE:

In the image, the green dot is where I clicked, the red dot is where my calculation of that point is calculated, using markE's method. The m values are the matrix values in your markE's method.

解决方案

When you command the context to translate and scale, these are known as canvas transformations.

Canvas transformations are based on a matrix that can be represented by 6 array elements:

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

If you do context.translate or context.scale and also simultaneously update the matrix, then you can use the matrix to convert untransformed X/Y coordinates (like mouse events) into transformed image coordinates.

context.translate:

You can simultaneously do context.translate(x,y) and track that translation in the matrix like this:

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

You can simultaneously do context.scale(x,y) and track that scaling the matrix like this:

// 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 mouse coordinates to transformed image coordinates

The problem is the browser is unaware that you have transformed your canvas coordinate system and the browser will return mouse coordinates relative to the browser window--not relative to the transformed canvas.

Fortunately the transformation matrix has been tracking all your accumulated translations and scalings.

You can convert the browser’s window coordinates to transformed coordinates like this:

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

这篇关于HTML5 canvas在缩放和翻译后获取坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆