谢谢阅读 .
The Goal
我想比较从Mike Bostock的块到基于画布的系统的工作SVG点击缩放 . 我把工作的SVG放在顶部,底部放了一个画布 . 当用户点击上部SVG中的状态时,我希望下部画布元素“跟随”或模仿缩放和平移 . 例如,单击上部SVG中的明尼苏达州也会导致下部画布缩放并平移到明尼苏达州 .
The Problem
我的canvas元素在加载topojson后绘制得很好,但它没有动画效果 . 我想要它的动画 . 我相信这是因为我不完全理解缩放行为和基于路径的投影 .
http://jsfiddle.net/30w8nv4t/2/
function zoomed(d) {
g.style("stroke-width", 1.5 / d3.event.scale + "px");
g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
// the zTranslate and zScale variables appear to be ok,
// but `d` is null. I'm not sure how to redraw.
var zTranslate = zoom.translate();
var zScale = zoom.scale();
console.log(zTranslate, zScale, d);
context.clearRect(0, 0, width, height);
context.beginPath();
canvasPath(d);
context.stroke();
}
在这种情况下, d
显然为null,我无法重绘任何内容 . 我假设我的问题可能在 zoomed
方法或 clicked
函数中 .
The Reason
我正在使用这种并排的方法,因为我想了解路径,投影和缩放行为如何协同工作 . 我很欣赏canvas对SVG的表现如何,但缺乏交互性是令人生畏的 . 幸运的是,能够缩放和平移到任意几何体可以将我的问题减少一半 .
谢谢你的阅读 . 链接到JSFiddle是这篇文章的顶部 .
1 回答
canvas
绘图函数使用纬度/经度坐标的投影值,但您没有在zoom
处理程序中更新scale
的scale
和translate
.获得您所追求的行为的一种方法是从
zoom
处理程序中的svg
上的transform
切换到projection
上的transform
.我已经在这个更新的小提琴中做到了这一点:http://jsfiddle.net/30w8nv4t/7/
不同之处是:
zoom
行为以使用projection
translate
和scale
作为默认值,并将scaleExtent
值设置为基于projection
.zoomed
函数更新为translate
和scale
projection
,然后重绘基于svg
的路径 .clicked
函数 .这可能是更改的主要组件之一,因为
scale
和translate
应用于zoom
行为,当它们出现时,它们必须由当前zoom
scale
缩放 . 然后clicked
函数触发zoomed
函数以重绘svg
和canvas
元素 .如您所见,您的
canvas
绘图代码是正确的 . 只是绘图代码使用projection
来确定要根据zoom
处理程序未更新的projection
绘制的点的x
和y
位置 .也可以为
canvas
单独设置projection
,并在调用canvas
重绘函数之前在zoom
处理程序中更新它 . 我会把它留给读者练习!