如何放大复杂的 svg 结构 [英] how to zoom in on a complex svg structure

查看:76
本文介绍了如何放大复杂的 svg 结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在代码段中有一组复杂的形状.它们是用 React 渲染的,但我真的只是在寻找一些关于如何放大和缩小这些形状的指示.

我的谷歌搜索失败了,我只能找到图表的例子.

如何放大和缩小这样的复杂结构?

 <g class="vx-group vx-tree" transform="translate(20, 70)"><g class="vx-group" transform="translate(0, 70)"><g class="vx-group" transform="translate(0, 0)"><path class="vx-link-vertical" d="M451.5,0C451.5,233.5,451.5,233.5,451.5,467" 百分比="0.5"stroke="#f7f7f3" stroke-width="1" stroke-opacity="0.2" fill="none"></path><g class="vx-group" transform="translate(0, 0)"><g class="vx-group" transform="translate(451.5, 0)" opacity="1"><g class="vx-group node__container" transform="translate(0, 0)"><svg class="" x="0" y="0" style="溢出:可见;"><多边形点= 25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30"class="node__hexagon"></polygon></svg><g class="vx-group node__business-unit" transform="translate(0, 0)"><use xlink:href="#icon-BusinessUnit"></use><g class="hierarchy-label__container" transform="translate(0, -40)"><路径类="" d="米 0.0078125, 5.15625L 34.64882865137755,25.156249999999996M -0.9921875, 5.15625L -34.63320365137754,25.156249999999996H -65.8515625a8,8 0 0 1 -8,-8V -47.15625a8,8 0 0 1 8,-8 H 65.8515625 a8,8 0 0 1 8,8大号 73.8515625, 17.156249999999996a8,8 0 0 1 -8,8L 34.64882865137755, 25.156249999999996Z></路径><svg x="0" y="0" style="溢出:可见;"><text class="hierarchy-label__item__name" width="150" y="-25" x="0" text-anchor="middle"style="pointer-events: none;"><tspan x="0" dy="0em">金融</tspan></svg><svg x="0" y="0" style="溢出:可见;"><text class="hierarchy-label__item__type" width="150" y="-5" x="0" text-anchor="middle"style="pointer-events: none;"><tspan x="0" dy="0.71em">事业部</tspan></svg></svg>

解决方案

svg 中的缩放是通过

可以在

I have a complex set of shapes that are in the snippet. They are rendered with React but I'm really just looking for some pointers about how I would go about being able to zoom these shapes in and out.

My googling is failing and I can only really find examples of graphs.

How can zoom in and out complex structures like this?

    <svg height="767" width="903">
    <g class="vx-group vx-tree" transform="translate(20, 70)">
        <g class="vx-group" transform="translate(0, 70)">
            <g class="vx-group" transform="translate(0, 0)">
                <path class="vx-link-vertical" d="M451.5,0C451.5,233.5,451.5,233.5,451.5,467" percent="0.5"
                      stroke="#f7f7f3" stroke-width="1" stroke-opacity="0.2" fill="none"></path>
            </g>
            <g class="vx-group" transform="translate(0, 0)">
                <g class="vx-group" transform="translate(451.5, 0)" opacity="1">
                    <g class="vx-group node__container" transform="translate(0, 0)">
                        <svg class="" x="0" y="0" style="overflow: visible;">
                            <polygon
                                    points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30"
                                    class="node__hexagon"></polygon>
                        </svg>
                        <g class="vx-group node__business-unit" transform="translate(0, 0)">
                            <use xlink:href="#icon-BusinessUnit"></use>
                        </g>
                        <g class="hierarchy-label__container" transform="translate(0, -40)">
                            <path class="" d="
                                  M 0.0078125, 5.15625
                                  L 34.64882865137755,25.156249999999996 
                                  M -0.9921875, 5.15625 
                                  L -34.63320365137754,25.156249999999996
                                  H -65.8515625 
                                  a8,8 0 0 1 -8,-8  
                                  V -47.15625 
                                  a8,8 0 0 1 8,-8 H 65.8515625 a8,8 0 0 1 8,8 
                                  L 73.8515625, 17.156249999999996  
                                  a8,8 0 0 1 -8,8 
                                  L 34.64882865137755, 25.156249999999996 
                                  Z 
                                 ">
                            </path>
                            <svg x="0" y="0" style="overflow: visible;">
                                <text class="hierarchy-label__item__name" width="150" y="-25" x="0" text-anchor="middle"
                                      style="pointer-events: none;">
                                    <tspan x="0" dy="0em">Finance</tspan>
                                </text>
                            </svg>
                            <svg x="0" y="0" style="overflow: visible;">
                                <text class="hierarchy-label__item__type" width="150" y="-5" x="0" text-anchor="middle"
                                      style="pointer-events: none;">
                                    <tspan x="0" dy="0.71em">Business Unit</tspan>
                                </text>
                            </svg>
                        </g>
                    </g>
                </g>
            </g>
        </g>
    </g>
</svg>

解决方案

Scaling in svg is done with viewBox, which combines both scaling and offset. There is a nice article How to Scale SVG. From the following article:

If you think of the document as a canvas, the view box is part of the canvas you want the viewer to see.

It's like a screen of your cell phone in the camera app which shows part of the scene which is observed with specified scale and offsets.

Nice sample which demonstrates what is viewBox can be found here.

