在 Raphael js 中使路径和图像可拖动
Posted
技术标签:
【中文标题】在 Raphael js 中使路径和图像可拖动【英文标题】:Making paths and images draggable in Raphael js 【发布时间】:2011-05-12 13:57:19 【问题描述】:是否可以使用 Raphael js 在页面周围拖放除圆形和矩形以外的对象?
我想添加路径和图像,然后您可以四处移动,但事实证明这很棘手。 我想和 Raphael 一起解决这个问题,因为它支持触摸界面。
这里是代码
<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>
【问题讨论】:
【参考方案1】:这里的关键(我发现)是将 x 和 y 增量转换为路径对象可以理解的平移值。
http://www.nathancolgate.com/post/2946823151/drag-and-drop-paths-in-raphael-js
实际上是相同的方法:
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);
【讨论】:
谢谢。但是有没有办法知道形状的最终(绝对)位置? Yako,你可以使用getBBox() translate 已被弃用,请参阅我对使用 transform 执行此操作的答案【参考方案2】:由于在 Raphael 中不推荐使用 translate,因此我修改了 Nathan 的答案以使用 transform:
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);
我对 Raphael 比较陌生,是通过反复试验得出这个结论的,所以有人可能会解释它的工作原理或更简洁的方法;)
【讨论】:
用这个路径字符串尝试了上面的答案:"M25 370 L10 370 L10 411 L25 411 L25 370 L61 370 L61 411 L25 411"
它不起作用。我想知道为什么?【参考方案3】:
我不久前对此进行了实验,并使用以下方法使其工作:
为您的页面添加一个初始隐藏、样式化、绝对定位的 div,该 div 具有透明背景和合适的边框样式,并使用 jQuery/UI 使其可拖动。 为您希望可拖动的每个 Rapahel/SVG 元素添加一个单击事件,并在此事件中添加代码以调整 div 的大小并将其重新定位到刚刚被单击的元素上,然后使其可见。 将代码添加到 div 中,以便在拖动 Raphael 元素时更新其位置。我对此进行了扩展以添加调整大小的功能,这也很有效,但未来很高兴看到 Raphael 内置的拖放和调整大小功能(理想情况下正确集成到库中而不是使用 jQuery),因为这些功能将为使用纯 Raphael 的浏览器内设计人员打开一大堆可能性。
【讨论】:
【参考方案4】:对非圈子试试这个。我认为 Circles 属性与图像、文本等不同。
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, ">");
;
【讨论】:
【参考方案5】:我会向你推荐 raphael.draggable 库,这对你来说是个窍门。我将它与一个地图应用程序一起使用,该应用程序允许用户使用缩放地图然后拖动它。
我在 IE8 中遇到了这个库的问题,因为在引用 mousedown、mousemove 等的函数事件中,IE 丢弃了一个异常,告诉用户 event
为空。您可以通过将event
替换为e
并在raphael.draggable.js 脚本中添加e = e || event
来解决它。此修复不会影响其他浏览器。
那么,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;
;
还有链接: https://github.com/mephraim/raphael.draggable
希望这对你有帮助。
【讨论】:
【参考方案6】:如果您了解 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);
;
您还可以通过 this.type 知道您在函数中拖动的是哪种图形,以便您可以使这些函数适用于所有类型的图形。
【讨论】:
【参考方案7】:如果有人仍在寻找解决方案,这里有一个插件,可以缩放、旋转和拖动包括路径在内的所有形状。
https://github.com/ElbertF/Raphael.FreeTransform
【讨论】:
以上是关于在 Raphael js 中使路径和图像可拖动的主要内容,如果未能解决你的问题,请参考以下文章
在 netlify cms 和 gatsby js 中使图像可选