How to keep viewBox centered when “zooming” in SVGs?

非 Y 不嫁゛ 提交于 2019-12-11 15:21:34

问题


Often I use the viewBox attribute to "zoom" a SVG element. Zoom is accomplished of course by using lower width and height values for the viewBox attribute - but the x and y values are tricky to figure out for keeping the scene centered.

Below is a snippet where viewBox="0 0 100 100". ( x y width height ) This is my starting point. The scene is to scale and starts at the top left corner.

<head>
  <link rel="stylesheet" href="https://codepen.io/basement/pen/oepKxY.css">
</head>

<body> 
  <iframe src="https://s.codepen.io/basement/debug/zdpVyV/PNAvYLZmJRQr"
          id="grid"
  ></iframe>

  <div class="wrp">   
  
    <!-- SVG relevant code below-->
    <svg xmlns="http://www.w3.org/2000/svg"
         viewBox="0 0 100 100"
         width="100" height="100"
         class="canvas"
    > 
      <defs>   
        <style type="text/css"> 

          circle {
            fill: #0ff;
            fill-opacity: 0.25;
            stroke-width: 0.25;
            stroke: #0ee;
          }

        </style>       
      </defs>

      <circle cx="37.5" cy="50" r="25" />
      <circle cx="62.5" cy="50" r="25" />
      <circle cx="50" cy="71.65" r="25" />    
    </svg>
    
  </div>
</body>

( Viewable in full page. Snippets are responsive )

Zooming in

Changing the width and height values to 50 in the viewBox zooms the scene. However I had to adjust the x and y values both to half the viewBox dimensions: 25 to keep the drawing centered.

viewBox="25 25 50 50"

<head>
  <link rel="stylesheet" href="https://codepen.io/basement/pen/oepKxY.css">
</head>

<body> 
  <iframe src="https://s.codepen.io/basement/debug/zdpVyV/PNAvYLZmJRQr"
          id="grid"
  ></iframe>

  <div class="wrp">   
  
    <!-- SVG relevant code below-->
    <svg xmlns="http://www.w3.org/2000/svg"
         viewBox="25 25 50 50"
         width="100" height="100"
         class="canvas"
    > 
      <defs>   
        <style type="text/css"> 

          circle {
            fill: #0ff;
            fill-opacity: 0.25;
            stroke-width: 0.25;
            stroke: #0ee;
          }

        </style>       
      </defs>

      <circle cx="37.5" cy="50" r="25" />
      <circle cx="62.5" cy="50" r="25" />
      <circle cx="50" cy="71.65" r="25" />    
    </svg>
    
  </div>
</body>

Halving the width and height isn't consistent

Following the pattern of halving the width and height to center the scene:

viewBox="12.5 12.5 25 25" should continue the zoom and stay centered. But it doesn't stay centered. My question is what formula or technique does SVG use that I can always figure out mathematically what x and y value I need to center a specific width and height value in the viewBox?

Note: I'm aware of libraries like Snap.svg and Raphaël. I'm avoiding libraries in an effort to understand the fundamentals.

One more thing: I'm asking if you already have a width and height value in the viewBox how do you find the center coordinates of the scene. Not vice versa.

External stylesheets were included for visual cognition. The only relevant code to this question is pertaining to the SVG elements.


回答1:


Your calculations are wrong. If the width and height of the viewBox get smaller, the x and y values need to get bigger.

Initial viewBox:  0 0 100 100
Zoom X2:          25 25 50 50
Zoom X4:          37.5 37.5 25 25

To get the x or y values, you need to subtract half the new width or height from the halfway point of the last (or original) viewBox.

Zoom X2:  centre - newWidth/2
          = (100/2) - (50/2) = 25
Zoom X4:  (100/2) - (25/2) = 37.5, or
          (25 + 50/2) - (25/2) = 37.5

Another waty to calculate it is to subtract the current width from the original width and divide by two.

Zoom X4:  (100 - 25) / 2 = 37.5

<head>
  <link rel="stylesheet" href="https://codepen.io/basement/pen/oepKxY.css">
</head>

<body> 
  <iframe src="https://s.codepen.io/basement/debug/zdpVyV/PNAvYLZmJRQr"
          id="grid"
  ></iframe>

  <div class="wrp">   
  
    <!-- SVG relevant code below-->
    <svg xmlns="http://www.w3.org/2000/svg"
         viewBox="37.5 37.5 25 25"
         width="100" height="100"
         class="canvas"
    > 
      <defs>   
        <style type="text/css"> 

          circle {
            fill: #0ff;
            fill-opacity: 0.25;
            stroke-width: 0.25;
            stroke: #0ee;
          }

        </style>       
      </defs>

      <circle cx="37.5" cy="50" r="25" />
      <circle cx="62.5" cy="50" r="25" />
      <circle cx="50" cy="71.65" r="25" />    
    </svg>
    
  </div>
</body>


来源:https://stackoverflow.com/questions/45892233/centering-on-specific-points-when-zooming-using-svg-viewbox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!