Javascript 如何使用d3.js沿GeoJSON路径设置对象动画?

Javascript 如何使用d3.js沿GeoJSON路径设置对象动画?,javascript,d3.js,Javascript,D3.js,我使用D3.js从GeoJSON文件生成并呈现路径。这很好,但现在我想沿该路径设置一个对象的动画。我知道如何使用D3和标准SVG实现这一点: 创建转换并设置其持续时间 对于变换的每一帧,使用%complete来查找沿路径的坐标 将对象移动到步骤2中找到的坐标 这很简单。但我遇到的问题是,d3.geo.path()似乎不像标准的d3 path对象那样返回任何长度或位置数据(例如有用的getPointAtLength()方法)。所以我找不到路径上25%的点的x,y坐标 有没有办法获得这些数据?(或者

我使用D3.js从GeoJSON文件生成并呈现路径。这很好,但现在我想沿该路径设置一个对象的动画。我知道如何使用D3和标准SVG实现这一点:

  • 创建转换并设置其持续时间
  • 对于变换的每一帧,使用%complete来查找沿路径的坐标
  • 将对象移动到步骤2中找到的坐标
  • 这很简单。但我遇到的问题是,d3.geo.path()似乎不像标准的d3 path对象那样返回任何长度或位置数据(例如有用的getPointAtLength()方法)。所以我找不到路径上25%的点的x,y坐标

    有没有办法获得这些数据?(或者有没有更好的方法,比如将d3.geo.path()转换为常规的d3路径?)

    下面是我的代码的截断版本;下面是一个活生生的例子:


    嗯,我想出来了,但我不完全确定我的解决方案是否是正确的。基本上,我使用D3选择由D3.geo.path()对象创建的原始SVG元素

    请注意对
    targetPath
    pathNode
    pathLength
    变量以及
    transform()
    attrTween()函数的更改:

    // Draw a red circle on the map:
    
    group = vis.append("svg:g");
    
    var targetPath = d3.selectAll('.route')[0][0],
        pathNode = d3.select(targetPath).selectAll('path').node(),
        pathLength = pathNode.getTotalLength();
    
    circle = group.append("circle")
        .attr({
        r: 10,
        fill: '#f33',
        transform: function () {
            var p = pathNode.getPointAtLength(0)
            return "translate(" + [p.x, p.y] + ")";
        }
    });
    
    // Animate the circle:
    
    duration = 10000;
    circle.transition()
        .duration(duration)
        .ease("linear")
        .attrTween("transform", function (d, i) {
        return function (t) {
            var p = pathNode.getPointAtLength(pathLength*t);
            return "translate(" + [p.x, p.y] + ")";
        }
    });
    
    现场示例如下:

    // Draw a red circle on the map:
    
    group = vis.append("svg:g");
    
    var targetPath = d3.selectAll('.route')[0][0],
        pathNode = d3.select(targetPath).selectAll('path').node(),
        pathLength = pathNode.getTotalLength();
    
    circle = group.append("circle")
        .attr({
        r: 10,
        fill: '#f33',
        transform: function () {
            var p = pathNode.getPointAtLength(0)
            return "translate(" + [p.x, p.y] + ")";
        }
    });
    
    // Animate the circle:
    
    duration = 10000;
    circle.transition()
        .duration(duration)
        .ease("linear")
        .attrTween("transform", function (d, i) {
        return function (t) {
            var p = pathNode.getPointAtLength(pathLength*t);
            return "translate(" + [p.x, p.y] + ")";
        }
    });