*作者:浮笙若有梦
开篇
轻流有一套自己的icon库,之前每个icon对应一个svg图标。这会导致一个问题:network中会有一堆的svg请求,这种多次请求会极大地增加服务器的负担,但现在项目启动后network中所有的svg请求都不见了,那么它究竟去哪里了?为了搞清楚这个问题,就需要我们掌握一些svg的知识,在文章的最后会由我带着大家来揭开这个疑问。
定义
可缩放矢量图形(Scalable Vector Graphics,svg)基于 XML 标记语言,用于描述二维的矢量图形。
相关拓展
对于计算机领域,图像一般分为两大类:矢量图和位图(也叫标量图)。
矢量图最大的特点是可以随意缩放,不论您如何改变矢量图像的大小,矢量图的质量是不会变的,因为矢量图完全由数学公式构成,图像大小不影响数学公式的表达。 常见的矢量图文件格式:
- .dwg
- .svg
- .ai
- .dxf
位图(标量图)指一个特定大小的图像。如果您放大一个位图,它会变得“像素化”并且失去之前的清晰度。这是因为位图本质上是由一组彩色的正方形组成的。 常见的位图文件格式:
- .jpg
- .bmp
- .tiff
- .gif
- .png
- .heif
两者的放大之后的对比图(左边:位图,右边:矢量图)
可以看出,矢量图并不会因为放大而变得模糊,而这次给大家介绍的svg就是属于矢量图,对于svg的学习,大家可以理解成是一套新的标签规范,和html标签差不多。
为什么要学习它
学习 SVG 可以为前端开发人员提供创建高质量图形的能力,并为自己网站或应用程序带来更好的用户体验。
- 矢量图形的优势:矢量图形可以根据需要进行缩放和拉伸,而不会失去清晰度和质量。与位图不同,SVG 可以轻松地适应不同的屏幕大小和设备类型,从而使网站或应用程序更具响应性。
- 动画效果:SVG 允许您创建复杂的动画效果,以增强用户体验。通过使用 JavaScript 库,您可以创建酷炫的动画和交互效果,从而使您的网站或应用程序更加生动和有趣。
- 图标设计:SVG 可以用于创建复杂的图标和标志。这些图标和标志可以缩放到任何大小,并且可以通过 CSS 或 JavaScript 进行自定义。
- 可访问性:使用 SVG 可以提高网站或应用程序的可访问性。由于矢量图形可以放大,因此即使用户具有较低的视力,他们也可以轻松地看到图像的细节。
使用方法
第一种方式,也是最常用的方式就是在html中直接引入,需要注意的是SVG 代码都必须放在顶层标签之中
<!-- 在不设置svg宽高的情况下,默认宽度是300px,默认高度是150px -->
<svg>
<circle cx="50" cy="50" r="50" fill="purple"></circle>
</svg>
<!-- 单独这样写是无法生效的 -->
<circle cx="50" cy="50" r="50" fill="purple"></circle>
第二种方式就是通过css作为背景图片引入
<style>
.svg-container {
width: 80px;
height: 80px;
background: no-repeat
url('https://***.qingflow.com/***/6cf48d87676A9D/044206d7-a000-45f3-a381-2ba7cf19f831.svg');
background-size: 80px 80px;
}
</style>
<div class="svg-container"></div>
第三种方式是通过img标签的形式引入的
<!-- 直接作为图片路径引入 -->
<img
src="https://***.qingflow.com/***/6cf48d87676A9D/044206d7-a000-45f3-a381-2ba7cf19f831.svg"
/>
剩下的方式都是不推荐的 🙅♂️ 🙅♂️ 🙅♂️
<!-- iframe的方式 -->
<iframe
src="https://***.qingflow.com/***/6cf48d87676A9D/044206d7-a000-45f3-a381-2ba7cf19f831.svg"
width="100"
height="100"
></iframe>
<!-- embed引入 -->
<embed
src="https://***.qingflow.com/***/6cf48d87676A9D/044206d7-a000-45f3-a381-2ba7cf19f831.svg"
width="100"
height="100"
/>
<!-- object引入 -->
<object
data="https://***.qingflow.com/***/6cf48d87676A9D/044206d7-a000-45f3-a381-2ba7cf19f831.svg"
type="image/svg+xml"
>
常用标签
矩形 rect
基础属性:
* x: 左上角x轴坐标
* y: 左上角y轴坐标
* width: 宽度
* height: 高度
* rx:圆角,x轴的半径
* ry:圆角
**注意点:**
1. **默认填充色是黑色**
2. **只设置rx或者ry其中一个是,另一个属性也是同样的值**
<!-- 矩形 -->
<svg width="100" height="100" style="border: 1px solid red">
<rect x="10" y="20" rx="0px" ry="0px" width="80" height="60"></rect>
</svg>
圆形 circle
基础属性:
* cx: 圆心在x轴坐标
* cy: 圆心在y轴坐标
* r: 半径
**注意点:**
1. **默认填充色是黑色**
<!-- 圆形 -->
<svg width="100" height="100" style="border: 1px solid red">
<circle cx="40" cy="40" r="30"></circle>
</svg>
椭圆 ellipse
基础属性:
* cx: 圆心在x轴坐标
* cy: 圆心在y轴坐标
* rx: x轴的半径
* ry: y轴的半径
**注意点:**
1. **默认填充色是黑色**
<!-- 椭圆 -->
<svg width="100" height="100" style="border: 1px solid red">
<ellipse cx="50" cy="50" rx="40" ry="20"></ellipse>
</svg>
直线 line
基础属性:
* x1: 起点x坐标
* y1: 起点y坐标
* x2: 终点x坐标
* y2: 终点y坐标
* stroke:描边颜色
**注意点:**
1. **默认填充色是黑色**
2. **x1,x2是固定名字,不可以改名**
<!-- 直线 -->
<svg width="100" height="100" style="border: 1px solid red">
<line x1="30" y1="40" x2="80" y2="80" stroke="purple"></line>
</svg>
折线 polyline
基础属性:
* points: 点集
* stroke: 描边颜色
* fill: 填充颜色
**注意点:**
1. **默认填充色是黑色**
2. **points接受的是一串点集,点集是两两一组表示一个坐标(其实不用逗号隔开,用逗号是为了看得清晰)**
<!-- 折线 (如果fill不设置为none,默认就会被填充) -->
<svg width="100" height="100" style="border: 1px solid red">
<polyline points="10 10, 30 80, 60 30" stroke="#000" fill="none"></polyline>
</svg>
多边形 polygon
基础属性:
* points: 点集
* stroke: 描边颜色
* fill: 填充颜色
**注意点:**
1. **默认填充色是黑色**
2. **polygon和polyline差不多,区别就是在于polygon会自动把起点和最后的终点连接一起来**
<!-- 多边形 -->
<svg width="100" height="100" style="border: 1px solid red">
<polygon points="20 20, 40 80, 80 30, 40,40"></polygon>
</svg>
路径 path
基础属性:
* d: 数据
d的关键字:
1. M: 起始点坐标,moveto 的意思。每个路径都必须以 M 开始。M 传入 x 和 y 坐标,用逗号或者空格隔开。
2. L: 轮廓坐标,lineto 的意思。L 是跟在 M 后面的。它也是可以传入一个或多个坐标。大写的 L 是一个绝对位置。
3. l: 这是小写 L,和 L 的作用差不多,但 l 是一个相对位置。
4. H: 和上一个点的Y坐标相等,是 horizontal lineto 的意思。它是一个绝对位置。
5. h: 和 H 差不多,但 h 使用的是相对定位。
6. V: 和上一个点的X坐标相等,是vertical lineto 的意思。它是一个绝对位置。
7. v: 这是一个小写的 v ,和大写 V 的差不多,但小写 v 是一个相对定位。
8. Z: 关闭当前路径,closepath 的意思。它会绘制一条直线回到当前子路径的起点。
**注意点:**
1. **svg里面所有基本图形都是path的简写,所有描述轮廓的数据都在d里面,d是data的简写**
2. **严格区分大小写,大小写决定着是相对坐标还是绝对坐标,但z命令不区分大小写**
<svg width="100" height="100" style="border: 1px solid red">
<!-- 大写的L代表绝对路径 -->
<path d="M 20 20 L 40 40 L 60 40 L 20 80" stroke="red" fill="none"></path>
</svg>
<svg width="100" height="100" style="border: 1px solid red">
<!-- 小写的l代表相对路径,它是会把离它最近的第一个绝对坐标都累积起来 -->
<path d="M 20 20 l 20 20 l 20 0 l -40 40" stroke="blue" fill="none"></path>
<!-- <path d="M 20 20 l 20 20 L 60 40 l -50 40" stroke="blue" fill="none"></path> -->
</svg>
<svg width="100" height="100" style="border: 1px solid red">
<!-- 大写的H代表和上一个点的纵坐标相同,只需要传入横坐标 -->
<path d="M 20 20 L 40 40 H 60 L 20 80" stroke="orange" fill="none"></path>
</svg>
<svg width="100" height="100" style="border: 1px solid red">
<!-- 小写的h代表和上一个点的纵坐标相同,横坐标和上一个点相加 -->
<path d="M 20 20 L 40 40 h 20 L 20 80" stroke="green" fill="none"></path>
</svg>
<svg width="100" height="100" style="border: 1px solid red">
<!-- 大写的V代表和上一个点的横坐标相同,只需要传入纵坐标 -->
<path d="M 20 20 V 80" stroke="purple" fill="none"></path>
</svg>
<svg width="100" height="100" style="border: 1px solid red">
<!-- 小写的v代表和上一个点的横坐标相同,纵坐标和上一个点相加 -->
<path d="M 20 20 v 60" stroke="gray" fill="none"></path>
</svg>
<svg width="100" height="100" style="border: 1px solid red">
<!-- Z代表闭合路径 -->
<path
d="M 20 20 L 40 40 L 60 40 L 20 80 Z"
stroke="cyan"
fill="none"
></path>
</svg>
曲线 path A
绘制曲线比较抽象,一般不推荐手动绘制,可以使用一些专业软件,去生成svg
特殊标签
defs
定义:
SVG 允许我们定义以后需要重复使用的图形元素。建议把所有需要再次使用的引用元素定义在defs元素里面。这样做可以增加 SVG 内容的易读性和无障碍。在defs元素中定义的图形元素不会直接呈现。你可以在你的视口的任意地方利用 <use>元素呈现这些元素。
**作用:**
**用于定义一个svg的模版,后面通过use去调用**
注意:初始是不可见的
<svg>
<!-- defs标签 后面需要给模版添加一个id属性 -->
<defs>
<circle id="container" fill="purple" cx="25" cy="25" r="30" />
</defs>
</svg>
<svg>
<!-- xlink:href这个地方通过指定为刚刚定义好的id来使用 -->
<use x="50" y="20" xlink:href="#container" />
</svg>
symbol
定义:
symbol元素用来定义一个图形模板对象,它可以用一个<use>元素实例化。symbol元素对图形的作用是在同一文档中多次使用,添加结构和语义。结构丰富的文档可以更生动地呈现出来,类似讲演稿或盲文,从而提升了无障碍。注意,一个symbol元素本身是不呈现的。只有symbol元素的实例(亦即,一个引用了symbol的 <use>元素)才能呈现。
**作用:**
**大致和defs作用相同,用法上面有点区别,还有一些属性是否可用的区别**
注意:初始也是不可见的
<svg>
<!-- symbol标签 id可以直接设置在symbol标签上面 -->
<symbol id="symbol-container">
<circle fill="cyan" cx="25" cy="25" r="30" />
</symbol>
</svg>
<svg>
<use x="50" y="20" xlink:href="#symbol-container" />
</svg>
use
定义:
use元素在 SVG 文档内取得目标节点,并在别的地方复制它们。它的效果等同于这些节点被深克隆到一个不可见的 DOM 中,然后将其粘贴到use元素的位置,很像 HTML5 中的克隆模板元素。因为克隆的节点是不可见的,所以当使用CSS样式化一个use元素以及它的隐藏的后代元素的时候,必须小心注意。隐藏的、克隆的 DOM 不能保证继承 CSS 属性,除非你明文设置使用CSS 继承。
**作用:**
**可以使用defs和symbol定义过的标签**
注意:初始是不可见的
<svg>
<!-- defs标签 -->
<defs>
<circle id="defs-container" fill="purple" cx="25" cy="25" r="30" />
</defs>
</svg>
<svg>
<!-- 使用这个定义好的标签 -->
<use x="50" y="20" xlink:href="#defs-container" />
</svg>
<svg>
<!-- symbol标签 -->
<symbol id="symbol-container">
<circle fill="cyan" cx="25" cy="25" r="30" />
</symbol>
</svg>
<svg>
<use x="50" y="20" xlink:href="#symbol-container" />
</svg>
g
定义:
元素g是用来组合对象的容器。添加到g元素上的变换会应用到其所有的子元素上。添加到g元素的属性会被其所有的子元素继承。此外,g元素也可以用来定义复杂的对象,之后可以通过<use>元素来引用它们。
**作用:**
**用于包含一组的svg标签,作用于g的动画或者效果以及其所有子元素都生效**
<svg>
<!-- 四个circle属于同一个 -->
<g stroke="green" fill="white" stroke-width="5">
<circle cx="25" cy="25" r="15" />
<circle cx="40" cy="25" r="15" />
<circle cx="55" cy="25" r="15" />
<circle cx="70" cy="25" r="15" />
</g>
</svg>
在线链接
终篇
现在我们对基本语法已经有个大致了解了,那么下面就是揭晓最终答案的时刻了。
首先看一下我们以前是如何使用svg的:
由上图可以看出,我们是通过请求某个svg图片资源,拿到它对应的的内容,然后再手动创建一个svg,所以当页面中有大量这样的icon,每一个icon为了创建图标,就会去请求对应的svg,从而产生了大量svg的请求。
对比来看,现在我们不是请求某个svg图片,而是去通过提前声明并创建好全部的symbol标签,再通过use标签去调用,这样就能省去了请求这一步了。
最后
轻流
无代码系统搭建平台·轻流
无需代码开发即可搭建专属管理系统
帮助管理者实现管理理念的数字化转型升级