JSFiddle - React, Tailwind, and code Playground

by meetamit

CSS

circle {
  stroke: #fff;
  stroke-width: 3px;
}
path {
  fill: none;
  stroke: #000;
  stroke-width: 3px;
}

JavaScript

var pathdata = [
 [[240, 100],
  [290, 200],
  [340, 50]],
 [[340, 50],
  [90, 150],
  [140, 50],
  [190, 200]],
 [[190, 200],
  [70, 180],
  [30, 30],
  [350, 160]]
];

var svg = d3.select("body").append("svg")
    .attr("width", 960)
    .attr("height", 500);

var paths = svg.selectAll("path")
    .data(pathdata)
    .enter()
    .append("path")
    .attr("d", d3.svg.line())
    .attr("id",function(d, i) { return "path" + i });

// plot path vertices
svg.selectAll(".point")
    .data([].concat.apply([], pathdata))
    .enter().append("circle")
    .attr("r", 5)
    .attr("fill", "red")
    .attr("transform", function(d) { return "translate(" + d + ")"; });

// Start the first animation.
animateSinglePath(paths, 0);

function animateSinglePath(selection, indexOfAnimated) {
    indexOfAnimated = indexOfAnimated || 0;
    
    // Create circle if doesn't already exist
    // (achived by binding to single element array)
    circle = svg.selectAll('.animated-circle').data([null])
    circle.enter()
        .append("circle")
        .attr("class", "animated-circle")
        .attr("r", 10)
        .attr("fill", "steelblue")    
    
    selection.each(function(d, i) {
        if(i == indexOfAnimated) {
            // In this context, the "this" object is the DOM
            // element of the path whose index, i equals the
            // desired indexOfAnimated
            path = d3.select(this)
            // For style, make it dashed
            path.attr('stroke-dasharray', '5, 5')
            
            // Move circle to start pos and begin animation
            console.log('Start animation', i)
            circle
                .attr("transform", "translate(" + d[0] + ")")
                .transition()
                .duration(2000)
                .attrTween("transform", translateAlong(path.node()))
                .each('end', function() {
                    console.log('End animation', i);
                    
                    // For style, revert...