我几乎是一个菜鸟,试图了解 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 找到供引用。
最佳答案
您链接的示例使用的是非常旧的 d3
版本(版本 2)。我相信动画在该版本中停止是因为您的 done
变量设置为 false,然后计时器函数返回 false 并且停止执行。但在版本 4 中,您需要显式调用 .stop() .
这是修补后的代码:
<!DOCTYPE html>
<html>
<head>
<script data-require="<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e682d5a6d2c8d6c8d6" rel="noreferrer noopener nofollow">[email protected]</a>" 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>
关于javascript - d3 地理动画不会停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47379998/