假设我有一个用d3绘制的任意路径
var points = [0, 4, 4, 4, 8, 8, 4, 4, 4, 8, 4, 4, 4, 4, 0];
var svg = d3.select('svg');
var line = d3.svg.line()
.y(function(d) { return 10*d})
.x(function(d, t) { return t*20 })
.interpolate('cubic');
svg.append('path')
.attr('d', line(points))
.attr('stroke', 'black')
.attr('stroke-width', 2)
.attr('fill', 'none')

<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.13/d3.min.js"></script>
<svg style="width: 100%; height: 100%; outline: 1px solid green;"></svg>
&#13;
我想要慢慢画出路径的动画。 I understand how to do it from beginning to end但在我的情况下,我想从线上的任意点开始,向两个方向以相同的速率向外绘制。 我无法弄清楚如何做到这一点。
我可以利用attrTween
并且随着时间的推移采取数组的切片,但是如果我这样做,则线移位,因为我不知道如何在每一步都正确设置水平偏移。 / p>
答案 0 :(得分:7)
希望您正在使用the page you linked to上的第二个答案(@duopixel的答案),因为这是一个更好的方法。如果是这样,那么如果稍微修改属性,则可以从中间开始绘制线:
var points = [0, 4, 4, 4, 8, 8, 4, 4, 4, 8, 4, 4, 4, 4, 0];
var svg = d3.select('svg');
var line = d3.svg.line()
.y(function(d) { return 10*d})
.x(function(d, t) { return t*20 })
.interpolate('cubic');
var path = svg.append('path')
.attr('d', line(points))
.attr('stroke', 'black')
.attr('stroke-width', 2)
.attr('fill', 'none');
totalLength = path.node().getTotalLength();
path
.attr("stroke-dasharray", '0 ' + totalLength)
.attr("stroke-dashoffset", totalLength/2)
.transition()
.duration(2000)
.attr("stroke-dasharray", totalLength + ' 0')
.attr("stroke-dashoffset", totalLength);
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.13/d3.min.js"></script>
<svg style="width: 100%; height: 100%; outline: 1px solid green;"></svg>
首先,考虑从开始到结束动画绘制路径的原始常见场景。如果l
是路径的长度(由path.node().getTotalLength()
获得),则将路径的stroke-dasharray
设置为l + ' ' + l
会使破折号与其与下一个破折号之间的差距相等到l
。在这些条件下,路径看起来是实心的,因为短划线长度为l
“推动”超过路径末端的间隙。通过将stroke-dashoffset
设置为l
,上述情况可以逆转 - 路径完全是间隙(因此不可见),并且破折号从路径上掉下来。通过在这两个状态之间转换(从一个偏移到一个没有偏移),我们逐渐绘制一条线。
现在,要从中间设置动画,短划线的长度为0
,间距的长度为l
。因此,由于0长短划线和l
长度间隙,现在该线也完全不可见。将stroke-dashoffset
设置为l/2
会将此0长度的短划线移动到路径的中间位置。这是动画的开始状态。结束状态是反向dasharray
,其中gap为0,dash-length为l
,这使得该行完全可靠。要在这些状态之间正确转换,我们还需要将结束状态的stroke-dashoffset
设置为l
。这是我通过实验得出的结果,我不确定如何用文字解释它。但它有效......