目录
前言:SVG 可以为 Web 页面或应用程序添加更多的视觉效果和动画效果,同时也可以实现更好的用户体验。另外,与 HTML 和 CSS 相比,SVG 具有更高的自由度和可定制性。 掌握 SVG 对于前端开发人员来说是非常必要的。它可以帮助开发者提高图形设计能力、增强表现能力、添加可访问性,并在多个平台上支持。
该文章是观看此视频所作笔记,详情请点击观看,支持原创视频!
SVG简介
SVG 英文全称是 Scalable Vector Graphics(即可缩放矢量图) 是一种基于XML 语法的图像格式,是W3C的一项建议。
我们用手机拍摄的照片,图片格式一般都是基于像素处理的,图片放大会模糊失真。SVG 则是属于对图像的形状描述,所以它本质上是文本文件,体积较小。且不管放大多少倍都不会失真。
SVG图片制作
PNG图片是基于像素处理的,我们不能再VSCode里直接编辑。而SVG图片是用类似HTML的代码绘制出来的,因此我们可以通过HTML元素来绘制SVG 图片,可以使用SVG标签使用它。
SVG标签(双标签)是SVG图形的一个容器
<svg>
···
</svg>
里面包含了很多子标签用于绘制各种图形,并且SVG 也可以理解为绘制图形的画布。
属性:width 定义画布的宽度,height 定义画布的高度。
SVG 绘制矩形、圆形和圆形
SVG有一些预定义的形状元素可以供开发者使用
绘制矩形
<rect />标签 ——> rectangle的缩写,单标签
注意:任何一个 HTML 单标签都可以在第二个尖角号前写一个斜杠,表示标签闭合。即用闭合标签表示单标签。
属性包括:
- width: 定义矩形的宽度。
- height: 定义矩形的高度。
- fill: 定义矩形的背景色填充颜色。
- stroke-width:定义了矩形的边框宽度。
- stroke:定义矩形边框的颜色。
<rect width="" height="" fill="" stroke-width="" stroke="" />
- fill-opacity 定义填充颜色的不透明度 合法值的范围是0到1
- stroke-opacity 定义描边颜色的不透明度 合法值的范围是0到1
- opacity 定义整个元素的不透明度 合法值的范围是0到1
透明度的值越小,透明度越高
- rx 定义圆角x轴方向的半径长度
- ry 定义圆角y轴方向的半径长度
- (两个值相等即为圆形的角,两个值不相等即为椭圆形的角)
绘制圆形
circle: 圆形 <circle/>
属性:
- cx: 定义圆形中心的x坐标。
- cy: 定义圆形中心的y坐标。
- r: 定义圆形的半径。
<circle cx="" cy="" stroke="" stroke-width="" fill=""/>
如果省略了cx和cy,圆的中心会被设置为(0,0)
绘制椭圆
属性包括:
- cx: 定义圆中心的x坐标。
- cy: 定义圆中心的 y 坐标。
- rx: 定义水平半径。
- ry: 定义垂直半径。
<ellipse cx="" cy="" rx="" ry="" />
绘制圆形使用 <ellipse /> 标签(圆的 x 和 y 半径是不同的)
位置和大小是由 cx, cy, rx, ry 来决定的
绘制线条、多边型和多线条
绘制线条
line 是线的意思、引申为线条
x1, y1属性 定义x轴,y轴直线起始坐标, x2, y2属性 定义x轴,y轴直线末端坐标
屏幕坐标系起点位置为画布的左上角,和我们熟知的数学坐标系区别是y 轴是相反的。
绘制多边形
<polygon /> poly 含义为“许多",gon 含义为“角度”,用于创建至少包含三个边的图形。
多边形是由直线组成的, 形状是封闭的,所有的线都连接起来。
<polygon points="220,20 250,190 160,210"/>
points 属性 定义了多边形每个角的 x 和y 的坐标(值至少要三对坐标,每一对坐标的x和y用逗号隔开,坐标之间用空格隔开)
绘制五角星
<polygon points="100,10 40,198 198,78 10,78 160,198" fill="ime" stroke="purple"
stroke-width />
绘制线条
<polyline /> 可以创建任何只由直线组成的形状(一般只是将点进行连接,不要求封闭)
poiints 属性 需要两个以上的 x 和y 的坐标对
<polyline points="20,20 40,25"/>
SVG绘制文本
<text X="0" y="15" font-size="20" text-anchor=""> QianFengHTML5</text>
属性x 和 属性y 用来定义文本的位置坐标,值为数字
SVG里为什么不用p标签来显示文本呢?
SVG 是在一个画布里面绘制图形,text 也是绘制的对象,因此就可以使用 svg 一些专有特性控制文本了,例:旋转文本。
<text transform= "rotate( 30 20,40)" >QianFengHTML5</text>
第一个参数是旋转角度,第二个参数是旋转的中心点坐标(这个参数在缺省情况下默认原点(0,0))。
text 元素可以包裹多个 tspan 子元素。每个 tspan 元素可以包含不同的格式和位置。
<text>
<tspan X="0" y="15"></tspan>
<tspan X="10" y="70"></tspan>
</text>
text绘制的文本可以添加链接吗?
为什么不直接用 href 属性呢?实际上 svg 是应用 xml 语法定义元素的,我们还要在 svg 标签上定义一个命名空间的属性 xmins:xlink。(照写即可)
<svg xmlns:xlink="http://www.w3.org/1999/xlink">
<a xlink:href="" target="">
<text> </text>
</a>
</svg>
SVG绘制路径
应用路径可以绘制任意形状的图形
d 属性 是用来定义绘制路径的命令(d 是draw 绘制 的缩写)
M命令(moveto) 定义绘制图形的起点坐标
L命令 (lineto) 用来绘制一条直线
命令的字母大小写表示的意义是不同的。大写字母表示绝对定位,小写字母表示相对定位。
绝对定位是相对于屏幕坐标原点的位置。
相对定位是相对于上一个绘制点的位置。
“贝赛尔曲线”是由法国数学家皮埃尔·贝塞尔 (Pierre Bezier) 发明的,由此为计算机的矢量图形学奠定了基础。
Q 是quadratic Bezier curve 的缩写,用来绘制二次贝塞尔曲线。需要定义控制点和终点的坐标。
我们可以使用 g 标签把多个绘图元素包裹起来。
<g>
<path />
<circle />
</text><text>
</g>
<g> 标签是一个用于组合多个 SVG 元素的容器标签。这些元素被称为“群组”(Group),可以同时应用多个属性和转换来控制它们的位置、大小等外观。
SVG描边属性
<path stroke /> 笔画属性
<path stroke-width /> 笔画宽度属性
<path stroke-linecap /> 笔画笔帽属性
<path stroke-dasharray /> 虚线笔画属性
所有的描边属性都可以应用于任何类型的线条、文本和元素的轮廓。
1️⃣stroke 属性 定义了一个元素的线条、文本或轮廓的颜色,值是任何合法的颜色值。
<path stroke="red" d="M5 20 l215 0" />
2️⃣stroke-width 属性 定义了一个元素的线条、文本或轮廓的厚度,值为数字。
<path stroke-width="2" d="M5 20 1215 0" />
3️⃣stroke-linecap 笔画笔帽属性 它定义了一个开放路径的不同类型的结束点.
<svg width="300” height="80">
<g fill="none" stroke="black" stroke-width="6">
<path stroke-linecap="butt" d="M5 20 1215 0" />
<path stroke-linecap="round" d="M5 40 1215 0" />
<path stroke-linecap="squared" d="M5 60 1215 0" />
</g>
<svg>
4️⃣stroke-dasharray 属性 (虚线序列)用来创建虚线。值为数字序列,以此定义虚线的线条与空隙的大小。序列值为数字,至少定义两个值。
<svg width="300" height="80">
<g fill="none"stroke="black" stroke-width="4">
<path stroke-dasharray="5,5" d"M5 20 1215 0" />
<path stroke-dasharray="10,10" d="M5 40 1215 0" />
<path stroke-dasharray="20,10,5,5,5,10" d="M5 60 1215 0" />
</g>
</svg>
SVG 模糊和阴影效果
filter 元素里面包含一个或多个效果滤镜,filter 元素有一个必要的 id 属性,用于识别过滤器,图形通过这个 id 指向要使用的过滤器。(x 和 y 是滤镜的起始点坐标)
filter 元素都是在 defs 元素中定义的(defs 元素是 definitions 的简称)。
1️⃣模糊效果(高斯模糊效果)可以通过 feGaussianBlur (单标签)滤镜来创建。需要定义在 filter 标签里面。
feGaussianBlur 通过 stdDeviation 属性定义模糊的数量,值为数字,值越大模糊程度越高。
<svg width= "110" height="110">
<defs>
<filter x="0" y="0" id="f1">
<feGaussianBlur stdDeviation="15" />
</filter>
</defs>
<rect width="90" height="90" stroke-"green" stroke-width="3" fill="yellow" filter="url(#f1)"></rect>
</svg>
2️⃣阴影效果可以通过 feOffset 滤镜和 feBlend 滤镜来实现
其原理是将一个SVG 图形、图像或元素,在 xy 平面上做一定的偏移。它需要定义在 filter 标签里面,是一个单标签,基本的语法为<feOffset/>
- dx 属性 表示阴影在 x 轴上的偏移量
- dy 属性 表示阴影在 y 轴上的偏移量
- in 属性 表示阴影图像的来源
- SourceAlpha 用黑色作为阴影
- SourceGraphic 用原始图像作为阴影
<feBlend /> 在偏移的图像上混合原始图像
<svg width="140" height="140">
<defs>
<filter x="0" y="0" width="200" height="200" id"f2">
<feOffset in="SourceAlpha" dx="20" dy="20" />
<feGaussianBlur stdDeviation="10" />
<feBlend in="SourceGraphic" />
</filter>
</defs>
<rect width-"90" height="90" stroke-"green" stroke-width-"3" fill-"yellow" filter="url
(#f2)"></rect>
</svg>
SVG 线性渐变和径向渐变
渐变是一种颜色向另一种颜色的平滑过渡。此外几种颜色的过渡可以应用于同一元素。
SVG中主要有两种渐变类型
1️⃣线性渐变 应用 linearGradient 元素(双标签)来定义,必须嵌套在 defs 标签中,可以实现水平渐变、垂直渐变或角度渐变
坐标属性 (x1,y1) (x2,y2)用于定义线性渐变的开始位置和结束位置
线性渐变的颜色范围可以由两种或多种颜色组成。每种颜色都用一个 stop 标签(单标签)来指定,一般需要定义两个属性。offset 属性用于定义渐变颜色的开始和结束位置(属性值是一个描述相对位置的百分比)
stop-color 属性用于定义渐变的颜色,值为任何一个合法的颜色值。
<svg wiath= "400" height="150">
<defs>
<linearGradient x1="0%" y1="0%" X2="100%" y2="0%" id="grad1">
<stop offset="0%" stop-color="rgb(255,255,0)" />
<stop offset="100%” stop-color="rgb(255,0,0)" />
</linearGradient>
</defs>
<ellipse cx="200” cy="70” rx="85” ry="55" fill="url(#grad1)" />
</svg>
如何将水平线性渐变调整为垂直线性渐变?
2️⃣经向渐变
cx、cy 和 r 属性定义了最外面的圆,fx 和 fy 属性 定义了最里面的圆,径向渐变的颜色范围可以由两种或多种颜色组成。和线性渐变一样,每种颜色都用一个 stop 标签来指定。
<svg wiath= "400" height="150">
<defs>
<radialGradient cx="50%" cy="50%" r="50%" fx="50%" fy="50" id="grad2">
<stop offset="0%" stop-color="rgb(255,255,255)" />
<stop offset="100%” stop-color="rgb(0,0,255)" />
</radialGradient>
</defs>
<ellipse cx="200” cy="70” rx="85” ry="55" fill="url(#grad2)" />
</svg>
我们可以改变高光的位置吗?
总结:
- SVG 的全称是可缩放矢量图形(Scalable Vector Graphics),它使用矢量图形描述图像和图形,而不是基于像素的位图。
- SVG 图形可以无限放大或缩小且不会失真,这使它成为在不同设备和分辨率下呈现高质量图形的理想选择。
- SVG 图形由路径、形状、文本、颜色、样式等元素组成,开发者可以通过文本编辑器或专业的图形编辑软件创建和编辑 SVG 图形。
- 在 Web 开发中,SVG 图形通常以 .svg 文件扩展名存储,并通过 <img> 标签或 CSS background-image 属性来在页面中显示。
- SVG 图形支持交互效果和动画,并可以使用 JavaScript 来实现事件处理和动态效果。
- SVG 图形也支持可访问性,开发者可以为网页添加更好的可访问性,帮助屏幕阅读器和残障用户更好地理解页面内容。
- SVG 图形具有高度的自由度和可定制性,开发者可以通过群组(<g>)、样式表、JavaScript 等方式来创建自定义的 SVG 图形。
因此SVG 是一种非常有用、灵活和通用的矢量图形格式,在 Web 开发中具有广泛的应用。开发者可以通过掌握 SVG,实现更好的用户体验、提高图形设计能力、增强表现能力,并为多种设备和分辨率呈现高质量的可缩放图形。
补充:canvas和SVG 区别
1️⃣SVG 是矢量图
- 基于XML描述的2D图形语言
- 用JS进行处理
- 每个图形都是对象,属性发生变化,浏览器可以自动加载
特点:
- 不依赖与分辨率
- 支持事件处理
- 适合带有大型渲染区域的应用程序,比如 谷歌地图了(过度使用会影响分辨率)
- 不适合游戏应用
2️⃣canvas 位图
- 逐像素渲染的 ,适合游戏
- 基于JS绘制2D图像
- 在canvas中,图形是被绘制完成,如果位置发生变化,整个场景都会发生变化
特点:
- 依赖于分辨率
- 不支持事件处理
- 文本渲染能力比较弱
- 可以存储成 JPG 或 PNG 的格式
- 适合图像密集型游戏(位置变化,场景重绘)