功能介绍 :
使用vue,实现SVG的拖拽缩放,
1.缩放的同时保持屏幕的中心点不会变,
2.同时增加某坐标点的聚焦。
使用的库
svg-pan-zoom + hammerjs
实现的代码片段
你的svg
<svg ref="svg" class="svg-content" width="380" height="840" id="svggroup" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 13270 7475"
style="enable-background:new 0 0 13270.2 7475.1;" xml:space="preserve">
svg内部元素
</svg>
引入
import svgPanZoom from 'svg-pan-zoom';
import Hammer from 'hammerjs';
data() {
return {
svgGroups: null,
viewBox: "0 0 13270 7475",
centerCoord: {x: 10104, y: 5008},
//测试的坐标系数 viewbox是我svg的系数
// centerCoord: {x: 4301, y: 2004},
// centerCoord: {x: 4180, y: 4329},
// centerCoord: {x: 3760, y: 2054},
};
},
主要的代码片段
initZoomPan() {
const eventsHandler = {
haltEventListeners: ['touchstart', 'touchend', 'touchmove', 'touchleave', 'touchcancel']
, init: function (options) {
var instance = options.instance
, initialScale = 1
, pannedX = 0
, pannedY = 0
this.hammer = Hammer(options.svgElement, {
inputClass: Hammer.SUPPORT_POINTER_EVENTS ? Hammer.PointerEventInput : Hammer.TouchInput
})
this.hammer.get('pinch').set({ enable: true })
this.hammer.on('doubletap', function (ev) {
instance.zoomIn()
})
this.hammer.on('panstart panmove', function (ev) {
if (ev.type === 'panstart') {
pannedX = 0
pannedY = 0
}
instance.panBy({ x: ev.deltaX - pannedX, y: ev.deltaY - pannedY })
pannedX = ev.deltaX
pannedY = ev.deltaY
})
this.hammer.on('pinchstart pinchmove', function (ev) {
if (ev.type === 'pinchstart') {
initialScale = instance.getZoom()
instance.zoom(initialScale * ev.scale)
}
instance.zoom(initialScale * ev.scale)
})
options.svgElement.addEventListener('touchmove', function (e) { e.preventDefault(); });
}
, destroy: function () {
this.hammer.destroy()
}
}
const element = document.querySelector('#svggroup');
this.svgGroups = svgPanZoom(element, {
zoomEnabled: true,
controlIconsEnabled: false,
dblClickZoomEnabled: false,
fit: 1,
center: 1,
minZoom: 1,
maxZoom: 20,
customEventsHandler: eventsHandler
});
}
如果想要某种情况的时候 svg某个坐标去聚焦
svg-pan-zoom_viewport是使用svg-pan-zoom的时候会在svg下创建一个子级g标签,你svg自带的内部元素
都在g下、
bbox 才是最后的容器,根据他的大小,结合svg的viewbox大小,去计算,1倍的的时候要到达的坐标中心,然后在去放大 多少倍
let bbox = document.querySelector('.svg-pan-zoom_viewport').getBoundingClientRect();
let clientWidth = this.svgGroups.getSizes().width;
let clientHeight = this.svgGroups.getSizes().height;
let centerX = bbox.left + (this.centerCoord.x - this.viewBox.split(" ")[0]) * bbox.width / parseInt(this.viewBox.split(" ")[2]);
let centerY = bbox.top + (this.centerCoord.y - this.viewBox.split(" ")[1]) * bbox.height / parseInt(this.viewBox.split(" ")[3]);
let x = clientWidth / 2 - centerX
let y = clientHeight / 2 - centerY
this.svgGroups.panBy({x, y});
this.svgGroups.zoom(5);
实现的效果
此功能一次一次的优化,这是最终版了就
svg-pan-zoom