如何沿路径移动但仅在两个指定路径点之间移动

How to move along a path but only between two specified path points

这个问题是关于 d3 版本 3.x 和路径移动的。

假设有一条路径和一个圆元素,我希望圆在过渡中遵循该路径,但最多只能达到一定百分比。 我之前问过这个问题,并从 Gerardo Furtado 那里得到了很好的回答:

我仍然有一个关于这方面的问题,由于我是初学者,到目前为止我找不到任何可行的解决方案:

我如何追踪这条路径,比方说,从 25% 的点到 50% 的点,然后再从 50% 的点到 60% 的点?

这些数字只是示例,任何百分比值都应该是可能的。

我需要避免路径移动总是从位置 0 开始,而是我想从圆已经到达的当前位置开始路径移动。

希望我能把我的问题表达清楚。

非常感谢您的任何见解和帮助。

嗯,我不得不同意, and I see that you also do. Since I answered your ,我只是需要在功能上做一些小的改动。但是,下次请记住他的建议:在提问时,向我们展示一些您尝试过的代码,即使它 工作,因为它显示了努力。

回到问题。

对于此解决方案,我将所有内容包装在一个名为 move 的函数中,该函数接受两个参数,即初始位置和最终位置(均以百分比表示):

function move(initialPosition, finalPosition) {

初始位置,顾名思义,设置圆沿路径的初始位置。数学是这样的:

var start = path.node()
    .getPointAtLength(path.node().getTotalLength() * initialPosition);

然后,我稍微改变了我上一个答案的函数来接受初始和最终位置:

function translateAlong(path) {
    var l = path.getTotalLength() * (finalPosition - initialPosition);
    return function() {
        return function(t) {
            var p = path.getPointAtLength(t * l + 
                (path.getTotalLength() * initialPosition));
            return "translate(" + p.x + "," + p.y + ")";
        };
    };
}

这是演示。单击按钮调用 move,参数为 0.25(初始位置)和 0.5(最终位置):

var points = [
  [240, 100],
  [290, 200],
  [340, 50],
  [390, 150],
  [90, 150],
  [140, 50],
  [190, 200]
];

var svg = d3.select("body").append("svg")
  .attr("width", 500)
  .attr("height", 300);

var path = svg.append("path")
  .data([points])
  .attr("d", d3.svg.line()
    .tension(0) // Catmull–Rom
    .interpolate("cardinal-closed"));

var color = d3.scale.category10();

var dataPositions = [{
  initial: 0.25,
  final: 0.5
}, {
  initial: 0.5,
  final: 0.6
}];


svg.selectAll(".point")
  .data(points)
  .enter().append("circle")
  .attr("r", 4)
  .attr("transform", function(d) {
    return "translate(" + d + ")";
  });

d3.select("button").on("click", function() {
  move(0.25, 0.5);
});

function move(initialPosition, finalPosition) {

  var start = path.node().getPointAtLength(path.node().getTotalLength() * initialPosition);

  var circle = svg.append("circle")
    .attr("r", 13)
    .attr("fill", function(d, i) {
      return color(i)
    })
    .attr("transform", "translate(" + start.x + "," + start.y + ")");

  circle.transition()
    .duration(1000)
    .attrTween("transform", function() {
      return translateAlong(path.node())()
    });

  function translateAlong(path) {
    var l = path.getTotalLength() * (finalPosition - initialPosition);
    return function() {
      return function(t) {
        var p = path.getPointAtLength(t * l + 
            (path.getTotalLength() * initialPosition));
        return "translate(" + p.x + "," + p.y + ")";
      };
    };
  }

}
path {
  fill: none;
  stroke: #000;
  stroke-width: 3px;
}

circle {
  stroke: #fff;
  stroke-width: 3px;
}
<script src="//d3js.org/d3.v3.min.js"></script>
<button>Move</button>
<br>

PS:这个答案中的函数 接受大于 1 的值。但是如果你需要做的比 "one lap" 在路径中。