如何在SVG中“缩放”时保持viewBox居中?

时间:2017-08-18 17:59:48

标签: html css svg zoom viewbox

我经常使用viewBox属性来“缩放”SVG元素。当然,通过使用viewBox属性的较低宽度高度值来完成缩放 - 但 x y 值很难弄清楚是否保持场景居中。

以下是viewBox="0 0 100 100"的摘录。 (x y width height)这是我的出发点。场景是缩放并从左上角开始。

<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>

(可在整页中查看。代码段响应)

放大

50中的宽度高度值更改为viewBox可缩放场景。但是,我必须将xy值调整为viewBox尺寸的一半:25以使图形居中。

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>

将宽度和高度减半不一致

遵循将宽度高度减半以使场景居中的模式:

viewBox="12.5 12.5 25 25"应继续缩放并保持居中。但它并没有保持中心。我的问题是SVG使用什么公式或技术,我总能在数学上弄清楚我需要以特定宽度为中心的 x y 和{em>身高值viewBox

注意:我知道Snap.svgRaphaël等库。我正在避免使用库来理解基础知识。

还有一件事:我问你viewBox中是否已经有宽度身高值?你怎么找到这个中心场景的坐标。反之亦然。

包含外部样式表用于视觉认知。此问题的唯一相关代码与SVG元素有关。

2 个答案:

答案 0 :(得分:2)

你的计算错了。如果viewBox的宽度和高度变小,则x和y值需要变大。

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

要获取x或y值,您需要从最后一个(或原始)视图框的中点减去新宽度或高度的一半。

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

计算它的另一个问题是从原始宽度中减去当前宽度并除以2。

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

&#13;
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

由于代码段已过期,因此我不得不考虑如何实现它,我想我会避免其他人这样做,并发布有效的代码段。

var svg = document.querySelector('svg');
var viewBox = svg.viewBox.baseVal

function zoomIn(){
    viewBox.x = viewBox.x + viewBox.width / 4;
    viewBox.y = viewBox.y + viewBox.height / 4;
    viewBox.width = viewBox.width / 2;
    viewBox.height = viewBox.height / 2;
}

function zoomOut(){
    viewBox.x = viewBox.x - viewBox.width / 2;
    viewBox.y = viewBox.y - viewBox.height / 2;
    viewBox.width = viewBox.width * 2;
    viewBox.height = viewBox.height * 2;
}

如果您实现了平移功能,则无需任何修改即可使用它。