svg 不同比例缩放后 拖拽事件的鼠标位置转换为svg图纸中的位置
说起来可能有点绕,下面尽可能的把我想表达的表述清楚吧
来看下下面这张图
svg元素的宽度和浏览器的宽度是不一样的,事实上,还有一个宽度,那就是svg画布的宽度
为什么会有这么多不一样的宽度呢,直接浏览器的宽高就是svg标签的宽高,同时也设置同样的画布宽高,不就不用转换拖拽事件鼠标的坐标位置了吗?
是这么个道理,一开始我也是这么干的,可是后来发现,不同客户用不同的电脑、不同的浏览器,会有不同的宽高,如果一个用户在1366*768的环境下设置好了一张画布,那么这个画布就得按照1366*768的尺寸来设置画布的宽高,但是当另一个用户来修改这张画布的内容时,他的浏览器宽高可能是1200*600,宽高比例不一样的话就会出现上图中的样子,或者是直接让svg变形填充,像下图这样:
图形好像都扁了一点点,好像也不影响观看,但是事实上也只是svg元素的宽高和浏览器的宽高相等了(1200*600),画布的宽高是不一样的(1366*768)
不过这种情况转换还是好计算些的,只要拿两个宽高的比例来计算下就行,逻辑见下图的分析
如果鼠标拖拽到100,150的地方后,直接在画布里100,150的地方放置图像,那么就会发现与我拖拽的位置是不一致的,有偏移,这样的体验效果是不好的,该如何计算呢?
可见想要求的x和y有这样的公式:
x / 1366(画布的宽度) = 100 / 1200 (svg元素的宽度)
同样 : y / 768 = 150 / 600
什么意思呢,就是浏览器中100,150这个点在浏览器中的比例,应该是与x, y这个点在画布中的比例是相等的(想一想如果这个红色的点在最右下角,就能理解这个等比了),这样就能获取红色点对应在画布中的位置
更复杂的情况就是图1中的情况,svg元素的宽度(elementW)、浏览器的宽度(HtmlWi)、svg画布的宽度(W)都不一样(当然也有可能是高度都不一样,具体要看原来的尺寸后来的客户的尺寸的差别)
可以发现 elementW 比 HtmlWi 小,两边都有留出空的区域,暂且称这个宽度为 gapX, 见下图:
当鼠标处于页面上的某一个位置时(比如100,150),那么这个点在svg标签上的位置,y 是相同的(150),但是 x 小一些,x 是 100 减去 gapX 后的值,见下图:
然后这个100 - gapX 同样满足 x / W(画布的宽度) = (100 - gapX) / elementW(svg元素的宽度)
这样看来好像也并不复杂了,下面贴代码
var elementW = W * HtmlHe / H; // 元素的宽高是自适应的,需要根据页面的宽高和画布的宽高来计算出来 if (elementW < HtmlWi) { // 只有当元素的宽高小于页面的宽高时,才需要计算gap的值 var gapX = (HtmlWi - elementW) / 2; SvgX = (e) => { if (MyPreserveAspectRatio == "") { // 不为空的话,是全屏显示,图形会被拉伸,也就不涉及gap值的处理了 return (e.clientX - gapX) * W / elementW; } else { return e.clientX * W / HtmlWi; } }; }
同样,当高度不一样时,也是需要处理 y 的值的:
var elementH = H * HtmlWi / W; if (elementH < HtmlHe) { var gapY = (HtmlHe - elementH) / 2; SvgY = (e) => { if (MyPreserveAspectRatio == "") { return (e.clientY - gapY) * H / elementH; } else { return e.clientY * H / HtmlHe; } }; }
到此就结束了