我正在使用SVG用Javascript开发 map 。

我想添加一个功能,您可以在其中搜索道路,如果找到了道路,则 map 上会出现一个圆圈。

我知道我可以在SVG中绘制一个圆,但是我的问题是,圆的大小不应随缩放级别而变化。换句话说,圆必须始终具有相同的大小。
我 map 上的道路具有此功能,我要做的就是添加

vector-effect="non-scaling-stroke"

线属性

一条线看起来像这样。
<line vector-effect="non-scaling-stroke" stroke-width="3" id = 'line1' x1 = '0' y1 = '0' x2 = '0' y2 = '0' style = 'stroke:rgb(255,215,0);'/>

圆圈看起来像这样。
<circle id = "pointCircle" cx="0" cy="0" r="10" stroke="red" stroke-width="1" fill = "red"/>

是否可以通过某种方式将圆定义为“非缩放”?

最佳答案

我花了一段时间,但我终于弄清了数学。此解决方案需要三件事:

  • 在页面中添加this script(以及SVGPan.js脚本),例如<script xlink:href="SVGPanUnscale.js"></script>
  • 标识您不想缩放的项目(例如,将它们放置在具有特殊类或ID的组中,或者在每个元素上放置特定的类),然后告诉脚本如何查找这些项目,例如unscaleEach("g.non-scaling > *, circle.non-scaling");
  • 使用transform="translate(…,…)"将每个元素(而不是cx="…" cy="…")放置在图表上。

  • 仅需执行这些步骤,使用SVGPan进行缩放和平移将不会影响标记元素的比例(或旋转或倾斜)。

    演示:http://phrogz.net/svg/scale-independent-elements.svg

    图书馆

    // Copyright 2012 © Gavin Kistner, !@phrogz.net
    // License: http://phrogz.net/JS/_ReuseLicense.txt
    
    // Undo the scaling to selected elements inside an SVGPan viewport
    function unscaleEach(selector){
      if (!selector) selector = "g.non-scaling > *";
      window.addEventListener('mousewheel',     unzoom, false);
      window.addEventListener('DOMMouseScroll', unzoom, false);
      function unzoom(evt){
        // getRoot is a global function exposed by SVGPan
        var r = getRoot(evt.target.ownerDocument);
        [].forEach.call(r.querySelectorAll(selector), unscale);
      }
    }
    
    // Counteract all transforms applied above an element.
    // Apply a translation to the element to have it remain at a local position
    function unscale(el){
      var svg = el.ownerSVGElement;
      var xf = el.scaleIndependentXForm;
      if (!xf){
        // Keep a single transform matrix in the stack for fighting transformations
        // Be sure to apply this transform after existing transforms (translate)
        xf = el.scaleIndependentXForm = svg.createSVGTransform();
        el.transform.baseVal.appendItem(xf);
      }
      var m = svg.getTransformToElement(el.parentNode);
      m.e = m.f = 0; // Ignore (preserve) any translations done up to this point
      xf.setMatrix(m);
    }
    

    示范代码

    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
      <title>Scale-Independent Elements</title>
      <style>
        polyline { fill:none; stroke:#000; vector-effect:non-scaling-stroke; }
        circle, polygon { fill:#ff9; stroke:#f00; opacity:0.5 }
      </style>
      <g id="viewport" transform="translate(500,300)">
        <polyline points="-100,-50 50,75 100,50" />
        <g class="non-scaling">
          <circle  transform="translate(-100,-50)" r="10" />
          <polygon transform="translate(100,50)" points="0,-10 10,0 0,10 -10,0" />
        </g>
        <circle class="non-scaling" transform="translate(50,75)" r="10" />
      </g>
      <script xlink:href="SVGPan.js"></script>
      <script xlink:href="SVGPanUnscale.js"></script>
      <script>
        unscaleEach("g.non-scaling > *, circle.non-scaling");
      </script>
    </svg>
    

    07-24 17:19
    查看更多