d3单击圆圈暂停并恢复沿线的标记过渡 [英] d3 on click on circle pause and resume transition of marker along line

查看:116
本文介绍了d3单击圆圈暂停并恢复沿线的标记过渡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望帮助纠正我的代码,以单击标记圆圈元素来暂停或恢复该元素沿直线的过渡.我的代码沿着一行移动标记,我可以使用单击按钮元素来暂停和恢复此过渡,但是我希望能够单击标记圈本身而不是按钮.我使用了各种参考资料,包括: http://www.nytimes.com/互动式/2013/09/25/sports/americas-cup-course.html http://jsfiddle.net/meetamit/UJuWX/3/ http://jsfiddle.net/Y62Hq/2/ D3补间-暂停和恢复控件

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 pause and resume this transition using on click on button element but I would like to be able to click on the marker circle itself, not the button. I have used various references including : http://www.nytimes.com/interactive/2013/09/25/sports/americas-cup-course.html http://jsfiddle.net/meetamit/UJuWX/3/ http://jsfiddle.net/Y62Hq/2/ D3 tween - pause and resume controls

我最终希望能够沿着地理路径为标记设置动画,在路径上的各个点处暂停并恢复该标记,然后单击这些点.

I would ultimately like to be able animate a marker along a geo path, pause and resume this at points along the path and click through on these points.

到目前为止,这是我的代码:

this is my code so far:

<!DOCTYPE html>
<html lang="en">
    <head>
<meta charset="utf-8">
<title>Need help</title>

<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>
</head>
<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){
        console.log(this);
        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){
                d3.select(this)
                .style("fill", "orange")
                .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>
</html>

推荐答案

要检查圆是否在click函数中移动,请使用d3.active(),该按钮...

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

...如果在指定的节点上没有这样的活动过渡,则返回null.

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

赞:

.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>

这篇关于d3单击圆圈暂停并恢复沿线的标记过渡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