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});
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…