js操作svg原点缩放和平移

模仿地图的缩放和平移,鼠标在哪就以哪为原点缩放,平移不跳点,“diagramSvg”为svg dom的id

/svg操作通用js/
export default {
data() {
return {
svgDom: null,
scale: 1,//当前缩放倍数
scaleStep: 1.5,//每次缩放的倍数
vbCX: 0,
vbCY: 0,
vbCW: 0,
vbCH: 0,
startX: 0,
startY: 0,
startVbCX: 0,
startVbCY: 0,
removeFlag: false
}
},
mounted() {
this.svgDom = document.getElementById(“diagramSvg”);
this.svgDom.addEventListener(“mousedown”, this.moveDownMouse);//监听svgDom鼠标按下事件
this.svgDom.addEventListener(“mouseup”, this.moveUpMouse);//监听svgDom鼠标松开事件
this.svgDom.addEventListener(“mousemove”, this.moveMouse);//监听svgDom鼠标移动事件
this.svgDom.addEventListener(“mousewheel”, this.MouseWheel);//监听svgDom鼠标滚轮滚动事件
},
methods: {
// 获取当前视图VB的位置信息
getCurrentVB() {
this.vbCX = parseFloat(this.svgDom.viewBox.animVal.x);
this.vbCY = parseFloat(this.svgDom.viewBox.animVal.y);
this.vbCW = parseFloat(this.svgDom.viewBox.animVal.width);
this.vbCH = parseFloat(this.svgDom.viewBox.animVal.height);
},
// 鼠标按下事件
moveDownMouse(evt) {
this.svgDom.setAttributeNS(null, “style”, “cursor: move”);
this.removeFlag = true;
this.startX = parseInt(evt.clientX); // 当前点击的点的横坐标
this.startY = parseInt(evt.clientY); // 当前点击的点的纵坐标
/记录开始移动时的vb坐标/
this.getCurrentVB();
this.startVbCX = this.vbCX;
this.startVbCY = this.vbCY;
},
// 鼠标点击后松开事件
moveUpMouse(evt) {
this.svgDom.setAttributeNS(null, “style”, “cursor: default”);
this.removeFlag = false;
},
// 鼠标移动事件
moveMouse(evt) {
if (this.removeFlag) {
let moveX = (parseInt(evt.clientX) - this.startX) / this.scale; // 当前点-原始点=移动量
let moveY = (parseInt(evt.clientY) - this.startY) / this.scale; // 当前点-原始点=移动量
this.vbCX = this.startVbCX - moveX;
this.vbCY = this.startVbCY - moveY;
this.vbCW = parseFloat(this.svgDom.viewBox.animVal.width); //刷新获取viewBox的高和宽
this.vbCH = parseFloat(this.svgDom.viewBox.animVal.height); //刷新获取viewBox的高和宽
// 刷新当前viewBox展示的视图位置
this.svgDom.setAttributeNS(
null,
“viewBox”,
this.vbCX + " " + this.vbCY + " " + this.vbCW + " " + this.vbCH
);
}
},
//鼠标滚轮事件
MouseWheel(e) {
let svgDiv = document.getElementById(“svgDiv”)
console.log(svgDiv.getBoundingClientRect().left)
console.log(this.svgDom.getBoundingClientRect().left)
let evt = e || window.event;
let down = true;
// ev.wheelDelta未定义,ev.detail > 0为true表示往下滚动,为false表示往上滚动
// wheelDelta和detail正好相反,火狐中wheelDelta未定义只能使用detail
down = evt.wheelDelta ? evt.wheelDelta < 0 : evt.detail > 0;
if (down) {
this.zoomOut(); // 缩小
} else {
this.zoomIn(); // 放大
}
return false;
},
//放大
zoomIn() {
let evt = window.event;
/svg画布左上角的位置/
let svgX = this.svgDom.getBoundingClientRect().left
let svgY = this.svgDom.getBoundingClientRect().top
/缩放前svg画布中鼠标与原点的距离/
let beforeX = (evt.clientX - svgX) / this.scale
let beforeY = (evt.clientY - svgY) / this.scale
this.scale *= this.scaleStep;
/缩放后svg画布中鼠标与原点的距离/
let laterX = (evt.clientX - svgX) / this.scale
let laterY = (evt.clientY - svgY) / this.scale
/得到偏移量/
const offsetX = laterX - beforeX;
const offsetY = laterY - beforeY ;

  this.getCurrentVB();
  this.vbCX -= offsetX
  this.vbCY -= offsetY
  this.vbCW /= this.scaleStep;
  this.vbCH /= this.scaleStep;

  // 刷新当前viewBox展示的视图位置
  this.svgDom.setAttributeNS(
    null,
    "viewBox",
    this.vbCX + " " + this.vbCY + " " + this.vbCW + " " + this.vbCH
  );
},
//缩小
zoomOut() {
  let evt = window.event;
  /*svg画布左上角的位置*/
  let svgX = this.svgDom.getBoundingClientRect().left
  let svgY = this.svgDom.getBoundingClientRect().top
  /*缩放前svg画布中鼠标与原点的距离*/
  let beforeX = (evt.clientX - svgX) / this.scale
  let beforeY = (evt.clientY - svgY) / this.scale
  this.scale /= this.scaleStep;
  /*缩放后svg画布中鼠标与原点的距离*/
  let laterX = (evt.clientX - svgX) / this.scale
  let laterY = (evt.clientY - svgY) / this.scale
  /*得到偏移量*/
  const offsetX = laterX - beforeX;
  const offsetY = laterY - beforeY ;

  this.getCurrentVB();
  this.vbCX -= offsetX
  this.vbCY -= offsetY
  this.vbCW *= this.scaleStep;
  this.vbCH *= this.scaleStep;

  // 刷新当前viewBox展示的视图位置
  this.svgDom.setAttributeNS(
    null,
    "viewBox",
    this.vbCX + " " + this.vbCY + " " + this.vbCW + " " + this.vbCH
  );
},

}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值