我正在使用RaphaelJS 2.0在一个div中创建几个形状。每个形状都需要能够独立地在div的范围内被拖放。双击形状时,该形状需要旋转90度。然后,它可能会被拖拽,然后再掉落和旋转。
我已经将一些代码加载到fiddler:http://jsfiddle.net/QRZMS/上。基本上是这样的:
window.onload = function () {
var angle = 0;
var R = Raphael("paper", "100%", "100%"),
shape1 = R.rect(100, 100, 100, 50).attr({ fill: "red", stroke: "none" }),
shape2 = R.rect(200, 200, 100, 50).attr({ fill: "green", stroke: "none" }),
shape3 = R.rect(300, 300, 100, 50).attr({ fill: "blue", stroke: "none" }),
shape4 = R.rect(400, 400, 100, 50).attr({ fill: "black", stroke: "none" });
var start = function () {
this.ox = this.attr("x");
this.oy = this.attr("y");
},
move = function (dx, dy) {
this.attr({ x: this.ox + dx, y: this.oy + dy });
},
up = function () {
};
R.set(shape1, shape2, shape3, shape4).drag(move, start, up).dblclick(function(){
angle -= 90;
shape1.stop().animate({ transform: "r" + angle }, 1000, "<>");
});
}拖放正在工作,其中一个形状在双击时也会旋转。然而,有两个问题:
非常感谢你的指点!
发布于 2011-11-18 23:37:53
我试过好几次,想把我的头绕在新的转换引擎上,但没有用。所以,我回到了第一原则。
我终于设法正确地拖放了一个经过几次转换的对象,试图计算出不同转换的影响-- t、T、...t、...T、r、R等.
所以,这是解决方案的关键
var ox = 0;
var oy = 0;
function drag_start(e)
{
};
function drag_move(dx, dy, posx, posy)
{
r1.attr({fill: "#fa0"});
//
// Here's the interesting part, apply an absolute transform
// with the dx,dy coordinates minus the previous value for dx and dy
//
r1.attr({
transform: "...T" + (dx - ox) + "," + (dy - oy)
});
//
// store the previous versions of dx,dy for use in the next move call.
//
ox = dx;
oy = dy;
}
function drag_up(e)
{
// nothing here
}就这样。愚蠢的简单,我相信已经有很多人想到了,但也许有人会发现它是有用的。
这是给你玩的小提琴。
..。这是最初问题的有效解决方案。
发布于 2011-11-14 20:54:00
正如amadan建议的那样,当多个事物具有相同的(初始)属性/属性时,创建函数通常是个好主意。这确实是你第一个问题的答案。至于第二个问题,那就有点棘手了。
当拉皮尔物体被旋转时,坐标平面也是如此。出于某种原因,dmitry和网络上的一些其他来源似乎同意这是实现它的正确方法。我和你一样不同意。我没有找到一个全面的好的解决方案,但我确实创造了一个工作。我将简要解释,然后显示代码。
如果你只旋转90度的形状(如果不是,那就更困难了),你就可以确定坐标应该如何操作。
var R = Raphael("paper", "100%", "100%");
//create the custom attribute which will hold the current rotation of the object {0,1,2,3}
R.customAttributes.rotPos = function (num) {
this.node.rotPos = num;
};
var shape1 = insert_rect(R, 100, 100, 100, 50, { fill: "red", stroke: "none" });
var shape2 = insert_rect(R, 200, 200, 100, 50, { fill: "green", stroke: "none" });
var shape3 = insert_rect(R, 300, 300, 100, 50, { fill: "blue", stroke: "none" });
var shape4 = insert_rect(R, 400, 400, 100, 50, { fill: "black", stroke: "none" });
//Generic insert rectangle function
function insert_rect(paper,x,y, w, h, attr) {
var angle = 0;
var rect = paper.rect(x, y, w, h);
rect.attr(attr);
//on createion of the object set the rotation position to be 0
rect.attr({rotPos: 0});
rect.drag(drag_move(), drag_start, drag_up);
//Each time you dbl click the shape, it gets rotated. So increment its rotated state (looping round 4)
rect.dblclick(function(){
var pos = this.attr("rotPos");
(pos++)%4;
this.attr({rotPos: pos});
angle -= 90;
rect.stop().animate({transform: "r" + angle}, 1000, "<>");
});
return rect;
}
//ELEMENT/SET Dragger functions.
function drag_start(e) {
this.ox = this.attr("x");
this.oy = this.attr("y");
};
//Now here is the complicated bit
function drag_move() {
return function(dx, dy) {
//default position, treat drag and drop as normal
if (this.attr("rotPos") == 0) {
this.attr({x: this.ox + dx, y: this.oy + dy});
}
//The shape has now been rotated -90
else if (this.attr("rotPos") == 1) {
this.attr({x:this.ox-dy, y:this.oy + dx});
}
else if (this.attr("rotPos") == 2) {
this.attr({x: this.ox - dx, y: this.oy - dy});
}
else if (this.attr("rotPos") == 3) {
this.attr({x:this.ox+dy, y:this.oy - dx});
}
}
};
function drag_up(e) {
}我真的想不出清晰、简洁的方法来解释drag_move是如何工作的。我认为最好是看一下代码,看看它是如何工作的。基本上,您只需要计算出x和y变量现在是如何从这个新的旋转状态中处理的。没有我画了很多图形,我不确定我是否足够清楚。(我做了很多事情,想弄清楚它应该做什么)。
但是,这种方法有一些缺点:
我假设你使用变换的原因是你可以动画旋转。如果这不是必要的话,那么您可以使用.rotate()函数,它总是围绕元素的中心旋转,因此可以消除我提到的第二个缺点。
这不是一个完整的解决方案,但它肯定会让您走上正确的道路。我希望看到一个完整的工作版本。
我还在jsfiddle上创建了一个版本,您可以在这里查看:http://jsfiddle.net/QRZMS/3/
祝好运。
发布于 2011-11-14 12:47:00
我通常为我的形状创建一个对象,并将事件处理写入对象中。
function shape(x, y, width, height, a)
{
var that = this;
that.angle = 0;
that.rect = R.rect(x, y, width, height).attr(a);
that.rect.dblclick(function() {
that.angle -= 90;
that.rect.stop().animate({
transform: "r" + that.angle }, 1000, "<>");
});
return that;
}在上面的示例中,构造函数不仅创建矩形,而且设置双击事件。
需要注意的一点是,对对象的引用存储在“那个”中。这是因为“此”引用根据作用域的不同而变化。在dblClick函数中,我需要引用对象中的rect和角值,因此我使用存储的引用that.rect和that.angle
请参阅此示例 (从前一个稍有可疑的实例中更新)
也许有更好的方法来做你需要的事情,但这应该对你有用。
希望能帮上忙
尼克
增编:丹,如果你真的是,而且没有Raphael2给你的一些东西,我建议搬回Raphael1.5.x。转换刚刚添加到Raphael2中,在1.5.2中,旋转/平移/缩放代码完全不同(而且更容易)。
看着我,更新我的帖子,希望有因果报应.
https://stackoverflow.com/questions/8115713
复制相似问题