I’ve added code for two potential solutions below. One gives a more moving motion, the other looks more like the line is growing in place.
const width = 300,
height = 50;
const dashArray = [8, 5];
const dashArrayLength = d3.sum(dashArray);
let pathLength;
const svg = d3.select("svg")
.attr("viewBox", [0, 0, width, height]);
svg.append('path')
.attr('d', d3.line()([
[100, height / 4],
[200, height / 4]
]))
.attr('stroke', 'black')
.attr('fill', 'none')
.attr("stroke-dasharray", function() {
pathLength = this.getTotalLength();
// Find how often `dashArrayLength` fits within `pathLength`
const repeat = Math.ceil(pathLength / dashArrayLength);
const array = (dashArray.join(" ") + " ").repeat(repeat);
// Prepend pathLength to give it a complete empty space beforehand
return "0 " + pathLength + " " + array;
})
.attr("stroke-dashoffset", "0")
.transition()
.on("start", function repeat() {
d3.active(this)
.transition()
.duration(4000)
.attr("stroke-dashoffset", -pathLength)
.transition()
.duration(1000)
.attr("stroke-dashoffset", "0")
.on("start", repeat);
});
svg.append('path')
.attr('d', d3.line()([
[100, height / 2],
[200, height / 2]
]))
.attr('stroke', 'black')
.attr('fill', 'none')
.attr("stroke-dasharray", function() {
pathLength = this.getTotalLength();
// Prepend pathLength to give it a complete empty space beforehand
return "0 " + pathLength;
})
.transition()
.on("start", function repeat() {
d3.active(this)
.transition()
.duration(4000)
.attrTween("stroke-dasharray", function() {
return function(t) {
const tweenPathLength = pathLength * t;
// Find how often `dashArrayLength` fits within `tweenPathLength`,
// this time rounding down
const repeat = Math.floor(tweenPathLength / dashArrayLength);
const array = (dashArray.join(" ") + " ").repeat(repeat);
// See how much space there is still left over to draw a final,
// maybe partial, stripe
const finalStripe = Math.min(
tweenPathLength - repeat * dashArrayLength,
dashArray[0]
);
// Finally, append a large empty space at the end
return array + [finalStripe, pathLength];
}
})
.transition()
.duration(1000)
.attr("stroke-dasharray", "0 " + pathLength)
.on("start", repeat);
});
svg.append("text")
.attr("x", 30)
.attr("y", height / 4)
.attr("font-size", "0.4em")
.text("Moving effect")
svg.append("text")
.attr("x", 30)
.attr("y", height / 2)
.attr("font-size", "0.4em")
.text("Growing effect")
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>
CLICK HERE to find out more related problems solutions.