Javascript SVG对象-如何正确缩放和拖动它?

Javascript SVG对象-如何正确缩放和拖动它?,javascript,css,svg,dom-events,Javascript,Css,Svg,Dom Events,我有一个SVG地图和简单的插件,添加了缩放和拖动功能 <svg> <g class="main-container draggable" transform="matrix(1 0 0 1 0 0)"> <path id="AT-1" title="Burgenland" class="land" d=".../> </g> </svg> 看起来我找到了解决方案,但我不太确定它到底是如何工作的 如果我从g元素

我有一个SVG地图和简单的插件,添加了缩放和拖动功能

<svg>
    <g class="main-container draggable" transform="matrix(1 0 0 1 0 0)">
      <path id="AT-1" title="Burgenland" class="land" d=".../>
  </g>
</svg>


看起来我找到了解决方案,但我不太确定它到底是如何工作的


如果我从g元素中删除.draggable类,它将按预期工作。似乎我找到了解决方案,但是,我不太确定它到底是如何工作的


如果我从g元素中删除.draggable

在此处发布可实现平移缩放功能的简易方法,它将正常工作

var svgCanvas=document.getElementById(“canvas”);
var viewPort=document.getElementById(“viewPort”);
var-drag=false;
变量偏移量={x:0,y:0};
var因子=.1;
var矩阵=新的DOMMatrix();
svgCanvas.addEventListener('pointerdown',函数(事件){
阻力=真;
偏移量={x:event.offsetX,y:event.offsetY};
});
svgCanvas.addEventListener('pointermove',函数(事件){
如果(拖动){
var tx=event.offsetX-offset.x;
var ty=event.offsetY-offset.y;
偏移量={
x:event.offsetX,
y:event.offsetY
};
matrix.preMultiplySelf(新的DOMMatrix()
.translateSelf(tx,ty));
viewPort.style.transform=matrix.toString();
}
});
svgCanvas.addEventListener('pointerup',函数(事件){
阻力=假;
});
svgCanvas.addEventListener(“控制盘”,函数(事件){
var zoom=event.deltaY>0?-1:1;
变量比例=1+因子*缩放;
偏移量={
x:event.offsetX,
y:event.offsetY
};
matrix.preMultiplySelf(新的DOMMatrix()
.translateSelf(偏移量x,偏移量y)
.scaleSelf(缩放,缩放)
.translateSelf(-offset.x,-offset.y));
viewPort.style.transform=matrix.toString();
});
html,
身体{
身高:100%;
保证金:0;
框大小:边框框;
字体大小:62.5%;
}
身体{
显示器:flex;
}
#周围{
显示器:flex;
宽度:100%;
边框:1px橙色虚线;
}
#帆布{
弹性:1;
高度:自动;
}

在此处发布可轻松实现平移缩放功能的方法

var svgCanvas=document.getElementById(“canvas”);
var viewPort=document.getElementById(“viewPort”);
var-drag=false;
变量偏移量={x:0,y:0};
var因子=.1;
var矩阵=新的DOMMatrix();
svgCanvas.addEventListener('pointerdown',函数(事件){
阻力=真;
偏移量={x:event.offsetX,y:event.offsetY};
});
svgCanvas.addEventListener('pointermove',函数(事件){
如果(拖动){
var tx=event.offsetX-offset.x;
var ty=event.offsetY-offset.y;
偏移量={
x:event.offsetX,
y:event.offsetY
};
matrix.preMultiplySelf(新的DOMMatrix()
.translateSelf(tx,ty));
viewPort.style.transform=matrix.toString();
}
});
svgCanvas.addEventListener('pointerup',函数(事件){
阻力=假;
});
svgCanvas.addEventListener(“控制盘”,函数(事件){
var zoom=event.deltaY>0?-1:1;
变量比例=1+因子*缩放;
偏移量={
x:event.offsetX,
y:event.offsetY
};
matrix.preMultiplySelf(新的DOMMatrix()
.translateSelf(偏移量x,偏移量y)
.scaleSelf(缩放,缩放)
.translateSelf(-offset.x,-offset.y));
viewPort.style.transform=matrix.toString();
});
html,
身体{
身高:100%;
保证金:0;
框大小:边框框;
字体大小:62.5%;
}
身体{
显示器:flex;
}
#周围{
显示器:flex;
宽度:100%;
边框:1px橙色虚线;
}
#帆布{
弹性:1;
高度:自动;
}

