首页 > 解决方案 > d3.js v4 svg 语义缩放和平移(沿 x 轴和 y 轴平移,仅沿 x 轴缩放)

问题描述

我想实现沿 x 和 y 轴平移 svg 对象并仅沿 x 轴进行语义缩放。

只要 d3.event.transform 对象保存缩放和平移的计算值,每当我一个接一个地调用平移和缩放时,新转换的 y 值是错误的,因为它们忽略\不忽略以前的相反动作。(缩放忽略平移动作的 d3.event.transform.y,平移不忽略缩放动作的 d3.event.transform.y)

如果您在 svg 区域中的任意位置缩放,则圆圈应仅平移 x 坐标,而 y 坐标应与以前保持一致(考虑到以前的平移)

现在,由于 y 值错误,圆圈正在“跳跃”。

if (isZoom)
{//zoom     
    return "translate(" + t.apply(d)[0] + "," + (d[1]) +")"; //ignores previous panning-only values and positions to static initial value
}   

//panning
return "translate(" + t.apply(d)[0] + "," + (t.y + d[1]) +")"; //how to ignore portion of t.y belonging to previous zooming?

您可以取消注释这行代码以防止圆圈跳跃但 y 在缩放时会发生变化(不应该)

//ignore isZoom and apply both for panning and zooming
return "translate(" + t.apply(d)[0] + "," + (t.y + d[1]) +")";  

https://jsfiddle.net/197cz2vj/

谢谢!

更新

最后我想出了一个类似黑客的解决方案。我不喜欢它,我仍在寻找合适的解决方案(我不喜欢决定 isZoom 操作和 deltaPanY 解决方案。这对于 d3 libray 的未来更改都是可行的)。这里是:

每次转换发生更改并且更改由 mousemove(panning) 触发时,更新 deltaPanY 变量,将新值与转换的旧记忆值进行比较。(我还制作了 tx 和 tk 的副本,但出于我的目的,只有 ty 和 deltaPanY 是必需的)。

function copyLastTransform(t)
{
    lastTransform = 
    {
        x: t.x,
        y: t.y,
        k: t.k
    };
};

每次转换发生时,设置增量变量并存储最后一次转换:

if (isZoom)
{
   deltaZoomY += t.y - lastTransform.y;
}
else
{
   deltaPanY += t.y - lastTransform.y;
}

copyLastTransform(t);

翻译函数现在看起来像这样:

return "translate(" + t.apply(d)[0] + "," + (deltaPanY + d[1]) +")";

分叉小提琴: https ://jsfiddle.net/xpr364uo/

标签: d3.jsaxiszoomingpanning

解决方案


推荐阅读