如何沿着路径移动,但仅在两个指定的路径点之间移动 [英] How to move along a path but only between two specified path points

查看:99
本文介绍了如何沿着路径移动,但仅在两个指定的路径点之间移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题与d3版本3.x和路径移动有关.

This question is about d3 version 3.x and path movements.

想象一下,有一条路径和一个圆元素,我希望圆在过渡过程中遵循该路径,但只能达到某个百分比. 我之前曾问过这个问题,并在这里从Gerardo Furtado获得了一个很好的答案:

Imagine there is a path and a circle element, and I want the circle to follow that path in a transition, but only up to some percentage. I was asking this before and got a great answer from Gerardo Furtado here: My former question

不过,这方面的问题仍然存在,对于我来说,作为一个初学者,到目前为止我找不到任何可行的解决方案:

Still, one question in this regards remains for me, and as I am a beginner, I couldn't find any working solution so far:

我如何跟踪从25%的点到50%的点,然后再从50%的点到60%的点?

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

These numbers are just examples, any percentage value should be possible.

我需要避免路径移动总是从位置0开始,但是我想从当前位置开始,圆圈已经到达了路径.

I need to avoid that the path movement always starts from position 0, but instead i want to start path movement from the current position the circle has reached already.

希望我能很清楚地表达我的问题.

Hopefully I could express my question clear enough.

非常感谢您的见解和帮助.

Thank you very much for any insight and help.

推荐答案

嗯,我必须同意最后一个问题,因此我只需要对该函数进行一些小的更改.但是,下次请记住他的建议:问问题时,请向我们展示您尝试过的一些代码,即使它行得通,因为它显示了努力.

Well, I have to agree with LeBeau, and I see that you also do. Since I answered your last question, I just needed to do some minor changes in the function. However, keep his advise in mind for the next times: when asking a question, show us some code you've tried, even if it doesn't work, because it shows effort.

回到问题.

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

For this solution, I'll wrap everything inside a function named move, which accepts two arguments, the initial position and the final position (both in percentages):

function move(initialPosition, finalPosition) {

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

The initial position, as the name implies, set the initial position of the circle along the path. The math is this:

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

然后,我从上一个答案中略微更改了该功能,以接受初始位置和最终位置:

Then, I slightly changed the function from my last answer to accept the initial and final positions:

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 + ")";
        };
    };
}

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

Here is the demo. Clicking on the button calls move with 0.25 (initial position) and 0.5 (final position) as arguments:

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的值.但是,如果您需要在路径中执行一圈以上"操作,则可以尝试更改它.

PS: The function in this answer does not accept values bigger than 1. But you can try to change it if you need to do more than "one lap" in the path.

这篇关于如何沿着路径移动,但仅在两个指定的路径点之间移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