const maxScale = 5,
        minScale = 0.15;

    var selected,
        scale = 1,
        svg = document.querySelector('svg');

    function beginDrag(e) {
        e.stopPropagation();
        let target = e.target;

        if (target.classList.contains('draggable')) {
            selected = target;
        } else {
            selected = document.querySelector('.main-container');
        }

        selected.dataset.startMouseX = e.clientX;
        selected.dataset.startMouseY = e.clientY;
    }

    function drag(e) {
        if (!selected) return;
        e.stopPropagation();

        let startX = parseFloat(selected.dataset.startMouseX),
            startY = parseFloat(selected.dataset.startMouseY),
            dx = (e.clientX - startX),
            dy = (e.clientY - startY);

        if (selected.classList.contains('draggable')) {
            let selectedBox = selected.getBoundingClientRect(),
                boundaryBox = selected.parentElement.getBoundingClientRect();

            if (selectedBox.right + dx > boundaryBox.right) {
                dx = (boundaryBox.right - selectedBox.right);
            } else if (selectedBox.left + dx < boundaryBox.left) {
                dx = (boundaryBox.left - selectedBox.left);
            }

            if (selectedBox.bottom + dy > boundaryBox.bottom) {
                dy = (boundaryBox.bottom - selectedBox.bottom);
            }
            else if (selectedBox.top + dy < boundaryBox.top) {
                dy = (boundaryBox.top - selectedBox.top);
            }
        }

        let currentMatrix = selected.transform.baseVal.consolidate().matrix,
            newMatrix = currentMatrix.translate(dx / scale, dy / scale),
            transform = svg.createSVGTransformFromMatrix(newMatrix);

        selected.transform.baseVal.initialize(transform);
        selected.dataset.startMouseX = dx + startX;
        selected.dataset.startMouseY = dy + startY;
    }

    function endDrag(e) {
        e.stopPropagation();

        if (selected) {
            selected = undefined;
        }
    }


    function zoom(e) {
        e.stopPropagation();
        e.preventDefault();

        let delta = e.wheelDelta,
            container = document.querySelector('svg .main-container'),
            scaleStep = delta > 0 ? 1.25 : 0.8;

        if (scale * scaleStep > maxScale) {
            scaleStep = maxScale / scale;
        }

        if (scale * scaleStep < minScale) {
            scaleStep = minScale / scale;
        }

        scale *= scaleStep;

        let box = svg.getBoundingClientRect();
        let point = svg.createSVGPoint();
        point.x = e.clientX - box.left;
        point.y = e.clientY - box.top;

        let currentZoomMatrix = container.getCTM();

        point = point.matrixTransform(currentZoomMatrix.inverse());

        let matrix = svg.createSVGMatrix()
            .translate(point.x, point.y)
            .scale(scaleStep)
            .translate(-point.x, -point.y);


        let newZoomMatrix = currentZoomMatrix.multiply(matrix);
        container.transform.baseVal.initialize(svg.createSVGTransformFromMatrix(newZoomMatrix));

        console.log("scale", scale);
        let t = newZoomMatrix;
        console.log("zoomMatrix", t.a, t.b, t.c, t.d, t.e, t.f);
    }

    document.querySelector('svg').addEventListener('mousedown', beginDrag);
    document.querySelector('svg').addEventListener('mousewheel', zoom);
    svg.addEventListener('mousemove', drag);
    window.addEventListener('mouseup', endDrag);