D3如何在启用平移/缩放的情况下居中元素

D3 how do you center an element with pan/zoom enabled?

本文关键字:缩放 情况下 元素 启用 D3      更新时间:2023-09-26

我当前更新的解决方案…

var myZoom = d3.behavior.zoom()
              .scaleExtent([.3, 10])
              .on("zoom", zoom);
var container = d3.select("body").append("svg")
    .attr("width", 500)
    .attr("height", 500)
    .style('border', '1px solid black') 
    .call(myZoom);
var trans1 = 250;
function sneakyTranslate1() {
    if(trans1 <= 0) return 0;
    trans1 = trans1 - .5;
    return trans1;
}
var trans2 = 250;
function sneakyTranslate2() {
    if(trans2 <= 0) return 0;
    trans2 = trans2 - .5;
    return trans2;
}
//I am centering my node here, but if I pan the node it jumps
var svg = container.append("g").attr("transform", "translate(250,250)"); 
 function zoom() { svg.attr("transform", "translate(" + 
    (d3.event.translate[0]+sneakyTranslate1()) + "," + 
    (d3.event.translate[1]+sneakyTranslate2()) + ")scale(" + d3.event.scale +
     ")"); }

为了澄清,我想首先将我的单个节点居中,然后允许平移和缩放作为默认值。当用户添加更多节点时,他们可能会担心居中和平移问题。

我当前的解决方案是将我的组转换到我的节点所在的位置。将平移后的偏移量添加到缩放函数中的缩放矢量中,并慢慢减小偏移量值,使其恢复为0。

如果有人知道一个更好的方法,或者在你开始绘制之前重置缩放和x,y你的节点,这将是有帮助的。

链接JsFiddle

我现在明白你的问题了。我在这里更新了你的jsFiddle。

问题是,即使你正在翻译SVG container,你没有翻译缩放(有点奇怪,我知道)。本质上,zoom函数认为您正在尝试放大SVG容器原来是(0,0)的地方,但是因为您将容器移动到其他地方(250,250),您必须移动myZoom对象,以便它知道从哪里缩放。

如果你看我加了这个

//I am centering my node here, but if I pan the node it jump 
var svg = container.append("g").attr("transform", "translate(250,250)");
// translate zoom function so it knows where to zoom from
myZoom.translate([250,250]);

这样它就知道将缩放对象转换到容器所在的位置。我还把这个还原了。

function zoom() {
  svg.attr("transform",
  "translate(" + d3.event.translate + ")"
  + " scale(" + d3.event.scale + ")");
}

希望这能解决你的问题