我这样写,为什么svg中的g元素不居中?

8,752 阅读4分钟

先从div中元素水平垂直居中谈起

元素在盒子内水平垂直居中,通常是为了展示上的好看。如果是div中元素的垂直居中,最好的方式就是flex布局,代码非常简单:

display:flex;
align-items:center;
justify-content:center;

排名第二的方式:

position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);

那在svg中呢?如果也这样写,那就糟糕了,元素根本不会垂直居中。在svg中元素都靠x,y坐标来定位,默认这些居中样式都是无效的。于是乎,我发出了疑问,svg中g元素如何居中?

svg的神奇居中属性

在svg中要想让元素居中,则不得不提到viewbox属性,view:视图的意思,顾名思义,viewbox就是视图box,这是svg的一个非常重要的属性,用来控制svg中哪些元素能展示到视野中。它有四个值:

viewbox="x,y,width,height"

其中x,y属性指定viewbox的起始点坐标,width,height指定宽高。我们通过实际代码效果先来体会一下viewBox的妙用。

<html>
<body>
<h1>viewBox 初体验</h1>
<svg height='200' width='200' style='border:1px solid black' >
   <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
</svg> 
</body>
</html>

以上代码定义了一个宽,长都为200的svg,里面有一个圆,没有居中,代码效果是这样的:

image.png

想让这个圆居中我们可以这样做:在svg上写

viewBox="0 -50 200 200"

得到的结果就是圆居中了,perfect!很完美!效果如下:

image.png

那就奇怪了为什么这样写就会居中呢?可能有的朋友对viewBox属性不是很了解,所以不明白这种写法是什么意思,不用慌,我接下来用最浅显易懂的方式来说明viewBox的真正含义。

首先,viewBox的后两个参数如果大于svg本身的宽高,那就代表缩小效果,反之代表放大效果。 何解?我们先这样写:把200改为400

viewBox="0 -50 400 400"

效果如下:

image.png 可以明显看到,整个视图被缩小了,那我们再把400改成100:

viewBox="0 -50 100 100"

效果如下:

image.png 很明显视图被放大了,圆都大得离谱,只能看到一个角了。相信这样展示之后,大家对viewbox的后两个属性已经有了明确的了解:缩放效果

我们再来研究viewbox的前两个属性。我们先让viewbox='0 -50 400 400'缩小效果的图居中,那就要重新调整x,y的值,这样写:

viewBox='-100 -150 400 400'

效果如下:

image.png

可以看到,调了x,y坐标之后,缩小版的圆也居中了,那x,y的值怎么来的?仔细听了,这很重要,要让图形水平居中那就要调整viewbox的x值,x的值计算公式:x=circle.x-viewbox.width/2;也就是当前圆的x坐标减去viewbox的宽的一半。怎么来的?看画图分析:

image.png

圆心坐标不会变,就是100,50;viewbox宽高就是所展示区域的宽高为400,此刻我们想让圆从(100,50)移动到正中央,也就是(200,200)的位置,怎么做呢?就是把整个框框往后移动就行了,移动多少一算就知道了: x=200-100=100; y=200-50=150; 因为框框是往后移动所以要取负的值所以就是x=-100 ,y=-150; 也就得到了居中的viewbox值:

viewBox='-100 -150 400 400'

此时有人可能会说,直接把圆往下移动就行了,还用移动框框那么麻烦吗?是的,直接改变圆的坐标,把(100,50)改成(200,200)就行了,这样也行,但这里遇到的是简单的图形,只有一个圆,万一成千上万个圆,那还要一个一个去改吗? 所以,viewbox的存在有一定的必要性。

相信到这里,大家一定懂得了viewbox的运用,知道了在svg里垂直居中的奥秘。那我们来进行最后一步,把放大的那个圆也居中一下,满足强迫症患者的最后需求。代码如下:

viewBox='50 0 100 100'

效果如下:

image.png

prefect!完美,大圆也正常居中。

最后,回到最开始的问题,svg里g元素如何居中?

g元素也仅仅只是一个元素,和circle一样,也就是和我们刚刚讲的这个圆一样,用viewBox属性去进行缩放居中就行了,好了,svg的居中知识就此完结,撒花。