A little math and I implemented zoom in/zoom out with mousewheel. In addition added panning with mousemove and display scale value. An example which demonstrates how viewBox can be used:

const svgImage = document.getElementById("svgImage");
const svgContainer = document.getElementById("svgContainer");

var viewBox = {x:0,y:0,w:svgImage.clientWidth,h:svgImage.clientHeight};
svgImage.setAttribute('viewBox', `${viewBox.x} ${viewBox.y} ${viewBox.w} ${viewBox.h}`);
const svgSize = {w:svgImage.clientWidth,h:svgImage.clientHeight};
var isPanning = false;
var startPoint = {x:0,y:0};
var endPoint = {x:0,y:0};;
var scale = 1;

svgContainer.onmousewheel = function(e) {
   e.preventDefault();
   var w = viewBox.w;
   var h = viewBox.h;
   var mx = e.offsetX;//mouse x  
   var my = e.offsetY;    
   var dw = w*Math.sign(e.deltaY)*0.05;
   var dh = h*Math.sign(e.deltaY)*0.05;
   var dx = dw*mx/svgSize.w;
   var dy = dh*my/svgSize.h;
   viewBox = {x:viewBox.x+dx,y:viewBox.y+dy,w:viewBox.w-dw,h:viewBox.h-dh};
   scale = svgSize.w/viewBox.w;
   zoomValue.innerText = `${Math.round(scale*100)/100}`;
   svgImage.setAttribute('viewBox', `${viewBox.x} ${viewBox.y} ${viewBox.w} ${viewBox.h}`);
}


svgContainer.onmousedown = function(e){
   isPanning = true;
   startPoint = {x:e.x,y:e.y};   
}

svgContainer.onmousemove = function(e){
   if (isPanning){
  endPoint = {x:e.x,y:e.y};
  var dx = (startPoint.x - endPoint.x)/scale;
  var dy = (startPoint.y - endPoint.y)/scale;
  var movedViewBox = {x:viewBox.x+dx,y:viewBox.y+dy,w:viewBox.w,h:viewBox.h};
  svgImage.setAttribute('viewBox', `${movedViewBox.x} ${movedViewBox.y} ${movedViewBox.w} ${movedViewBox.h}`);
   }
}

svgContainer.onmouseup = function(e){
   if (isPanning){ 
  endPoint = {x:e.x,y:e.y};
  var dx = (startPoint.x - endPoint.x)/scale;
  var dy = (startPoint.y - endPoint.y)/scale;
  viewBox = {x:viewBox.x+dx,y:viewBox.y+dy,w:viewBox.w,h:viewBox.h};
  svgImage.setAttribute('viewBox', `${viewBox.x} ${viewBox.y} ${viewBox.w} ${viewBox.h}`);
  isPanning = false;
   }
}

svgContainer.onmouseleave = function(e){
 isPanning = false;
}

<span id="zoomValue">1</span>
<div id="svgContainer">
<svg id="svgImage" height="964" width="767">
    <g  class="vx-group vx-tree" transform="translate(20, 70)">
        <g class="vx-group" transform="translate(0, 70)">
            <g class="vx-group" transform="translate(0, 0)">
                <path class="vx-link-vertical" d="M451.5,0C451.5,233.5,451.5,233.5,451.5,467" percent="0.5" stroke="#f7f7f3" stroke-width="1" stroke-opacity="0.2" fill="none"></path>
            </g>
            <g class="vx-group" transform="translate(0, 0)">
                <g class="vx-group" transform="translate(451.5, 0)" opacity="1">
                    <g class="vx-group node__container" transform="translate(0, 0)">
                        <svg class="" x="0" y="0" style="overflow: visible;">
                            <polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30" class="node__hexagon"></polygon>
                        </svg>
                        <g class="vx-group node__business-unit" transform="translate(0, 0)">
                            <use xlink:href="#icon-BusinessUnit"></use>
                        </g>
                        <g class="hierarchy-label__container" transform="translate(0, -40)">
                           <path class="" d="
                              M 0.0078125, 5.15625
                              L 34.64882865137755,25.156249999999996 
                              M -0.9921875, 5.15625 
                              L -34.63320365137754,25.156249999999996
                              H -65.8515625 
                              a8,8 0 0 1 -8,-8  
                              V -47.15625 
                              a8,8 0 0 1 8,-8 H 65.8515625 a8,8 0 0 1 8,8 
                              L 73.8515625, 17.156249999999996  
                              a8,8 0 0 1 -8,8 
                              L 34.64882865137755, 25.156249999999996 
                              Z 
                             "></path>
     			          <svg x="0" y="0" style="overflow: visible;">
     			              <text class="hierarchy-label__item__name" width="150" y="-25" x="0" text-anchor="middle" style="pointer-events: none;">
     			                  <tspan x="0" dy="0em">Finance</tspan>
     			              </text>
     			          </svg>
             			  <svg x="0" y="0" style="overflow: visible;">
             			      <text class="hierarchy-label__item__type" width="150" y="-5" x="0" text-anchor="middle" style="pointer-events: none;">
             			          <tspan x="0" dy="0.71em">Business Unit</tspan>
             			      </text>
             			  </svg>
                       </g>
                   </g>
               </g>
           </g>
       </g>
   </g>
   </svg>
</div>

Math:

这篇关于如何放大复杂的 svg 结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