svg.js svg.draggable.js和外观操纵

时间:2017-05-16 17:56:10

标签: javascript svg svg.js

我想使用svg.js来实现拖放,并操纵图形元素的外观。它主要起作用,但我不完全理解为什么。

我从我的应用程序中提取了必要部分来说明我的应用程序的情况。可以在那里玩,看看效果。

https://jsfiddle.net/bwl21/ex8dcxtm/12/

SVG由我的应用程序生成为字符串。我通过在jsfiddle中将HTML添加到HTML窗格来模拟这个。

我有一个函数" set_draggable(id),它获取svg元素的id并附加一个拖动处理程序。

function set_draggable(svg_element) {

  var xx = SVG.get(svg_element);
  xx.addClass("zn_draggable");

  xx.draggable(function(x, y) {
    return {
      x:  Math.floor(x),
      y:  Math.floor(y)
    }
  });

  var sx = 0,
    sy = 0;
  xx.on('dragstart', function(e) {
    sx = e.detail.p.x;
    sy = e.detail.p.y;
    this.fill("red");
  });

  // todo: don't know why 'this' is the only way to change the filling ...
  xx.on('dragend', function(e) {
    this.fill("green");
    var result = {
      delta: [ e.detail.p.x - sx, e.detail.p.y - sy],
      element: svg_element
    };
    alert(JSON.stringify(result));
  })
}


set_draggable("ZN_18");
set_draggable("ZN_19");
set_draggable("ZN_20");
set_draggable("ZN_21");

我的问题:

  1. 在可拖动事件处理程序中,我想更改对象的颜色。 为什么'这个'引用拖动的对象?这是我发现应用fill()的唯一方法。我尝试使用xx这是我附加可拖动的dom节点。还尝试了e.target.fill("red")

  2. 拖动Fermata - Character(这是一条路径)时,颜色不会改变。它在拖动文本时有效。 可能是什么原因?

    通过bwl21回答:同时我发现该组的属性不会覆盖子项的属性。所以我不得不从路径中移除笔划和填充。

    尽管如此,我还是没有设法导航到孩子们并改变那里的属性。

  3. 当我拖动ZN_19时,它可以仅垂直移动,因为我可以拖动它。如果我将它包装在一个组(如ZN_20)中并在其上调用draggable(),我可以按照自己的意愿移动它。

  4. 有没有更好的方法来获取拖拽后的差异?我将x和y存储在' dragstart'处理程序,并计算' dragend'中的delta。处理程序。我希望delta是整数,因为我将它传递给draggable()函数。

  5. 如果我有很多对象(我的应用程序大约有300个),我是否会遇到性能问题,因为我创建了许多处理程序?有更好的方法吗?

  6. 欢迎任何帮助。

1 个答案:

答案 0 :(得分:1)

哇,这是一堆问题。我会尝试完成它们。

1。为什么'this'指的是被拖动的对象?

这是svg.js的一般做法。所有事件处理程序都在元素的上下文中执行。 因此,单击元素时会打印true

el.on('click', function() { console.log(this == el) })

所以是的,你可以使用xx代替它,它在你的例子中工作得很好。只需将this替换为xx

但是,this是保存方式,因为在使用可能在其他地方重新清除的外部变量时,您可能会遇到变量作用域的问题(典型示例:在循环中附加事件处理程序)

2。为什么fermata的填充不会改变

这已经得到了正确回答。作为一般性提示,我可以说:如果他们只持有一个形状,就不要使用组。没有必要这样做。

关于浏览dom的后续问题:svg.js有一个很棒的文档。只需在http://svgjs.com/的搜索中输入children

您有多种可能性:

el.children() // array
el.get(index) // element at index
el.first() // first element
el.last() // last element

3。为什么拖动文本只能垂直工作

您的svg不是使用svg.js生成的。 Svg.js将每个第一级tspan视为使用svg.js创建的新行 IF 。如果没有,它没有什么特别之处。在你的情况下,这意味着:文本 IS 被移动(查看dom - 你可以看到它)。但是,在您的svg代码中,您将x坐标重置为tspan中的80,以便它永远保留在那里。如果您不想这样做,请不要使用x,而是使用dx或在tspan上调用newLine(),这将启用对行的特殊处理,其中还包括对文本的x坐标的更改x坐标已更改。

关于这一点的说明:我在你的例子小提琴中做了这个,这使得文本消失了。多数民众赞成,因为文本本身的x为189,不在屏幕之外,因此您需要将其调整为80首

4。有没有更好的方法来获得拖累的结果?

没有。

在将元素设置到元素之前,将舍入应用于坐标。但是:在事件对象中给出了原始点,因为它是真实的来源

5。使用多个元素

时是否存在性能问题

许多元素减慢了dom操作。所以不要将数百个元素组合在一起。只是将处理程序应用于它们应该不是问题。

但是,性能还取决于浏览器。尝试编写高性能代码。通过定义它们(el.draggable(nameOfFunc))重用draggable-constraint函数,尽量避免在处理程序中访问外部变量(如xx),因此不需要生成闭包,不要拖拽繁重,使用相反,他要做重担。

希望我能帮忙