浅谈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。

三、最后

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

相关推荐
LawrenceLan6 分钟前
Flutter 零基础入门(二十六):StatefulWidget 与状态更新 setState
开发语言·前端·flutter·dart
秋秋小事26 分钟前
TypeScript 模版字面量与类型操作
前端·typescript
2401_892000521 小时前
Flutter for OpenHarmony 猫咪管家App实战 - 添加提醒实现
前端·javascript·flutter
Yolanda941 小时前
【项目经验】vue h5移动端禁止缩放
前端·javascript·vue.js
广州华水科技2 小时前
单北斗GNSS形变监测一体机在基础设施安全中的应用与技术优势
前端
EndingCoder2 小时前
案例研究:从 JavaScript 迁移到 TypeScript
开发语言·前端·javascript·性能优化·typescript
阿珊和她的猫4 小时前
React 路由:构建单页面应用的导航系统
前端·react.js·状态模式
Amumu121384 小时前
Vue脚手架(二)
前端·javascript·vue.js
花间相见4 小时前
【LangChain】—— Prompt、Model、Chain与多模型执行链
前端·langchain·prompt
lichenyang4535 小时前
从零开始构建 React 文档系统 - 完整实现指南
前端·javascript·react.js