d3 地理动画不会停止
Posted
技术标签:
【中文标题】d3 地理动画不会停止【英文标题】:d3 geo animation does not stop 【发布时间】: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找到以供参考。
【问题讨论】:
【参考方案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>
【讨论】:
以上是关于d3 地理动画不会停止的主要内容,如果未能解决你的问题,请参考以下文章