我想使用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");
我的问题:
在可拖动事件处理程序中,我想更改对象的颜色。
为什么'这个'引用拖动的对象?这是我发现应用fill()的唯一方法。我尝试使用xx
这是我附加可拖动的dom节点。还尝试了e.target.fill("red")
。
拖动Fermata - Character(这是一条路径)时,颜色不会改变。它在拖动文本时有效。 可能是什么原因?
通过bwl21回答:同时我发现该组的属性不会覆盖子项的属性。所以我不得不从路径中移除笔划和填充。
尽管如此,我还是没有设法导航到孩子们并改变那里的属性。
当我拖动ZN_19时,它可以仅垂直移动,因为我可以拖动它。如果我将它包装在一个组(如ZN_20)中并在其上调用draggable(),我可以按照自己的意愿移动它。
有没有更好的方法来获取拖拽后的差异?我将x和y存储在' dragstart'处理程序,并计算' dragend'中的delta。处理程序。我希望delta是整数,因为我将它传递给draggable()函数。
如果我有很多对象(我的应用程序大约有300个),我是否会遇到性能问题,因为我创建了许多处理程序?有更好的方法吗?
欢迎任何帮助。
答案 0 :(得分:1)
这是svg.js的一般做法。所有事件处理程序都在元素的上下文中执行。
因此,单击元素时会打印true
:
el.on('click', function() { console.log(this == el) })
所以是的,你可以使用xx
代替它,它在你的例子中工作得很好。只需将this
替换为xx
。
但是,this
是保存方式,因为在使用可能在其他地方重新清除的外部变量时,您可能会遇到变量作用域的问题(典型示例:在循环中附加事件处理程序)
这已经得到了正确回答。作为一般性提示,我可以说:如果他们只持有一个形状,就不要使用组。没有必要这样做。
关于浏览dom的后续问题:svg.js有一个很棒的文档。只需在http://svgjs.com/的搜索中输入children
。
您有多种可能性:
el.children() // array
el.get(index) // element at index
el.first() // first element
el.last() // last element
您的svg不是使用svg.js生成的。 Svg.js将每个第一级tspan视为使用svg.js创建的新行 IF 。如果没有,它没有什么特别之处。在你的情况下,这意味着:文本 IS 被移动(查看dom - 你可以看到它)。但是,在您的svg代码中,您将x坐标重置为tspan中的80
,以便它永远保留在那里。如果您不想这样做,请不要使用x
,而是使用dx
或在tspan上调用newLine()
,这将启用对行的特殊处理,其中还包括对文本的x坐标的更改x坐标已更改。
关于这一点的说明:我在你的例子小提琴中做了这个,这使得文本消失了。多数民众赞成,因为文本本身的x为189,不在屏幕之外,因此您需要将其调整为80首
没有。
在将元素设置到元素之前,将舍入应用于坐标。但是:在事件对象中给出了原始点,因为它是真实的来源
许多元素减慢了dom操作。所以不要将数百个元素组合在一起。只是将处理程序应用于它们应该不是问题。
但是,性能还取决于浏览器。尝试编写高性能代码。通过定义它们(el.draggable(nameOfFunc)
)重用draggable-constraint函数,尽量避免在处理程序中访问外部变量(如xx
),因此不需要生成闭包,不要拖拽繁重,使用相反,他要做重担。
希望我能帮忙