在 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 中使图像可选

有没有办法在 Angular 中使字段可拖动和可编辑?

raphael.js 如何将 id 添加到路径

使用 png 填充图像移动 Raphael 路径,而不破坏 IE 中的图像或相对于元素移动图像?

Raphael JS 的径向饼图菜单

在 Jquery 中使新的 div 可拖动