【问题标题】:d3 geo animation does not stopd3 地理动画不会停止
【发布时间】:2018-05-02 23:06:38
【问题描述】:

我几乎是个菜鸟,试图了解一些在 d3.js 中看起来很有趣但又有点超出我掌握的东西。当然,我在 bl.ocks.org 上弄乱了一些代码,结果在我不明白为什么的情况下就中断了。

这可能是一个更大的问题,而不是出现或缺少一些显而易见的东西,但我无法让旋转动画停止,因为当未选中全球或动画框时,可以停止。其他一切似乎都按预期工作。

这是我对 d3.v4 所做的:

var feature;

var projection = d3.geoOrthographic()
    .scale(380)
    .rotate([71.03,-42.37])
    .clipAngle(90)
    .translate([400, 400]);

var path = d3.geoPath()
    .projection(projection);

var svg = d3.select("#body").append("svg:svg")
    .attr("width",  "100%")
    .attr("height", "100%")
    .on("mousedown", mousedown);

if (frameElement) frameElement.style.height = '800px';

d3.json("https://gist.githubusercontent.com/phil-pedruco/10447085/raw/426fb47f0a6793776a044f17e66d17cbbf8061ad/countries.geo.json", function(collection) {
  feature = svg.selectAll("path")
      .data(collection.features)
    .enter().append("svg:path")
      .attr("d",clip);

  feature.append("svg:title")
      .text(function(d) { return d.properties.name; });

  startAnimation();

  d3.select('#animate').on('click', function () {
    if (done) startAnimation(); else stopAnimation();
  });
});

function stopAnimation() {
  done = true;
  d3.select('#animate').node().checked = false;
}

function startAnimation() {
  done = false;
  d3.timer(function() {
    var rotate = projection.rotate();
    rotate = [rotate[0] + 0.1, rotate[1]];
    projection.rotate(rotate);
    refresh();
    return done;
  });
}

function animationState() {
  return 'animation: '+ (done ? 'off' : 'on');
}

d3.select(window)
    .on("mousemove", mousemove)
    .on("mouseup", mouseup);


var m0
  , o0
  , done
  ;

function mousedown() {
  stopAnimation();
  m0 = [d3.event.pageX, d3.event.pageY];
  o0 = projection.rotate();
  d3.event.preventDefault();
}

function mousemove() {
  if (m0) {
    var m1 = [d3.event.pageX, d3.event.pageY]
      , o1 = [o0[0] - (m0[0] - m1[0]) / 8, o0[1] - (m1[1] - m0[1]) / 8];
    projection.rotate(o1);
    refresh();
  }
}

function mouseup() {
  if (m0) {
    mousemove();
    m0 = null;
  }
}

function refresh(duration) {
  (duration ? feature.transition().duration(duration) : feature).attr("d",clip);
}

function clip(d) {
  return path(d);
}

function reframe(css) {
  for (var name in css)
    frameElement.style[name] = css[name] + 'px';
}

原始代码可以在http://bl.ocks.org/johan/1392488找到以供参考。

【问题讨论】:

    标签: javascript d3.js geo


    【解决方案1】:

    您的链接示例使用的是真正旧版本的 d3(版本 2)。我相信动画在那个版本中停止了,因为您的 done 变量设置为 false,然后计时器函数返回 false 并停止执行。但是,在版本 4 中,您需要显式调用 .stop()

    这是修补的代码:

    <!DOCTYPE html>
    <html>
    
      <head>
        <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
      </head>
    
      <body>
        <div class="tip">drag to rotate the origin</div>
            <div><label for="animate">animate:</label>
              <input id="animate" type="checkbox" checked>
            </div>
        <div id="body" style="width:800px;height:800px"></div>
        <script>
          var feature;
    
    var projection = d3.geoOrthographic()
        .scale(380)
        .rotate([71.03,-42.37])
        .clipAngle(90)
        .translate([400, 400]);
    
    var path = d3.geoPath()
        .projection(projection);
    
    var svg = d3.select("#body").append("svg:svg")
        .attr("width",  "100%")
        .attr("height", "100%")
        .on("mousedown", mousedown);
        
    if (frameElement) frameElement.style.height = '800px';
    
    d3.json("https://gist.githubusercontent.com/phil-pedruco/10447085/raw/426fb47f0a6793776a044f17e66d17cbbf8061ad/countries.geo.json", function(collection) {
      feature = svg.selectAll("path")
          .data(collection.features)
        .enter().append("svg:path")
          .attr("d",clip);
    
      feature.append("svg:title")
          .text(function(d) { return d.properties.name; });
    
      startAnimation();
    
      d3.select('#animate').on('click', function () {
        if (done) startAnimation(); else stopAnimation();
      });
    });
    
    function stopAnimation() {
      done = true;
      d3.select('#animate').node().checked = false;
      timer.stop();
    }
    
    function startAnimation() {
      done = false;
      timer = d3.timer(function() {
        var rotate = projection.rotate();
        rotate = [rotate[0] + 0.1, rotate[1]];
        projection.rotate(rotate);
        refresh();
      });
    }
    
    d3.select(window)
        .on("mousemove", mousemove)
        .on("mouseup", mouseup);
    
    
    var m0
      , o0
      , done
      , timer
      ;
    
    function mousedown() {
      stopAnimation();
      m0 = [d3.event.pageX, d3.event.pageY];
      o0 = projection.rotate();
      d3.event.preventDefault();
    }
    
    function mousemove() {
      if (m0) {
        var m1 = [d3.event.pageX, d3.event.pageY]
          , o1 = [o0[0] - (m0[0] - m1[0]) / 8, o0[1] - (m1[1] - m0[1]) / 8];
        projection.rotate(o1);
        refresh();
      }
    }
    
    function mouseup() {
      if (m0) {
        mousemove();
        m0 = null;
      }
    }
    
    function refresh(duration) {
      (duration ? feature.transition().duration(duration) : feature).attr("d",clip);
    }
    
    function clip(d) {
      return path(d);
    }
    
    function reframe(css) {
      for (var name in css)
        frameElement.style[name] = css[name] + 'px';
    }
        </script>
      </body>
    
    </html>

    【讨论】:

      猜你喜欢
      • 2011-11-15
      • 2019-05-03
      • 2015-08-10
      • 1970-01-01
      • 2011-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-03
      相关资源
      最近更新 更多