放大和缩小,但保持 svg 居中

Zoom in and out, but keep svg centered

我有一张 svg 格式的世界地图,我正在使用视图框来关注非洲。我有两个用于放大和缩小的按钮:

<rect class="button" x="75" y="170" onclick="zoom(0.8)" style="width:25px; height:20px; fill:khaki"/>
<rect class="button" x="100" y="170" onclick="zoom(1.25)" style="width:25px; height:20px; fill:khaki"/>

在外部 .js 文件中,我有平移和缩放的代码,这是我在 Peter Collingridge 的在线教程中找到的:

var transformMatrix = [1, 0, 0, 1, 0, 0];
var svg = document.getElementById('map-svg');
var viewbox = svg.getAttributeNS(null, "viewBox").split(" ");
var centerX = parseFloat(viewbox[2]) / 2;
var centerY = parseFloat(viewbox[3]) / 2;
var matrixGroup = svg.getElementById("matrix-group");

function pan(dx, dy) {
    transformMatrix[4] += dx;
    transformMatrix[5] += dy;
    var newMatrix = "matrix(" +  transformMatrix.join(' ') + ")";
    matrixGroup.setAttributeNS(null, "transform", newMatrix);
}

function zoom(scale) {
    for (var i = 0; i < transformMatrix.length; i++) {
transformMatrix[i] *= scale;
}

    transformMatrix[4] += (1 - scale) * centerX;
    transformMatrix[5] += (1 - scale) * centerY;

    var newMatrix = "matrix(" +  transformMatrix.join(' ') + ")";
    matrixGroup.setAttributeNS(null, "transform", newMatrix);
}

除一件事外,一切都如我所愿。当我放大时,非洲 "jumps" 在右边,当我缩小时,它在左边 "jumps"。我怎样才能放大和缩小非洲留在视框的中心?

我想我回答了我自己的问题。第4行和第5行定义了centerX和centerY:

var centerX = parseFloat(viewbox[2]) / 2;
var centerY = parseFloat(viewbox[3]) / 2;

然后在第20行和第21行,使用了centerX和centerY:

transformMatrix[4] += (1 - scale) * centerX;
transformMatrix[5] += (1 - scale) * centerY;

我想,"What if I multiply centerX and centerY by 2, to offset the division by 2 in lines 4 and 5?" 它以 Y 轴为中心,而不是 X 轴。所以,我一直在更改数字,直到我得到:

transformMatrix[4] += (1 - scale) * (centerX * 4);
transformMatrix[5] += (1 - scale) * (centerY * 2);

现在它像我希望的那样缩放,使非洲大陆保持在视图框的中心。