提问者:小点点

d3.行为.鼠标滚轮缩放中心的动态偏移


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

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

我正在使用一个名为 webcola 的库在节点树图中处理多个坐标空间,该库扩展了 d3。为了在平移/缩放之外实现平滑的节点拖动,我缓冲了平移坐标并在节点拖动后合并它们。(而不是使用在可乐中未实现的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个答案

匿名用户

我能够在不修改 d3 源的情况下解决这个问题,方法是在鼠标移动时使用每个节点拖动事件的缓冲平移偏移值设置 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);