【问题标题】:Making paths and images draggable in Raphael js在 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>

【问题讨论】:

    标签: drag-and-drop javascript raphael


    【解决方案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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-08-29
              • 1970-01-01
              • 2014-06-24
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多