通过特定路径拖动对象并在兄弟路径中移动

时间:2016-02-24 20:07:04

标签: javascript html5 canvas raphael

我想知道如何通过画布拖动对象,我已经想出了这个:JsFiddle

现在的情况是:我有两条不同的路径,我需要在它们(球)上拖动两个物体,球应该在两条路径上独立移动。我正在移动它。

我正在尝试执行类似Google地图高程服务的操作,您可以沿着路径移动球,并在另一侧可视化与路径区域对应的高程。

(为了展望这一点,请转到谷歌地图并选择A到B点并选择自行车,然后将在屏幕左侧显示高程。)

Google Maps

我有一些使用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);

1 个答案:

答案 0 :(得分:2)

你可以创建第二条路径(假设它们是不同的,如果不是,你可以克隆()第一条路径并缩放它或者某种东西),找出行进的比率,然后调整第二条路径圆圈以沿着它移动比。所以它看起来像......

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(拖动无限循环)