javascript 在 Raphael js 中使路径和图像可拖动
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4224359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Making paths and images draggable in Raphael js
提问by Decodal
Is it possible to be able to drag and drop objects other than just circles and rectangles around a page using Raphael js?
是否可以使用 Raphael js 在页面周围拖放除圆形和矩形以外的对象?
I want to add in paths and images which you can then move around but its proving tricky. I would like to work this out with Raphael because of its support with touch interfaces.
我想添加路径和图像,然后您可以四处移动,但事实证明这很棘手。我想和 Raphael 一起解决这个问题,因为它支持触摸界面。
Here is the code
这是代码
<script>
window.onload = function () {
var R = Raphael(0, 0, "100%", "100%"),
r = R.circle(100, 100, 50).attr({fill: "hsb(0, 1, 1)", stroke: "none", opacity: .5}),
g = R.circle(210, 100, 50).attr({fill: "hsb(.3, 1, 1)", stroke: "none", opacity: .5}),
b = R.circle(320, 100, 50).attr({fill: "hsb(.6, 1, 1)", stroke: "#fff", "fill-opacity": 0, "stroke-width": 0.8, opacity: .5}),
p = R.path("M 250 250 l 0 -50 l -50 0 l 0 -50 l -50 0 l 0 50 l -50 0 l 0 50 z") .attr({fill: "hsb(.8, 1, 1)", stroke: "none", opacity: .5});
var start = function () {
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.animate({r: 70, opacity: .25}, 500, ">");
},
move = function (dx, dy) {
this.attr({cx: this.ox + dx, cy: this.oy + dy});
},
up = function () {
this.animate({r: 50, opacity: .5}, 500, ">");
};
R.set(r, g, b, p).drag(move, start, up);
};
</script>
回答by Nathan Colgate
The key here (that I found) is to convert the x and y deltas into translate values, which the path object understands.
这里的关键(我发现)是将 x 和 y 增量转换为路径对象理解的转换值。
http://www.nathancolgate.com/post/2946823151/drag-and-drop-paths-in-raphael-js
http://www.nathancolgate.com/post/2946823151/drag-and-drop-paths-in-raphael-js
Effectively the same approach:
有效的相同方法:
var paper = Raphael(10, 50, 320, 200);
var tri = paper.path("M0 0L0 20L25 10L0 0Z").attr("fill", "#ff0");
var rex = paper.rect(10, 20, 50, 50).attr("fill", "#ff0");
var start = function () {
this.odx = 0;
this.ody = 0;
this.animate({"fill-opacity": 0.2}, 500);
},
move = function (dx, dy) {
this.translate(dx - this.odx, dy - this.ody);
this.odx = dx;
this.ody = dy;
},
up = function () {
this.animate({"fill-opacity": 1}, 500);
};
tri.drag(move, start, up);
rex.drag(move, start, up);
回答by Rick Westera
As translate is being deprecated in Raphael, I've modified Nathan's answer to work with transform:
由于翻译在 Raphael 中被弃用,我修改了 Nathan 的答案以使用转换:
var paper = Raphael(10, 50, 320, 200);
var tri = paper.path("M0 0L0 20L25 10L0 0Z").attr("fill", "#ff0");
var start = function () {
this.lastdx ? this.odx += this.lastdx : this.odx = 0;
this.lastdy ? this.ody += this.lastdy : this.ody = 0;
this.animate({"fill-opacity": 0.2}, 500);
},
move = function (dx, dy) {
this.transform("T"+(dx+this.odx)+","+(dy+this.ody));
this.lastdx = dx;
this.lastdy = dy;
},
up = function () {
this.animate({"fill-opacity": 1}, 500);
};
tri.drag(move, start, up);
I'm relatively new to Raphael and came up with this through trial and error, so someone out there might have an explanation of why it works or a cleaner way of doing it ;)
我对 Raphael 比较陌生,并通过反复试验提出了这一点,所以那里的人可能会解释它为什么有效或更简洁的方法;)
回答by cabreracanal
I would recommend you raphael.draggablelibrary, that makes the trick for you. I used it with a map application that allows the user to use zoom over the map and then drag it.
我会向你推荐raphael.draggable库,这对你来说是个窍门。我将它与地图应用程序一起使用,该应用程序允许用户在地图上缩放然后拖动它。
I had a problem with this library in IE8 because in the function events refering to mousedown, mousemove, etc. IE drops an exception, telling the user that eventis null. You can solve it by replacing the eventby eand adding e = e || eventin the raphael.draggable.js script. This fix doesn't affect other browsers.
我在 IE8 中遇到了这个库的问题,因为在引用 mousedown、mousemove 等的函数事件中。 IE 抛出一个异常,告诉用户这event是空的。您可以通过替换eventbye并e = e || event在 raphael.draggable.js 脚本中添加来解决它。此修复不会影响其他浏览器。
So, the method mousemove in the startDragger is:
所以,startDragger 中的 mousemove 方法是:
function startDragger() {
document.onmousemove = function(e) {
e = e || event
if (paper.draggable.current()) {
var transX = e.clientX - lastDragX;
var transY = e.clientY - lastDragY;
paper.draggable.current().translate(transX, transY);
lastDragX = e.clientX;
lastDragY = e.clientY;
}
};
}
And the link: https://github.com/mephraim/raphael.draggable
和链接:https: //github.com/mephraim/raphael.draggable
Hope this could help you.
希望这可以帮助你。
回答by ciw1973
I experimented with this a little while ago, and got it working using the following approach:
不久前我对此进行了试验,并使用以下方法使其工作:
- Add an initially hidden, styled, absolutely positioned div with a transparent background and suitable border styling to your page, and using jQuery/UI make it draggable.
- Add a click event to each of the Rapahel/SVG elements you wish to be draggable, and in this event add code to resize and reposition the div over the element which has just been clicked and then make it visible.
- Add code to the div which updates the position of the Raphael element when it is dragged.
- 向您的页面添加一个最初隐藏的、样式化的、绝对定位的具有透明背景和合适的边框样式的 div,并使用 jQuery/UI 使其可拖动。
- 向您希望可拖动的每个 Rapahel/SVG 元素添加一个 click 事件,并在此事件中添加代码以调整 div 的大小并将其重新定位在刚刚单击的元素上,然后使其可见。
- 向 div 添加代码,在拖动时更新 Raphael 元素的位置。
I extended this to add resizing capabilities, and this also worked well, but going forward it would be great to see drag, drop and resize capabilities (ideally properly integrated into the library rather than using jQuery) built into Raphael, as these features would open up a whole bunch of possibilities for in-browser designers using pure Raphael.
我扩展了它以添加调整大小的功能,这也很有效,但是在未来看到 Raphael 内置的拖放和调整大小功能(理想情况下正确集成到库中而不是使用 jQuery)会很棒,因为这些功能将打开为使用纯 Raphael 的浏览器设计师提供了一大堆可能性。
回答by Chris Butler
Try this for non-circles. Circles attributes are different than images, text, etc, I think.
对非圈子试试这个。我认为圆圈属性不同于图像、文本等。
var start = function () {
this.ox = this.attr("x");
this.oy = this.attr("y");
this.animate({r: 70, opacity: .25}, 500, ">");
},
move = function (dx, dy) {
this.attr({x: this.ox + dx, y: this.oy + dy});
},
up = function () {
this.animate({r: 50, opacity: .5}, 500, ">");
};
回答by Chielus
it's not that hard if you understand the usual dragging functions Chris Butler gave you. I use this:
如果您了解 Chris Butler 提供给您的常用拖动功能,这并不难。我用这个:
var start = function () {
//storing original coordinates
this.xSource = this.attrs.path[0][1];
this.ySource = this.attrs.path[0][2];
this.xDest = this.attrs.path[1][1];
this.yDest = this.attrs.path[1][2];
this.attr({opacity: 0.5});
},
move = function (dx, dy) {
//move will be called with dx and dy
var xS = this.xSource+dx;
var xD = this.xDest+dx;
var yS = this.ySource+dy;
var yD = this.yDest+dy;
this.attr({path: "M"+ xS +" "+ yS +"L"+ xD +" "+yD});
},
drag = function(){
this.node.drag(this.move,this.start,this.up);
};
You can also know which sort of figure you're dragging in the functions with this.type, so that you can make these functions work for all sort of figures.
您还可以通过 this.type 了解您在函数中拖动的是哪种图形,以便您可以使这些函数适用于所有类型的图形。
回答by Elbert Alias
In case anyone is still looking for a solution, here's a plugin that scales, rotates and drags all shapes including paths.
如果有人仍在寻找解决方案,这里有一个插件可以缩放、旋转和拖动包括路径在内的所有形状。

