zoukankan      html  css  js  c++  java
  • 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;
                }
            };
        }

     到此就结束了

  • 相关阅读:
    PHP新的垃圾回收机制:Zend GC详解
    SSH隧道技术简介
    mysql主从延迟
    非root配置linux下vim
    PHP 中的 9 个魔术方法
    PHP内核介绍及扩展开发指南—Extensions 的编写(下)
    PHP内核介绍及扩展开发指南—Extensions 的编写
    php 扩展开发
    php opcode
    rsa 数学推论
  • 原文地址:https://www.cnblogs.com/LcxSummer/p/12803892.html
Copyright © 2011-2022 走看看