How to draw non-scalable circle in SVG with Javascript

后端 未结 4 1814
星月不相逢
星月不相逢 2020-12-16 20:51

I\'m developing a map, in Javascript using SVG to draw the lines.

I would like to add a feature where you can search for a road, and if the road is found, a circle a

4条回答
  •  半阙折子戏
    2020-12-16 21:05

    It took me a while, but I finally got the math clean. This solution requires three things:

    1. Include this script in your page (along with the SVGPan.js script), e.g.
    2. Identify the items you want not to scale (e.g. place them in a group with a special class or ID, or put a particular class on each element) and then tell the script how to find those items, e.g.
      unscaleEach("g.non-scaling > *, circle.non-scaling");
    3. Use transform="translate(…,…)" to place each element on the diagram, not cx="…" cy="…".

    With just those steps, zooming and panning using SVGPan will not affect the scale (or rotation, or skew) of marked elements.

    Demo: http://phrogz.net/svg/scale-independent-elements.svg

    Library

    // 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);
    }
    

    Demo Code

    
      Scale-Independent Elements
      
      
        
        
          
          
        
        
      
      
      
      
    
    

提交回复
热议问题