切换扫描标志时d3弧转换错误

时间:2018-01-17 21:14:12

标签: d3.js

我正在尝试使用以下代码实现弧的过渡以翻转其方向及其曲率:

<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("body").append("svg")
    .attr("width", 200)
    .attr("height", 200);
var sweepFlag0 = 0,
    sweepFlag1 = 1;
var curve1 = 'M30,30A10,10 0 0 ' + sweepFlag0 + ' 100,100';
var curve2 = 'M30,30A100,100 0 0 ' + sweepFlag0 + ' 100,100'; // error if use sweepFlag1

svg.append('path')
  .style('fill', 'none')
  .style('stroke', 'black')
  .attr('d', curve1)
  .transition().duration(1000)
  .attr('d', curve2);
</script>

当curve1和curve2共享相同的sweep-flag值(sweepFlag0或sweepFlag1)时,它可以工作。然而,为了翻转曲率方向,当两个扫描标志值不同时产生误差。任何帮助非常感谢!

1 个答案:

答案 0 :(得分:2)

您正试图在弧扫描值1 and 0 (clockwise or counter-clockwise)之间转换,但这是不可能的,因为该值是二进制的(即离散且不连续)。您应该尝试使用curveto代替arcto,因为curveto使用的Bezier curves比弧形中的椭圆曲线强大得多。

这样的事情:

var curve1 = 'M0,0 C100,0 100,0 100,100'
var curve2 = 'M0,0 C20,80 20,80 100,100'

svg.append('path')
  .style('fill', 'none')
  .style('stroke', 'black')
  .attr('d', curve1)
  .transition().duration(1000)
  .attr('d', curve2)

查看这些资源:

用于保持弧线的编辑:

var sweepFlag0 = 0,
    sweepFlag1 = 1;

var curve1 = 'M30,30A10,10 0 0 ' + sweepFlag0 + ' 100,100';
var curve2 = 'M30,30A8000,8000 0 0 ' + sweepFlag0 + ' 100,100';
var curve3 = 'M30,30A8000,8000 0 0 ' + sweepFlag1 + ' 100,100';
var curve4 = 'M30,30A100,100 0 0 ' + sweepFlag1 + ' 100,100';

svg.append('path')
  .style('fill', 'none')
  .style('stroke', 'black')
  .attr('d', curve1)
  .transition().duration(500)
  .attr('d', curve2)
  .transition().duration(0)
  .attr('d', curve3)
  .transition().duration(500)
  .attr('d', curve4)

这种方法有点hacky,但这是我能想到的最好的方法,因为在两个相反曲率的椭圆之间理论上没有实际的转换。这种方法正在做的是将半径增加到如此大的值,使得线直线。现在它看起来是直的,你可以在没有用户注意的情况下潜入曲率翻转,之后你将能够进一步转换曲率,无论你喜欢什么。尝试传递ease function以使过渡看起来更平滑