沿路径捕捉.svg拖动
Drag along path snap.svg
你好,这个小提琴的答案非常适合我需要做的事情 - 沿着路径拖动一些东西。但是他们使用了 Rapael - 我想更新内容并使用 snap.svg 代替。
在这个答案中替换从拉斐尔到 Snap 的引用是行不通的——有人知道为什么吗?
这是我在这个代码笔中得到的 - 我想要一个 10 点的形状 - 其外部点可以向中心移动很长的路径。
var s = Snap("#svg");
var paths = [], points = [], circles = [], lines = [], l = 0, searchDl = 1;
var dist = function (pt1, pt2) {
var dx = pt1.x - pt2.x;
var dy = pt1.y - pt2.y;
return Math.sqrt(dx * dx + dy * dy);
};
var gradSearch = function (l0, pt, path) {
var totLen = path.getTotalLength();
l0 = l0 + totLen;
var l1 = l0,
dist0 = dist(path.getPointAtLength(l0 % totLen), pt),
dist1,
searchDir;
console.log(dist0);
if (dist(path.getPointAtLength((l0 - searchDl) % totLen), pt) >
dist(path.getPointAtLength((l0 + searchDl) % totLen), pt)) {
searchDir = searchDl;
} else {
searchDir = -searchDl;
}
l1 += searchDir;
dist1 = dist(path.getPointAtLength(l1 % totLen), pt);
console.log(dist1);
while (dist1 < dist0) {
dist0 = dist1;
l1 += searchDir;
dist1 = dist(path.getPointAtLength(l1 % totLen), pt);
}
l1 -= searchDir;
console.log(l1 % totLen);
return (l1 % totLen);
};
var startCircleToPoly = function () {
// storing original coordinates
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.attr({opacity: 1});
};
var moveCircleToPoly = function (dx, dy) {
var tmpPt = {
x : this.ox + dx,
y : this.oy + dy
};
var path = paths[this.data('int')];
// move will be called with dx and dy
l = gradSearch(l, tmpPt, path);
//console.log(l);
pt = path.getPointAtLength(l);
this.attr({cx: pt.x, cy: pt.y});
};
var endCircleToPoly = function () {
// restoring state
this.attr({opacity: 1});
};
for(var i = 1; i <= 10; i++){
//polygon points
points.push( s.select('#line' + i).attr('x2') + ' ' + s.select('#line' + i).attr('y2') );
paths.push( s.path('M' + s.select('#line' + i).attr('x2') + ' ' + s.select('#line' + i).attr('y2') + ' L' + s.select('#line' + i).attr('x1') + ' ' + s.select('#line' + i).attr('y1')).attr({stroke: "blue"}) );
lines.push(s.select('#line' + i).attr({'stroke' : ''}));
//circles
circles.push( s.circle(
s.select('#line'+i).attr('x2'),
s.select('#line'+i).attr('y2'),5).attr({
fill: "red",
id: "circle"+i,
style: {"cursor" : "pointer"}
}).data({int: i-1}).drag( moveCircleToPoly, startCircleToPoly, endCircleToPoly )
);
}
//add poly
/*var poly = s.polygon(points);
poly.attr({
id:"poly",
fill:"#555555"
});
*/
<svg id="svg" version="1.1" preserveAspectRatio="xMinYMin meet" class="svg-content" viewBox="-10.109 -107.67 400 400">
<line id="line1" fill="none" x1="82.196" y1="-17.513" x2="107.595" y2="-95.686"/>
<line id="line2" fill="none" x1="82.196" y1="-17.513" x2="148.689" y2="-65.827"/>
<line id="line3" fill="none" x1="82.196" y1="-17.513" x2="164.391" y2="-17.513"/>
<line id="line4" fill="none" x1="82.196" y1="-17.513" x2="148.689" y2="30.801"/>
<line id="line5" fill="none" x1="82.196" y1="-17.513" x2="107.595" y2="60.66"/>
<line id="line6" fill="none" x1="82.196" y1="-17.513" x2="56.796" y2="60.66"/>
<line id="line7" fill="none" x1="82.196" y1="-17.513" x2="15.699" y2="30.801"/>
<line id="line8" fill="none" x1="82.196" y1="-17.513" x2="0" y2="-17.513"/>
<line id="line9" fill="none" x1="82.196" y1="-17.513" x2="15.699" y2="-65.827"/>
<line id="line10" fill="none" x1="82.196" y1="-17.513" x2="56.796" y2="-95.686"/>
</svg>
谢谢!
我认为
您的主要问题是某些浮点数被视为字符串而不是数字 ID。我也会在你以前没有的奇怪地方使用 data() 方法。
所以我会做下面这样的事情来强制计算,或者你可以使用 parseInt 等
var tmpPt = {
x : +this.data("ox") + +dx,
y : +this.data("oy") + +dy
};
代码笔
补充说明:你可能想考虑一下矩阵和变换,以及你的拖动发生在具有不同屏幕变换的元素上,所以当你拖动它们时,它们的移动速度会稍微快一些,所以你可能想要补偿这一点。
相关文章:
- 禁用SVG拖动
- 将SVG元素拖动到另一个SVG元素上
- 只能使用snap.svg在svg中拖动圆圈
- 微调可拖动 SVG 形状的位置,而无需更改 X
- 如何限制可拖动 SVG 形状的范围
- 通过可拖动的 SVG 形状设置 HTML 输入值 ?(或画布)
- 捕捉.svg拖动路径元素
- 避免在拖动时跳转带有文本锚点的 SVG 文本
- 使用 JqueryUI 拖动内联 SVG
- 沿路径捕捉.svg拖动
- 捕捉.svg拖动“真实”位置
- D3.js SVG 图像拖动有效,但引发许多类型错误
- 捕捉svg拖动一组集合
- Snap.svg沿着一条路径拖动一个组并保存位置
- 产卵,拖动SVG元素-方法
- 截取SVG拖动和缩放:我的矩形不会停止缩放
- 如何在svg.js中自定义拖动事件
- 使用Jquery-svg拖动SVG的初始位置
- RaphaelJS/Snap.SVG拖动事件
- AngularJS-SVG拖动旋转的元素