d3.behavior.zoom鼠标滚轮变焦中心的动态偏移

时间:2014-09-24 19:58:31

标签: javascript d3.js zoom

有没有人知道如何动态修改d3.behavior.zoom的中心属性,以便通过指定的x和y值将鼠标滚轮缩放到偏离鼠标位置的点?

缩放仍应像往常一样跟踪鼠标位置,但会被动态生成的值偏移。

我使用名为webcola的库来处理节点树图中的多个坐标空间,该库扩展了d3。除了平移/缩放之外,为了实现平滑的节点拖动,我已经缓冲了平移坐标并在节点拖动后合并它们。 (而不是使用未在cola中实现的stopPropagation()方法。)

网络拖动+平移修复有效,但是会抵消d3.behavior.zoom中心。现在我想通过指定的x和y来偏移鼠标滚轮上的缩放目标,以便在鼠标滚轮缩放时恢复正确的光标跟踪。

例如,如果鼠标位于位置100,100但坐标空间移动了50,50,则鼠标滚轮应缩放至150,150,而不是实际鼠标位置100,100。

此偏移目标应在节点的平移/拖动时动态更新。

    function zoomCoords() {
        // generate the zoom coords based on the merged coordinate space - doesn't work
        console.log("d3.mouse");
            console.log(d3.mouse);
            return [0,0];
        }

    var zoom = d3.behavior.zoom()
        .scaleExtent([0.2, 3])
        // .center(zoomCoords()) // set dynamically ??? 
        .on("zoom", zoomed);

    svg.call(zoom);

...

    function zoomed() {
        if (enablePanning === true) {
            // we're dragging on the background, not a node.
            // zoom.center=newCoords; // doesn't work       
            // zoom.center(newCoords); // doesn't work              
            newCoords=[(d3.event.translate[0]-translateBuffer[0]),(d3.event.translate[1]-translateBuffer[1])];              
            container.attr("transform", "translate(" + newCoords + ")scale(" + d3.event.scale + ")");
        } else {
            // dragging on a node. save the translation to apply to the next container drag
            translateBuffer[0]=(d3.event.translate[0]-newCoords[0]);
            translateBuffer[1]=(d3.event.translate[1]-newCoords[1]);
        }
    }

由于

1 个答案:

答案 0 :(得分:2)

我能够在不修改d3源的情况下解决这个问题,方法是在mousemove上设置zoom.center,并使用每个节点拖动事件的缓冲转换偏移值。

    function mouseMove() {
        m = d3.mouse(this);
        // apply the translate buffer so mousewheel zooms on the correct point after dragging the graph
        pt=[ m[0]+translateBuffer[0], m[1]+translateBuffer[1] ];
        zoom.center(pt);
    }


    var zoom = d3.behavior.zoom()
        .scaleExtent([0.2, 3])
        .on("zoom", zoomed);

    svg.call(zoom)
        .on('mousemove', mouseMove);