总体而言,这是一个相当棘手的问题。这是大多数解决方案,至少应该使您成为一种可能的方法。对于距离检查,我使用了原始小提琴中的代码,因此感谢编写该代码的人,因为它可能很棘手(也许值得提出自己的 SO 问题,但我认为它需要调整)。
fiddle here 编辑:您需要调整以允许更好的起始位置。
拖动圆圈开始它,因为我还没有设置开始位置。您将需要调整元素的起始位置,具体取决于您是否将它们零偏移或其他(否则您需要在移动/转换时允许这样做)。您可能还想检查第一个/最后一个元素是否到达末尾并将它们全部停止,因此如果一个元素到达路径末尾,它们都会停止。
它的工作原理是将所有对象放在一个集合中,并为每个对象附加一个处理程序(您可能在组中只有一个处理程序,更优雅但可能有点棘手)。
我们跟踪每个元素的索引
this.data('index')
因此,当涉及到沿线移动它们时,我们知道它在“链”中的位置,并且可以偏移以补偿,即以下线...
var whichDrag = this;
....
mySet.forEach( function( el, i ) {
var which = whichDrag.data("index") - i;
pt = path.getPointAtLength(l + (which * spacer ));
if( !isNaN(pt.x) && !isNaN(pt.x) ) { // check if over end
el.transform('t' + pt.x + ',' + pt.y );
};
} );
完整代码...
var paper = Snap('#panel');
var 间隔 = 70;
VAR =路径paper.path( 'M44.16,44.16 L44.16,44.16 L73.6,14.719999999999999 L132.48,73.6 L14.719999999999999,191.35999999999999 L132.48,309.12 L103.03999999999999,338.55999999999995 L44.16,279.67999999999995 L44.16,279.67999999999995')
.attr({
中风:'灰色',
行程宽度:3,
填充:'无'
});
var pt = path.getPointAtLength(l);
//e = r.ellipse(pt.x, pt.y, 4, 4).attr({stroke: "none", fill: "#f00"}),
var totLen = path.getTotalLength();
var r1 = paper.rect(0,0,10,10);
var c3 = paper.circle(0,0, 15);
var c2 = paper.circle(0,0, 15);
var c1 = paper.circle(0,0, 15);
变量 l = 0;
var searchDl = 1;
var cGroup = paper.g();
cGroup.add(c3,c2,c1,r1);
var mySet = cGroup.selectAll("*");
开始=函数(){
this.data("牛", +this.getBBox().cx );
this.data("oy", +this.getBBox().cy );
this.attr({不透明度: 1});
},
移动 = 函数 (dx, dy) {
var whichDrag = this;
var tmpPt = {
x : this.data("ox") + dx,
y : this.data("oy") + dy
};
// move 将使用 dx 和 dy 调用
l = gradSearch(l, tmpPt);
pt = path.getPointAtLength(l);
// this.attr({cx: pt.x, cy: pt.y});
mySet.forEach(函数(埃尔,我){
var which = whichDrag.data("index") - i;
pt = path.getPointAtLength(l + (which * spacer));
如果(!isNaN(pt.x)&&!isNaN(pt.x)){
//el.attr({cx: pt.x, cy: pt.y});
el.transform('t' + pt.x + ',' + pt.y );
};
});
},
向上 = 函数 () {
// 恢复状态
this.attr({不透明度: 1});
},
gradSearch = 函数 (l0, pt) {
l0 = l0 + totLen;
变量 l1 = l0,
dist0 = dist(path.getPointAtLength(l0 % totLen), pt),
区 1,
搜索目录;
if (dist(path.getPointAtLength((l0 - searchDl) % totLen), pt) >
dist(path.getPointAtLength((l0 + searchDl) % totLen), pt)) {
搜索目录 = 搜索 Dl;
} 别的 {
搜索目录 = -searchDl;
}
l1 += 搜索目录;
dist1 = dist(path.getPointAtLength(l1 % totLen), pt);
而 (dist1