浅谈ViewBox那些事(一)

ViewBox这个属性在svg里一般用于图像的缩放,是一个比较常见的属性,写法如下:

html 复制代码
<svg
    width="100%"
    height="100%"
    ViewBox="min-x min-y width height"
></svg>

官方对于它的解释是,ViewBox相当于圈了一个矩形,矩形的左上角坐标是(min-x,min-y),宽高分别是width、height。

那接下来,我们正式开始吧。

一、坐标系统

以下面这段代码为例:

html 复制代码
<svg
  width='200'
  height='200'
  style='background-color: antiquewhite'
  ViewBox='25 25 50 50'
>
  <line x1="25" y1="0" x2="25" y2="200" stroke="black" />
  <line x1="0" y1="25" x2="200" y2="25" stroke="black" />
  <line x1="50" y1="0" x2="50" y2="200" stroke="black" />
  <line x1="0" y1="50" x2="200" y2="50" stroke="black" />
  <line x1="75" y1="0" x2="75" y2="200" stroke="black" />
  <line x1="0" y1="0" x2="0" y2="200" stroke="black" />
</svg>

上面这段代码,信息量巨大。为了能够看出效果,我们再添加一个一模一样,只是没有ViewBox属性的svg标签,如下:

html 复制代码
<svg
  width='200'
  height='200'
  style='background-color: antiquewhite'
>
  <line x1="25" y1="0" x2="25" y2="200" stroke="black" />
  <line x1="0" y1="25" x2="200" y2="25" stroke="black" />
  <line x1="50" y1="0" x2="50" y2="200" stroke="black" />
  <line x1="0" y1="50" x2="200" y2="50" stroke="black" />
  <line x1="75" y1="0" x2="75" y2="200" stroke="black" />
  <line x1="0" y1="0" x2="0" y2="200" stroke="black" />
</svg>

首先说一下line标签,它是用来画直线的标签,从(x1,y1)画到(x2,y2),stroke代表线段的颜色。

用浏览器访问一下这两段代码,效果如下:

左侧是带"ViewBox"属性的,右侧不带。

html 复制代码
<svg width='200' height='200' ViewBox='25 25 50 50' ></svg>

上面这段话的含义是当前svg标签的物理长度是200,物理高度也是200。但是当前svg的起点坐标是(25, 25),终点坐标是(25 + 50,25 + 50),也就是(75, 75)。

所以,你在(25,25)到(75,75)之间画图形是ok的,超出这个区域就看不见了,这也变相的被叫做"裁剪功能"。

我们来试验一下,在之前的ViewBox属性的svg里,我们来画一条(25,25)到(50,50)的直线,如下:

html 复制代码
<svg
  width='200'
  height='200'
  style='background-color: antiquewhite'
  ViewBox='25 25 50 50'
>
  <line x1="25" y1="0" x2="25" y2="200" stroke="black" />
  <line x1="0" y1="25" x2="200" y2="25" stroke="black" />
  <line x1="50" y1="0" x2="50" y2="200" stroke="black" />
  <line x1="0" y1="50" x2="200" y2="50" stroke="black" />
  <line x1="75" y1="0" x2="75" y2="200" stroke="black" />
  <line x1="0" y1="0" x2="0" y2="200" stroke="black" />
  
  <path d=" M 25 25 L 50 50 " stroke="black" ></path>
</svg>

这里面我们使用path标签来画直线,当然你也可以使用line标签,它俩都可以用来画直线。

path标签的d属性是绘图的功能,为了能够更精细的绘图,d属性里又细分了N个子命令,比如M、L、Z等等。

这里多解释一下,d属性分为了很多个子命令,可以分2个方面理解。

第一个方面,可以是坐标点。从这个角度看的话,分为了两大类,分别是大写字母(M、L、Z、A、Q等等),小写字母(m、l、z、a、q等等)。其中大写代表绝对坐标,小写代表相对坐标(意思就是相对前面的坐标进行加减运算),如下:

html 复制代码
<path d=" M 25 25 L 50 50 " >

将画笔挪动到(25,25),画一条直线到(50,50)。

