我正在探索d3js(版本4)库,并在玩弄缩放行为时遇到了以下问题。
当通过点击svg触发程序化缩放后使用鼠标滚轮进行缩放时,它会导致一个laagy / jumpy行为失去它的位置。
我找到了这个Stack Overflow资源:d3.js pan and zoom jumps when using mouse after programatic zoom并认为这可能对我有所帮助。但它没有。
我已经设置了一个简单的示例,以便您可以看到我的意思。 我在这里错过了什么?
boost

$(document).ready(function() {
var svg = d3.select('svg');
var group = d3.select('g#content');
svg.call(
d3.zoom().scaleExtent([1, 30]).on('zoom', function() {
group.attr('transform', d3.event.transform);
})
);
svg.on('click', function() {
group
.transition()
.duration(1000)
.attr("transform", "translate(100,100) scale(2)");
});
});

修改 通过在我的事件监听器中添加以下行,放大时行为会有所改善。在缩小时它仍会跳转;
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg width="1200" height="500" viewBox="0 0 1200 500">
<g id="content">
<path d="M10,10 l50,0 0,50 -50,0 0,-50 Z" />
<path d="M70,10 l50,0 0,50 -50,0 0,-50 Z" />
<path d="M130,10 l50,0 0,50 -50,0 0,-50 Z" />
<path d="M190,10 l50,0 0,50 -50,0 0,-50 Z" />
<path d="M250,10 l50,0 0,50 -50,0 0,-50 Z" />
<path d="M310,10 l50,0 0,50 -50,0 0,-50 Z" />
</g>
</svg>
完整更新的代码段:
var transform = d3.zoomTransform(group.node());
transform.x = m.x;
transform.y = m.y;
transform.k = scale;
&#13;
$(document).ready(function() {
var svg = d3.select('svg');
var group = d3.select('g#content');
svg.call(
d3.zoom().scaleExtent([1, 30]).on('zoom', function() {
group.attr('transform', d3.event.transform);
})
);
svg.on('click', function() {
group
.transition()
.duration(1000)
.attr("transform", "translate(100,100) scale(2)");
var transform = d3.zoomTransform(group.node());
transform.x = 100;
transform.y = 100;
transform.k = 2;
});
});
&#13;
提前致谢!
答案 0 :(得分:1)
这是因为您在初始化缩放时从event.transform(鼠标滚轮缩放事件)设置缩放值,而在您的点击事件处理程序中,您要为transform属性设置静态值。
所以下次发生缩放事件时,event.transform值和你的svg变换值会有所不同。所以它跳了起来。
例如:使用鼠标滚轮进行缩放。 event.transform将是(500x,500y,5k)。 您执行鼠标单击并将变换属性设置为(100x,100y,2k)。 下次执行鼠标滚轮事件时,event.transform将从(500x,500y,5k)改为(600x,600y,6k)。但是由于你的svg变换属性是(100x,100y,2k),它似乎会跳跃。
答案 1 :(得分:1)
以编程方式应用缩放时,您应该这样做:
svg.on('click', function() {
svg.transition()
.duration(750)
.call(zoom.transform, d3.zoomIdentity
.translate(100, 100) // set x and y transition
.scale(2) // set scale value
);
});
请注意,必须在比例尺之前应用翻译。
另外,请注意d3-zoom具有双击事件的默认行为(缩放)。如果您不想要它,可以使用以下代码禁用它:
svg.on("dblclick.zoom", null);
工作演示:
$(document).ready(function() {
var svg = d3.select('svg');
var group = d3.select('g#content');
var zoom = d3.zoom().scaleExtent([1, 30]).on('zoom', function() {
group.attr('transform', d3.event.transform);
});
svg.call(zoom);
svg.on("dblclick.zoom", null);
svg.on('click', function() {
svg.transition()
.duration(750)
.call(zoom.transform, d3.zoomIdentity
.translate(100, 100)
.scale(2)
);
});
});
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg width="1200" height="500" viewBox="0 0 1200 500">
<g id="content">
<path d="M10,10 l50,0 0,50 -50,0 0,-50 Z" />
<path d="M70,10 l50,0 0,50 -50,0 0,-50 Z" />
<path d="M130,10 l50,0 0,50 -50,0 0,-50 Z" />
<path d="M190,10 l50,0 0,50 -50,0 0,-50 Z" />
<path d="M250,10 l50,0 0,50 -50,0 0,-50 Z" />
<path d="M310,10 l50,0 0,50 -50,0 0,-50 Z" />
</g>
</svg>
&#13;