简单实现svg的拖拽和缩放

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单实现svg的拖拽和缩放相关的知识,希望对你有一定的参考价值。

参考技术A

此方法限制太多,可能
svg使用d3绘制,并且抽象出svg中所有元素的一个参照点和缩放比例
svg元素不会太多,否则会造成卡顿。

最近有个项目需要我帮一下前端,主要是使用d3绘制svg放在页面,其中有一个功能就是对绘制的svg进行拖动和缩放,有点像地图。
这里我已经写好了一个方法来绘制svg

其中svg是要绘制的元素,data是要绘制的数据,x,y是svg的中心坐标,svgA是父元素的边长,来控制svg(正方形)刚好在父元素内,radio是缩放比例

实现方式是<font color=\'red\'>重绘</font>,所以元素太多会造成卡顿。
一、拖拽
我们来分析拖拽的过程,鼠标按下---->鼠标移动------>松开鼠标。对应的事件分别是mousedown、mousemove、mouseup,先定义两个全局变量

鼠标按下事件

鼠标移动事件

最后放开鼠标

一个问题,毋庸置疑这三个事件都注册在svg元素(或者与svg等大的父元素)上,但是当鼠标拖到svg外面时,在svg外面放开了鼠标,鼠标回到svg中,图形会随着鼠标移动,这样是不应该的,所以应该把最后一个事件mouseup注册到最外面的元素上,那么鼠标在svg外放开也可以触发。

二、缩放
缩放的实现和拖拽类似,相同的就不赘述了。
缩放是根据鼠标滚轮的事件触发,但是鼠标滚轮有他的默认事件,那就是页面滚动,这里要阻止它。

对于缩放,我是想做对于鼠标位置放大和缩小,这里要获取到鼠标相对于父元素的坐标(具体做法可以参考上篇文章),保证鼠标放在的那一点相对于父元素的坐标(后都称绝对坐标)不变,再计算中心坐标的偏移量,一开始我是使用矩阵的坐标变换做的,计算量很大,结果显示并不如预期,并且当时矩阵坐标变换也学的不好,我怀疑是算错了,然后突然想到向量,发现用向量的话计算量大大降低,结果显示还是一样。最后还是做的关于中心坐标(包括拖拽后的)的缩放。
对于没能将图形在鼠标位置放大缩小的原因,我认为是做法有问题,项目中的svg图形是以中心点开始向外发散绘制的,所以不应该是鼠标那一点绝对坐标不变,而应该是鼠标所在的元素组的参考点绝对坐标不变。但是实现起来太麻烦,另外如果鼠标没有在任何一个元素组也不好处理,所以干脆以中心坐标不变吧。
另外,此方法简单粗暴,但用处并不太大,只做对拖拽和缩放的理解使用。
最尴尬的是在写这篇博客的时候我看到了一篇文章,让我知道了有 transform ,汗呐!!!
https://blog.csdn.net/leixu1027/article/details/80519730

把svg放大三倍,这里缩放就要计算中心位置偏移量了,然后使用transform的translate进行平移,避免重绘。

以上是关于简单实现svg的拖拽和缩放的主要内容,如果未能解决你的问题,请参考以下文章

第八章 d3拖拽和事件及缩放

d3.js svg 可以同时加拖拽和缩放事件吗

Vue2 实现图片的拖拽缩放旋转

在vue中使用alloyfinger,实现元素的拖拽,缩放,双击,长按等功能

VUE3 中实现拖拽和缩放自定义看板 vue-grid-layout

微信小程序的拖拽缩放和旋转手势