如何使用 JavaScript 和 Raphael 旋转先前拖动的 SVG 对象?
我正在使用 Raphael 库来旋转和拖动图像。我正确地拖动了它,并且我有一个按钮,每次按下它时它都会正确旋转 90 度。但是,当我旋转图像、拖动它,然后尝试再次旋转它时,我遇到了问题。
HTML 中的唯一元素是用于保存 Raphael 画布的 div 和用于旋转图像的按钮。 JavaScript 在这里:
var gboard;
var piece;
window.onload = function ()
{
gboard = Raphael("gameboard", 800, 500);
// piece = gboard.rect(100, 100, 50, 50).attr({fill: "#0CF", "fill-opacity": 1, stroke: "none", cursor: "move"});
piece = gboard.image("piece.gif", 100, 100, 50, 50).attr({cursor: "move"});
piece.drag(dragMove, dragStart, dragStop);
var angle = 0;
document.getElementById('btn').onclick = function () {
angle += 90;
var cx = piece.attr('x') + 25;
var cy = piece.attr('y') + 25;
piece.animate({transform: "R" + angle + ", " + cx + ", " + cy + ""}, 500, "<>");
// piece.transform("R90," + cx + "," + cy);
};
}
// Set up the object for dragging
function dragStart()
{
this.ox = this.attr("x");
this.oy = this.attr("y");
}
// Clean up after dragging ends
function dragStop() {}
/**
* Handle the moving of objects when dragging
* Check the current angle to compensate for rotated coordinate system.
*/
function dragMove(dx, dy)
{
var angle = getAngle(this._['deg']);
if (angle == 90)
this.attr({x: this.ox + dy, y: this.oy - dx});
else if (angle == 180)
this.attr({x: this.ox - dx, y: this.oy - dy});
else if (angle == 270)
this.attr({x: this.ox - dy, y: this.oy + dx});
else // angle == 0
this.attr({x: this.ox + dx, y: this.oy + dy});
}
/**
* Get the simplified equivalent angle (0 <= angle <= 360) for the given angle.
*
* @param deg The angle in degrees
* @return The equivalent angle between 0 and 360
*/
function getAngle(deg)
{
if (deg % 360 == 0)
return 0;
else if (deg < 0)
{
while (deg < 0)
deg += 360;
}
else if (deg > 360)
{
while (deg > 360)
deg -= 360;
}
return deg;
}
I'm using the Raphael library to rotate and drag an image. I have it correctly dragging and I have a button that correctly rotates it 90 degrees each time it's pressed. However I'm having a problem when I rotate the image, drag it, and then try to rotate it again.
The only elements in the HTML are the div to hold the Raphael canvas and the button that rotates the image. The JavaScript is here:
var gboard;
var piece;
window.onload = function ()
{
gboard = Raphael("gameboard", 800, 500);
// piece = gboard.rect(100, 100, 50, 50).attr({fill: "#0CF", "fill-opacity": 1, stroke: "none", cursor: "move"});
piece = gboard.image("piece.gif", 100, 100, 50, 50).attr({cursor: "move"});
piece.drag(dragMove, dragStart, dragStop);
var angle = 0;
document.getElementById('btn').onclick = function () {
angle += 90;
var cx = piece.attr('x') + 25;
var cy = piece.attr('y') + 25;
piece.animate({transform: "R" + angle + ", " + cx + ", " + cy + ""}, 500, "<>");
// piece.transform("R90," + cx + "," + cy);
};
}
// Set up the object for dragging
function dragStart()
{
this.ox = this.attr("x");
this.oy = this.attr("y");
}
// Clean up after dragging ends
function dragStop() {}
/**
* Handle the moving of objects when dragging
* Check the current angle to compensate for rotated coordinate system.
*/
function dragMove(dx, dy)
{
var angle = getAngle(this._['deg']);
if (angle == 90)
this.attr({x: this.ox + dy, y: this.oy - dx});
else if (angle == 180)
this.attr({x: this.ox - dx, y: this.oy - dy});
else if (angle == 270)
this.attr({x: this.ox - dy, y: this.oy + dx});
else // angle == 0
this.attr({x: this.ox + dx, y: this.oy + dy});
}
/**
* Get the simplified equivalent angle (0 <= angle <= 360) for the given angle.
*
* @param deg The angle in degrees
* @return The equivalent angle between 0 and 360
*/
function getAngle(deg)
{
if (deg % 360 == 0)
return 0;
else if (deg < 0)
{
while (deg < 0)
deg += 360;
}
else if (deg > 360)
{
while (deg > 360)
deg -= 360;
}
return deg;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我通过在值发生变化时重新应用所有转换来解决这个问题。
http://alias.io/raphael/free_transform/
来源:https://github.com/ElbertF/Raphael.FreeTransform
I solved this by re-applying all transformations when a value changes.
http://alias.io/raphael/free_transform/
Source: https://github.com/ElbertF/Raphael.FreeTransform
您可以使用变换工具来处理两者,而不是使用 x/y 属性操作位置和使用变换旋转,从而大大简化您的项目。
由于我们在翻译中使用大写“T”,它会忽略同一字符串中先前的翻译命令,因此我们在拖动时不再需要担心当前角度。
jsFiddle
Instead of manipulating the position with the x/y attributes and the rotation with a transform, you can use the transform tool to handle both, simplifying your project quite a bit.
Since we're using a capital 'T' in the translation, which ignores previous translation commands in the same string, we no longer have to worry about the current angle when dragging.
jsFiddle
好奇的;看起来旋转实际上改变了 x 和 y 值。因此,如果旋转 90 度,则将框向右移动 100 像素实际上会将其向上移动 100 像素,然后将其转换为向右移动。这会抛弃 cx 和 cy 值,它们决定了盒子旋转的点。
要明白我的意思,请旋转一次,然后拖动框,同时在检查器中观察 X 和 Y 值。
我可以看到两种方法来解决它:您可以进行数学计算以在每次旋转时重新计算“真实”x 和 y,或者您可以通过附加数据属性(这就是我的方法)自行跟踪 x 和 y会推荐)。祝你好运!
Curious; it looks like the rotation actually alters the x and y values. So if you rotate 90 degrees, moving the box 100 pixels to the right actually moves it 100 pixels up, which is then translated as being to the right. This is throwing off the cx and cy values, which determine the point around which to rotate the box.
To see what I mean, rotate once, then drag the box while watching the X and Y values in the inspector.
I can see two ways to fix it: you can either do the math to recalculate the "real" x and y on every rotation, or you can keep track of the x and y on your own by attaching data attributes (which is what I would recommend). Good luck!