d3 on click on circle pause and resume transition of marker along line

前端 未结 1 1284
独厮守ぢ
独厮守ぢ 2021-01-23 05:59

I would like help to correct my code to click the marker circle element to pause or resume transition of this element along the line. My code moves marker along a line and I can

相关标签:
1条回答
  • 2021-01-23 06:36

    To check if the circle is moving in the click function use d3.active(), which...

    ... returns null if there is no such active transition on the specified node.

    Like this:

    .on('click', function(d, i) {
        if (d3.active(this)) {
            marker.transition();
            setTimeout(function() {
                pauseValues.lastTime = pauseValues.currentTime;
            }, 100);
        } else {
            transition();
        }
    });
    

    Here is your code with that change:

    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script src="https://d3js.org/d3-array.v1.min.js"></script>
    <script src="https://d3js.org/d3-geo.v1.min.js"></script>
    <script src="https://d3js.org/d3-queue.v3.min.js"></script>
    
    <style type="text/css">
      body {
        font-family: "Helvetica Neue", Helvetica, sans-serif;
        color: red;
      }
      
      button {
        position: absolute;
        top: 15px;
        left: 10px;
        background: #004276;
        padding-right: 26px;
        border-radius: 2px;
        cursor: pointer;
      }
      
      circle {
        fill: steelblue;
        stroke: pink;
        stroke-width: 3px;
      }
      
      .point {
        fill: green;
      }
      
      .line {
        fill: none;
        stroke: red;
        stroke-width: 4;
        stroke-dasharray: 4px, 8px;
      }
    
    </style>
    
    <body>
    
      <button>Start</button>
    
      <script>
        var w = 960,
          h = 500;
    
        var duration = 10000;
    
        var svg = d3.select("body").append("svg")
          .attr("width", w)
          .attr("height", h);
    
        var line = d3.line()
          .x(function(d) {
            return (d)[0];
          })
          .y(function(d) {
            return (d)[1];
          });
    
        var data = [
          [480, 200],
          [580, 400],
          [680, 100],
          [780, 300],
          [180, 300],
          [280, 100],
          [380, 400]
        ];
    
        //path to animate
        var linepath = svg.append("path")
          .data([data])
          .attr("d", line)
          .attr('class', 'line')
          .attr("d", function(d) {
            return line(d)
          });
    
        var points = svg.selectAll("circle")
          .data(data)
          .enter()
          .append("circle")
          .attr("r", 7)
          .attr("transform", function(d) {
            return "translate(" + (d) + ")";
          })
          .attr("class", "point");
    
        var pauseValues = {
          lastTime: 0,
          currentTime: 0
        };
        var marker = svg.append("circle")
          .attr("r", 19)
          .attr("transform", "translate(" + (data[0]) + ")")
          .on('click', function(d, i) {
            if (d3.active(this)) {
              marker.transition();
              setTimeout(function() {
                pauseValues.lastTime = pauseValues.currentTime;
              }, 100);
            } else {
              transition();
            }
          });
    
        function transition() {
          marker.transition()
            .duration(duration - (duration * pauseValues.lastTime))
            .attrTween("transform", translateAlong(linepath.node()))
            .on("end", function() {
              pauseValues = {
                lastT: 0,
                currentT: 0
              };
              transition()
            });
        }
    
        function translateAlong(path) {
          var l = path.getTotalLength();
          return function(d, i, a) {
            return function(t) {
              t += pauseValues.lastTime;
              var p = path.getPointAtLength(t * l);
              pauseValues.currentTime = t;
              return "translate(" + p.x + "," + p.y + ")";
            };
          };
        }
    
        d3.select('button').on('click', function(d, i) {
          var self = d3.select(this);
          if (self.text() == "Pause") {
            self.text('Start');
            marker.transition()
              .duration(0);
            setTimeout(function() {
              pauseValues.lastTime = pauseValues.currentTime;
            }, 100);
          } else {
            self.text('Pause');
            transition();
          }
        });
    
      </script>
    </body>

    0 讨论(0)
提交回复
热议问题