通过特定路径拖动对象并在同级路径中移动
Drag object through specific path and move in a sibling path
我想知道如何通过 canvas 拖动对象,我想到了这个:JsFiddle
现在的问题是:我有两条不同的路径,我需要在它们(球)上拖动两个对象,球应该在两条路径上独立地移动,我正在移动哪一个。
我正在尝试做类似 Google 地图高程服务的事情,您可以沿着路径移动一个球,并在另一侧可视化对应于该路径区域的高程。
(要查看此内容,请转到 Google 地图和 select A 到 B 点和 select 自行车,然后海拔将显示在屏幕左侧。 )
我有一些使用 Raphael.js 的代码,但我找不到解决方法。
var searchDl = 1;
var l = 0;
// Creates canvas 320 × 200 at 10, 50
var r = Raphael(10, 50, 320, 200);
var p = r.path("M100,100c0,50 100-50 100,0c0,50 -100-50 -100,0z").attr({stroke: "#ddf"}),
pt = p.getPointAtLength(l);
e = r.ellipse(pt.x, pt.y, 4, 4).attr({stroke: "none", fill: "#f00"}),
totLen = p.getTotalLength(),
start = function () {
// storing original coordinates
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.attr({opacity: 1});
},
move = function (dx, dy) {
var tmpPt = {
x : this.ox + dx,
y : this.oy + dy
};
// move will be called with dx and dy
l = gradSearch(l, tmpPt);
pt = p.getPointAtLength(l);
this.attr({cx: pt.x, cy: pt.y});
},
up = function () {
// restoring state
this.attr({opacity: 1});
},
gradSearch = function (l0, pt) {
l0 = l0 + totLen;
var l1 = l0,
dist0 = dist(p.getPointAtLength(l0 % totLen), pt),
dist1,
searchDir;
if (dist(p.getPointAtLength((l0 - searchDl) % totLen), pt) >
dist(p.getPointAtLength((l0 + searchDl) % totLen), pt)) {
searchDir = searchDl;
} else {
searchDir = -searchDl;
}
l1 += searchDir;
dist1 = dist(p.getPointAtLength(l1 % totLen), pt);
while (dist1 < dist0) {
dist0 = dist1;
l1 += searchDir;
dist1 = dist(p.getPointAtLength(l1 % totLen), pt);
}
l1 -= searchDir;
return (l1 % totLen);
},
dist = function (pt1, pt2) {
var dx = pt1.x - pt2.x;
var dy = pt1.y - pt2.y;
return Math.sqrt(dx * dx + dy * dy);
};
e.drag(move, start, up);
你可以创建第二条路径(假设它们不同,如果不同,你可以克隆第一个并缩放它或其他东西),计算出行进的比率,然后调整第二条路径圆圈移动相同的比例。所以它可能看起来像...
var p2 = r.path("M150 0 L75 200 L225 200 Z").attr({ stroke: 'blue' }),
pt2 = p2.getPointAtLength(l),
e2 = r.ellipse(pt2.x, pt2.y, 4, 4).attr({stroke: "none", fill: "#f00"}),
p2totLen = p2.getTotalLength();
然后在你的 move() 函数中...
var ratioDone = l / totLen;
var p2Len = ratioDone * p2totLen
var p2Pt = p2.getPointAtLength( p2Len )
e2.attr({ cx: p2Pt.x, cy: p2Pt.y })
jsfiddle(拖动无限圆)
我想知道如何通过 canvas 拖动对象,我想到了这个:JsFiddle
现在的问题是:我有两条不同的路径,我需要在它们(球)上拖动两个对象,球应该在两条路径上独立地移动,我正在移动哪一个。
我正在尝试做类似 Google 地图高程服务的事情,您可以沿着路径移动一个球,并在另一侧可视化对应于该路径区域的高程。
(要查看此内容,请转到 Google 地图和 select A 到 B 点和 select 自行车,然后海拔将显示在屏幕左侧。 )
我有一些使用 Raphael.js 的代码,但我找不到解决方法。
var searchDl = 1;
var l = 0;
// Creates canvas 320 × 200 at 10, 50
var r = Raphael(10, 50, 320, 200);
var p = r.path("M100,100c0,50 100-50 100,0c0,50 -100-50 -100,0z").attr({stroke: "#ddf"}),
pt = p.getPointAtLength(l);
e = r.ellipse(pt.x, pt.y, 4, 4).attr({stroke: "none", fill: "#f00"}),
totLen = p.getTotalLength(),
start = function () {
// storing original coordinates
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.attr({opacity: 1});
},
move = function (dx, dy) {
var tmpPt = {
x : this.ox + dx,
y : this.oy + dy
};
// move will be called with dx and dy
l = gradSearch(l, tmpPt);
pt = p.getPointAtLength(l);
this.attr({cx: pt.x, cy: pt.y});
},
up = function () {
// restoring state
this.attr({opacity: 1});
},
gradSearch = function (l0, pt) {
l0 = l0 + totLen;
var l1 = l0,
dist0 = dist(p.getPointAtLength(l0 % totLen), pt),
dist1,
searchDir;
if (dist(p.getPointAtLength((l0 - searchDl) % totLen), pt) >
dist(p.getPointAtLength((l0 + searchDl) % totLen), pt)) {
searchDir = searchDl;
} else {
searchDir = -searchDl;
}
l1 += searchDir;
dist1 = dist(p.getPointAtLength(l1 % totLen), pt);
while (dist1 < dist0) {
dist0 = dist1;
l1 += searchDir;
dist1 = dist(p.getPointAtLength(l1 % totLen), pt);
}
l1 -= searchDir;
return (l1 % totLen);
},
dist = function (pt1, pt2) {
var dx = pt1.x - pt2.x;
var dy = pt1.y - pt2.y;
return Math.sqrt(dx * dx + dy * dy);
};
e.drag(move, start, up);
你可以创建第二条路径(假设它们不同,如果不同,你可以克隆第一个并缩放它或其他东西),计算出行进的比率,然后调整第二条路径圆圈移动相同的比例。所以它可能看起来像...
var p2 = r.path("M150 0 L75 200 L225 200 Z").attr({ stroke: 'blue' }),
pt2 = p2.getPointAtLength(l),
e2 = r.ellipse(pt2.x, pt2.y, 4, 4).attr({stroke: "none", fill: "#f00"}),
p2totLen = p2.getTotalLength();
然后在你的 move() 函数中...
var ratioDone = l / totLen;
var p2Len = ratioDone * p2totLen
var p2Pt = p2.getPointAtLength( p2Len )
e2.attr({ cx: p2Pt.x, cy: p2Pt.y })
jsfiddle(拖动无限圆)