Javascript SVG对象-如何正确缩放和拖动它?
我有一个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>
<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);