如何获得鼠标单击 canvas 时的 "rotated" 坐标?
How can I get the "rotated" coordinates of a mouse-click on a canvas?
背景
我有一个显示 canvas 的图像编辑程序,用户可以在其中执行多种操作,例如绘制形状。用户绘制的形状被发送到服务器,然后服务器将它们作为元素添加到 XML 文件中。 XML 文件被发送回客户端。客户端然后读取此 XML 文件并为每个元素绘制相应的形状。
我想为我的程序添加新功能。我想这样做,以便用户可以在本地旋转视图。也就是说,该用户应该能够单击将 canvas 向右旋转 90 度的按钮。因此,如果形状位于 40x40 canvas 的位置 (10, 10),则单击此按钮时它将位于 (30, 10)。
我是通过如下方式使用旋转和平移实现的:
ctx.translate(width/2,height/2);
ctx.rotate(90*Math.PI/180);
ctx.translate(-width/2,-height/2);
// draw shapes from returned XML file
所以现在当从我的 XML 文件中绘制形状时,它们将显示为旋转的。
问题
当我尝试在旋转的 canvas 上绘制新形状时出现问题。假设我正在绘制一个从 (10, 10) 到 (15, 15) 的矩形。该程序会将这些坐标发送到我的服务器。然后服务器会将它们添加到 XML 文件并将 XML 文件发送回我的客户端。当我的客户完成其绘图周期时,它将绘制新形状。然而,由于 canvas 已经旋转,它会绘制在旋转位置的形状。
所以我正在从 (10, 10) 绘制到 (15, 15),但是我在 canvas 上看到的形状从 (30, 10) 到 (25, 15)。
为了解决这个问题,我的想法是不向服务器发送鼠标的实际坐标,而是向它提供坐标,就好像 canvas 已经向与鼠标相反的方向旋转了与旋转按钮创建的旋转度数相同。
因此,如果旋转度数为 90 并且我单击 (10, 10),而不是提供我的程序 (10, 10),我会提供 (10, 30)。这样在绘制它时它会旋转它并且它会出现在正确的位置。
因此我的问题是,如何获得鼠标单击 canvas 时的 "rotated" 坐标? (没有任何外部库)
// Code to draw a rectangle
Rectangle.prototype.handleInput = function() {
var coord = {};
var anchor = {};
var imgData = s.ctx.getImageData(0, 0, s.width, s.height);
var drawingSquare = false;
var squareDrawn = false;
var color, thickness;
var mouseMoved;
s.canvas.onmousedown = function(e) {
mouseMoved = false;
color = getColor();
thickness = getThickness();
anchor.x = e.clientX - s.getX();
anchor.y = e.clientY - s.getY();
drawingSquare = true;
imgData = s.ctx.getImageData(0, 0, s.width, s.height);
};
s.canvas.onmousemove = function(e) {
if (drawingSquare) {
mouseMoved = true;
coord.x = e.clientX - s.getX();
coord.y = e.clientY - s.getY();
s.ctx.putImageData(imgData, 0, 0);
Rectangle.draw(anchor.x, anchor.y, coord.x, coord.y, color, thickness);
squareDrawn = true;
xml.editRect(anchor.x, anchor.y, getColor(), getThickness(), coord.x, coord.y);
}
};
s.canvas.onmouseup = function(e) {
drawingSquare = false;
// startX, startY, strokeStyle, lineWidth, endX, endY
if (mouseMoved) {
sm.save();
xml.addRect(anchor.x, anchor.y, getColor(), getThickness(), coord.x, coord.y);
}
如果您只是以 90 度为增量旋转,那么数学就相当简单了。此示例将坐标向左旋转 90°。
unrotated.x = anchor.y;
unrotated.y = s.height - anchor.x;
其他旋转类似,只是交换进出 x 和 y 位置以及宽度和高度。
背景
我有一个显示 canvas 的图像编辑程序,用户可以在其中执行多种操作,例如绘制形状。用户绘制的形状被发送到服务器,然后服务器将它们作为元素添加到 XML 文件中。 XML 文件被发送回客户端。客户端然后读取此 XML 文件并为每个元素绘制相应的形状。
我想为我的程序添加新功能。我想这样做,以便用户可以在本地旋转视图。也就是说,该用户应该能够单击将 canvas 向右旋转 90 度的按钮。因此,如果形状位于 40x40 canvas 的位置 (10, 10),则单击此按钮时它将位于 (30, 10)。
我是通过如下方式使用旋转和平移实现的:
ctx.translate(width/2,height/2);
ctx.rotate(90*Math.PI/180);
ctx.translate(-width/2,-height/2);
// draw shapes from returned XML file
所以现在当从我的 XML 文件中绘制形状时,它们将显示为旋转的。
问题
当我尝试在旋转的 canvas 上绘制新形状时出现问题。假设我正在绘制一个从 (10, 10) 到 (15, 15) 的矩形。该程序会将这些坐标发送到我的服务器。然后服务器会将它们添加到 XML 文件并将 XML 文件发送回我的客户端。当我的客户完成其绘图周期时,它将绘制新形状。然而,由于 canvas 已经旋转,它会绘制在旋转位置的形状。
所以我正在从 (10, 10) 绘制到 (15, 15),但是我在 canvas 上看到的形状从 (30, 10) 到 (25, 15)。
为了解决这个问题,我的想法是不向服务器发送鼠标的实际坐标,而是向它提供坐标,就好像 canvas 已经向与鼠标相反的方向旋转了与旋转按钮创建的旋转度数相同。
因此,如果旋转度数为 90 并且我单击 (10, 10),而不是提供我的程序 (10, 10),我会提供 (10, 30)。这样在绘制它时它会旋转它并且它会出现在正确的位置。
因此我的问题是,如何获得鼠标单击 canvas 时的 "rotated" 坐标? (没有任何外部库)
// Code to draw a rectangle
Rectangle.prototype.handleInput = function() {
var coord = {};
var anchor = {};
var imgData = s.ctx.getImageData(0, 0, s.width, s.height);
var drawingSquare = false;
var squareDrawn = false;
var color, thickness;
var mouseMoved;
s.canvas.onmousedown = function(e) {
mouseMoved = false;
color = getColor();
thickness = getThickness();
anchor.x = e.clientX - s.getX();
anchor.y = e.clientY - s.getY();
drawingSquare = true;
imgData = s.ctx.getImageData(0, 0, s.width, s.height);
};
s.canvas.onmousemove = function(e) {
if (drawingSquare) {
mouseMoved = true;
coord.x = e.clientX - s.getX();
coord.y = e.clientY - s.getY();
s.ctx.putImageData(imgData, 0, 0);
Rectangle.draw(anchor.x, anchor.y, coord.x, coord.y, color, thickness);
squareDrawn = true;
xml.editRect(anchor.x, anchor.y, getColor(), getThickness(), coord.x, coord.y);
}
};
s.canvas.onmouseup = function(e) {
drawingSquare = false;
// startX, startY, strokeStyle, lineWidth, endX, endY
if (mouseMoved) {
sm.save();
xml.addRect(anchor.x, anchor.y, getColor(), getThickness(), coord.x, coord.y);
}
如果您只是以 90 度为增量旋转,那么数学就相当简单了。此示例将坐标向左旋转 90°。
unrotated.x = anchor.y;
unrotated.y = s.height - anchor.x;
其他旋转类似,只是交换进出 x 和 y 位置以及宽度和高度。