D3.js 在d3中,是否有可能动态地改变路径位置的起始位置?

D3.js 在d3中,是否有可能动态地改变路径位置的起始位置?,d3.js,glyph,D3.js,Glyph,致:澄清。画一个圆圈。我们从一个特定的坐标开始画圆。现在,让我们从另一个坐标开始绘制圆 我正在使用从SVG图示符派生的路径数据,然后使用d3js tween来设置路径之间变化的动画 对于本例,从1->9,0开始计数,然后重复 正如您所看到的,一些转换不如其他转换好。他们画了一条线,封闭下一条路径的路径。(我猜)在计算新形状时,如果路径的起点和终点相距很远,就会发生这种情况。当它工作时,它非常好 有谁能提出一个可能的解决方案吗 没有路径数据的代码 svg.append("path") .

致:澄清。画一个圆圈。我们从一个特定的坐标开始画圆。现在,让我们从另一个坐标开始绘制圆

我正在使用从SVG图示符派生的路径数据,然后使用d3js tween来设置路径之间变化的动画

对于本例,从1->9,0开始计数,然后重复

正如您所看到的,一些转换不如其他转换好。他们画了一条线,封闭下一条路径的路径。(我猜)在计算新形状时,如果路径的起点和终点相距很远,就会发生这种情况。当它工作时,它非常好

有谁能提出一个可能的解决方案吗

没有路径数据的代码

svg.append("path")
    .attr("transform", "translate(150,300)scale(.2,-.2)")
  .style("stroke", "red")
  .style("fill", "gray")
  .style("stroke-width", "9")
    .attr("d", d0)
    .call(transition, digits[0], digits[position]);

function transition(path, d0, d1) {
  position++;
  if(position==10)
  {
    position=0;
  }
  path.transition()
      .duration(2000)
      .attrTween("d", pathTween(d1, 4))
      .each("end", function() { d3.select(this).call(transition, d1, digits[position]); });
}

function pathTween(d1, precision) {
  return function() {
    var path0 = this,
        path1 = path0.cloneNode(),
        n0 = path0.getTotalLength(),
        n1 = (path1.setAttribute("d", d1), path1).getTotalLength();

    // Uniform sampling of distance based on specified precision.
    var distances = [0], i = 0, dt = precision / Math.max(n0, n1);
    while ((i += dt) < 1) distances.push(i);
    distances.push(1);

    // Compute point-interpolators at each distance.
    var points = distances.map(function(t) {
      var p0 = path0.getPointAtLength(t * n0),
          p1 = path1.getPointAtLength(t * n1);
      return d3.interpolate([p0.x, p0.y], [p1.x, p1.y]);
    });

    return function(t) {
      return t < 1 ? "M" + points.map(function(p) { return p(t); }).join("L") : d1;
    };
  };
}
svg.append(“路径”)
.attr(“变换”,“平移(150300)比例(.2,-.2)”)
.style(“笔划”、“红色”)
.样式(“填充”、“灰色”)
.样式(“笔划宽度”、“9”)
.attr(“d”,d0)
.呼叫(转换,数字[0],数字[position]);
功能转换(路径,d0,d1){
位置++;
如果(位置==10)
{
位置=0;
}
path.transition()
.期限(2000年)
.attrTween(“d”,pathTween(d1,4))
.each(“end”,function(){d3.select(this).call(transition,d1,digits[position]);});
}
函数路径(d1,精度){
返回函数(){
var path0=这个,
path1=path0.cloneNode(),
n0=path0.getTotalLength(),
n1=(path1.setAttribute(“d”,d1),path1.getTotalLength();
//基于指定精度的距离均匀采样。
变量距离=[0],i=0,dt=precision/Math.max(n0,n1);
当((i+=dt)<1)距离时,推(i);
距离。推(1);
//计算每个距离处的点插值器。
var点=距离。映射(函数(t){
var p0=path0.getPointAtLength(t*n0),
p1=路径1.getPointAtLength(t*n1);
返回d3.插值([p0.x,p0.y],[p1.x,p1.y]);
});
返回函数(t){
返回t<1?“M”+点.map(函数(p){返回p(t);}).join(“L”):d1;
};
};
}
不幸的是,它在chrome手机上也失败了,因为as工作正常


下一步是将这种效果应用到句子中。

你的例子和博斯托克的例子之间的区别在于,在他的例子中,有一条连续的路径,他在另一条连续路径之间穿插

然而,在您的示例中,像1、2、3、5、6、7这样的数字可以使用单个连续路径绘制。但是,为了绘制像4、6、9和0这样的数字,您需要两条路径——一条在另一条之上。对于数字8,您需要在外部路径的顶部有两条路径

因此,我的建议是,在当前使用的外部路径上始终保留两条路径,并在显示任何特殊数字时为它们提供适当的尺寸

有关更多详细信息,请参阅图片:

嗯,这个问题很有趣。看起来需要更好的算法来匹配插值中的p0和p1点。您可能需要尝试Gale-Shapley根据欧几里德距离匹配点。我认为最好的算法应该是优先考虑两个点之间的插值,而不会导致任何交点。但我不知道怎么做。