如果此时我们将"L 50 50"里的L换成小写,也就是换成"l 50 50",那么此时就代表从(25,25)画一条线到(25 + 50, 25 + 50)。

第二个方面,可以是功能。要么画曲线(A、Q等等),要么画直线(L、H等等)。

继续回到ViewBox里,我们来看下现在的效果:

我们可以看到左侧ViewBox里,(25,25)到 (75,75)这个区域内已经成功的画出了一条直线,大家可以自行在这两个区域外画线,答案肯定是画线失败的,就不在这里展示了。

说完左侧,我们再来说说右侧吧,右侧是没有ViewBox属性的svg,那么根据代码,右侧svg的物理长度是200,物理高度也是200,起点是(0,0),终点是(200,200)。

左侧svg的X轴上有50个逻辑点,50个逻辑点平分200的物理长度,一个点是多少大家自行去算吧。

右侧svg上X轴上有200个逻辑点,200个逻辑点平分200的物理长度,一个点是多少大家也自行去算吧。

这个就是坐标系统(默认情况下,一个逻辑点能体现多少物理长度,这个是由具体业务决定的)。

这跟我们上学时学习数学是一样的,坐标轴默认最小单位设置为1,因为好算,当然,个别场景下,如果1不够用,那就0.1等等。

说完坐标系统,我们来讲讲宽高。

二、宽高

先说结论,代码里的逻辑长度 * 具体的比例系数 === 实际的物理长度。

继续在之前的代码上增加逻辑,如下:

html 复制代码
<svg
  width='200'
  height='200'
  style='background-color: antiquewhite'
  ViewBox='25 25 50 50'
>
  <line x1="25" y1="0" x2="25" y2="200" stroke="black" />
  <line x1="0" y1="25" x2="200" y2="25" stroke="black" />
  <line x1="50" y1="0" x2="50" y2="200" stroke="black" />
  <line x1="0" y1="50" x2="200" y2="50" stroke="black" />
  <line x1="75" y1="0" x2="75" y2="200" stroke="black" />
  <line x1="0" y1="0" x2="0" y2="200" stroke="black" />
  <path d=" M 25 25 L 50 50 " stroke="black" ></path>
  
  <rect x="25" y="25" width="30" height="20" fill="cornflowerblue"></rect> 
 </svg>

跟宽高相关的东西就要涉及到缩放了。因为我们这里缩放系数是4(svg是正方形、ViewBox也是正方形,因此怎么看缩放系数都是一个),rect标签用来画矩形,其中(x,y)是矩形左上角的坐标点,剩下的属性就不用解释。

当大家查看这个效果后会发现,矩形的长宽进行缩放了。在代码里,我们的矩形逻辑宽度是30,50个逻辑点平分200个物理长度,那么一个逻辑点就代表着4个物理长度,因此画出来的矩形物理长度自然就是120 * 80。

三、最后

上面说的都是中规中矩,列举的例子都是正方形,下篇文章咱们来聊聊非常规的情况。我们下期再见,拜拜~~

相关推荐
萨克・麦・迪克13 分钟前
mac安装java17
前端·macos
熊猫在哪17 分钟前
macOS安装nvm
前端·macos·node.js·nvm
AwesomeDevin1 小时前
一种前端硬编码图片扩写方案
前端
放逐者-保持本心,方可放逐1 小时前
css 布局及动画应用(flex+transform+transition+animation)
前端·css·transform·animation·flex·transition·transgorm
卿言卿语2 小时前
第三章:HTML的字符实体,meta标签以及全局属性
前端·html·visual studio code
marshalVS2 小时前
前端学习-事件对象与典型案例(二十六)
前端·javascript·学习
mit6.8242 小时前
[Qt] 窗口 | 菜单栏MenuBar
前端·c++·qt·ubuntu
PieroPc2 小时前
特制一个自己的UI库,只用CSS、图标、emoji图 第二版
前端·css·ui
PieroPc2 小时前
两个关于 li bottom 的CSS 问题 笔记
前端·css·笔记
72degrees2 小时前
vue2迁移至rsbuild
前端·javascript·vue.js