1. SVG 邂逅
1.1 什么是 SVG ?
什么是SVG?维基百科介绍:
- SVG 全称为(Scalable Vector Graphics),即可缩放矢量图形。(矢量定义:既有大小又有方向的量。在物理学中称作矢量,如一个带箭头线段:长度表示大小,箭头表示方向;在数学中称作向量。在计算机中,矢量图可无限放大而不变形)
- SVG 是一种基于XML格式的矢量图,主要用于定义二维图形,支持交互和动画。
- SVG 规范是万维网联盟(W3C) 自 1998 年以来开发的标准。
- SVG 图像可在不损失质量的情况下按比例缩放,并支持压缩。
- 基于XML的SVG可轻松的用文本编辑器或矢量图形编辑器创建和编辑,并可以直接在浏览器显示。
1.2 SVG 的历史
SVG1.x 版本
- SVG 是 W3C SVG工作组于 1998 年开始开发 ,而 SVG 1.0于 2001 年 9 月 4 日成为W3C 推荐的标准。
- SVG 1.1 于 2003 年 1 月 14 日成为 W3C 推荐的标准。 该版本增加了模块化规范的内容。除此之外,1.1 和 1.0 几乎没有区别。
- SVG Tiny 1.2 于 2008 年 12 月 22 日成为 W3C 推荐标准,主要是为性能低的小设备生成图形,但是后来被 SVG 2 所弃用了。
- SVG 1.1 第二版 于 2011 年 8 月 16 日发布,这次只是更新了勘误表和说明,并没有增加新功能 。
SVG 2.0 版本(推荐)
- SVG 2.0于2016 年 9 月 15 日成为W3C 候选推荐标准,最新草案于2020年5月26日发布。
1.3 SVG 的优缺点
优点:
- 扩展好:矢量图像在浏览器中放大缩小不会失真,可被许多设备和浏览器中使用。而光栅图像(PNG 、JPG)放大缩小会失真。
- 矢量图像是基于矢量的点、线、形状和数学公式来构建的图形,该图形是没有像素的,放大缩小是不会失真的。
- 光栅图像是由像素点构建的图像——微小的彩色方块,大量像素点可以形成高清图像,比如照片。图像像素越多,质量越高。
- 灵活:SVG是W3C开发的标准,可结合其它的语言和技术一起使用,包括 CSS、JavaScript、 HTML 和 SMIL 。SVG图像可以
直接使用JS和CSS进行操作,使用时非常方便和灵活,因为SVG也是可集成到 DOM 中的。
3、 可以动画:SVG 图像可以使用 JS 、 CSS 和 SMIL 进行动画处理。对于 Web 开发人员来说非常的友好。
- 轻量级:与其它格式相比,SVG 图像的尺寸非常小。根据图像的不同,PNG 图像质量可能是 SVG 图像的 50 倍。
- 可打印:SVG 图像可以以任何分辨率打印,而不会损失图像质量。
- 利于SEO:SVG 图像被搜索引擎索引。因此,SVG 图像非常适合 SEO(搜索引擎优化)目的。
- 可压缩:与其它图像格式一样,SVG 文件支持压缩。
- 易于编辑:只需一个文本编辑器就可以创建 SVG 图像。设计师通常会使用 Adobe Illustrator (AI)等矢量图形工具创建和编辑。
缺点:
不适和高清图片制作
- SVG 格式非常适合用于徽标和图标(ICON)等 2D 图形,但不适用于高清图片,不适合进行像素级操作。
- SVG 的图像无法显示与标准图像格式一样多的细节,因为它们是使用点和路径而不是像素来渲染的。
- SVG 图像变得复杂时,加载会比较慢
不完全扩平台
- 尽管 SVG 自 1998 年以来就已经存在,并得到了大多数现代浏览器(桌面和移动设备)的支持,但它不适用于 IE8 及更低版本的旧版浏览器。根据caniuse的数据,大约还有 5% 的用户在使用不支持 SVG 的浏览器。
1.4 应用场景
- SVG 非常适合显示矢量徽标(Logo)、图标(ICON)和其他几何设计。
- SVG 适合应用在需适配多种尺寸的屏幕上展示,因为SVG的扩展性更好。
- 当需要创建简单的动画时,SVG 是一种理想的格式。
- SVG 可以与 JS 交互来制作线条动画、过渡和其他复杂的动画。
- SVG 可以与 CSS 动画交互,也可以使用自己内置的 SMIL 动画。
- SVG 也非常适合制作各种图表(条形图、折线图、饼图、散点图等等),以及大屏可视化页面开发。
1.5 SVG 和 Canvas 的区别
可扩展性:
- SVG 是基于矢量的点、线、形状和数学公式来构建的图形,该图形是没有像素的,放大缩小不会失真。
- Canvas 是由一个个像素点构成的图形,放大会使图形变得颗粒状和像素化(模糊)。
- SVG可以在任何分辨率下以高质量的打印。Canvas 不适合在任意分辨率下打印。
渲染能力:
- 当 SVG 很复杂时,它的渲染就会变得很慢,因为在很大程度上去使用 DOM 时,渲染会变得很慢。
- Canvas 提供了高性能的渲染和更快的图形处理能力,例如:适合制作H5小游戏。
- 当图像中具有大量元素时,SVG 文件的大小会增长得更快(导致DOM变得复杂),而Canvas并不会增加太多。
灵活度:
- SVG 可以通过JavaScript 和 CSS 进行修改,用SVG来创建动画和制作特效非常方便。
- Canvas只能通过JavaScript进行修改,创建动画得一帧帧重绘。
使用场景:
- Canvas 主要用于游戏开发、绘制图形、复杂照片的合成,以及对图片进行像素级别的操作,如:取色器、复古照片。
- SVG 非常适合显示矢量徽标(Logo)、图标(ICON)和其他几何设计。
1.6 一份 SVG 代码
<?xml version="1.0" standalone="no" ?>
<svg
width="100"
height="100"
xmlns="http://www.w3.org/2000/svg"
>
<rect x="0" y="0" width="100" height="100"></rect>
</svg>
2. SVG 基础
2.1 SVG Grid 和 坐标系
SVG 使用的 坐标系统(网格系统) 和 Canvas的差不多。坐标系是 以左上角为 (0,0) 坐标原点,坐标以像素为单位,x 轴正方向是向右,y 轴正方向是向下。
SVG Grid(坐标系)
<svg>
元素默认宽为 300px, 高为 150px。- 通常来说网格中的一个单元相当于 svg 元素中的一像素。
- 基本上在 SVG 文档中的 1 个像素对应输出设备(比如显示屏)上的 1 个像素(除非缩放)。
<svg>
元素和其它元素一样也是有一个坐标空间的,其原点位于元素的左上角,被称为初始视口坐标系<svg>
的 transform 属性可以用来移动、旋转、缩放SVG中的某个元素,如<svg>
中某个元素用了变形,该元素内部会建立一个新的坐标系统,该元素默认后续所有变化都是基于新创建的坐标系统。
2.2 SVG 坐标系单位
SVG坐标系统,在没有明确指定单位时,默认以像素为单位。
比如:<rect x="0" y="0" width="100" height="100" />
- 定义一个矩形,即从左上角开始,向右延展 100px,向下延展 100px,形成一个 100*100 大的矩形。
当然我们也可以手动指明坐标系的单位,比如:
2.3 视口-viewport
视口(viewport)
- 视口是 SVG 可见的区域(也可以说是SVG画布大小)。可以将视口视为可看到特定场景的窗口。
- 可以使用
<svg>
元素的width和height属性指定视口的大小。 - 一旦设置了最外层 SVG 元素的宽度和高度,浏览器就会建立初始视口坐标系和初始用户坐标系。
视口坐标系
- 视口坐标系是在视口上建立的坐标系,原点在视口左上角的点(0, 0),x轴正向向右,y轴正向下。
- 初始视口坐标系中的一个单位等于视口中的一个像素,该坐标系类似于 HTML 元素的坐标系。
用户坐标系( 也称为当前坐标系或正在使用的用户空间,后面绘图都是参照该坐标系 )
- 用户坐标系是建立在 SVG 视口上的坐标系。该坐标系最初与视口坐标系相同——它的原点位于视口的左上角。
- 使用viewBox属性,可以修改初始用户坐标系,使其不再与视口坐标系相同。
为什么要有两个坐标系?
- 因为SVG是矢量图,支持任意缩放。在用户坐标系统绘制的图形,最终会参照视口坐标系来进行等比例缩放。
2.4 视图框-viewBox
视图框(viewBox)
- viewport是 SVG 画布的大小,而 viewBox 是用来定义用户坐标系中的位置和尺寸 (该区域通常会被缩放填充视口)。
- viewBox 也可理解为是用来指定用户坐标系大小。因为SVG的图形都是绘制到该区域中。用户坐标系可以比视口坐标系更小或更大,也可以在
视口内完全或部分可见。
- 一旦创建了视口坐标系(
<svg>
使用width和height),浏览器就会创建一个与其相同的默认用户坐标系。 - 我们可以使用 viewBox 属性指定用户坐标系的大小。
✓ 如果用户坐标系与视口坐标系具有相同的高宽比,它将viewBox区域拉伸以填充视口区域。
✓ 如果用户坐标系和视口坐标系没有相同的宽高比,可用 preserveAspectRatio 属性来指定整个用户坐标系统是否在视口内可见。
viewBox语法
viewBox =
<min-x>
<min-y>
<width>
<height>
,比如:viewBox =' 0 0 100 100'<min-x>
和<min-y>
确定视图框的左上角坐标(不是修改用户坐标系的原点,绘图还是从原来的 0, 0 开始)<width>
<height>
确定该视图框的宽度和高度。
➢ 宽度和高度不必与父
<svg>
元素上设置的宽度和高度相同。
➢ 宽度和高度负值无效,为 0 是禁用元素的显示。
- viewport和viewBox有相同的宽高比
<svg width="400" height="400" viewBox="0 0 100 100" >
<circle cx="50" cy="50" r="50"></circle>
</svg>
- viewport和viewBox有相同的宽高比-指定viewBox最小的x和y
<svg width="400" height="400" viewBox="50 50 100 100" >
<circle cx="50" cy="50" r="50"></circle>
</svg>
- viewport和viewBox不同的宽高比
<svg width="400" height="400"
viewBox="0 0 200 100"
preserveAspectRatio="xMinYMin"
>
<circle cx="50" cy="50" r="50"></circle>
</svg>
关于viewBox属性,可以参考这篇文章,非常容易理解如何理解SVG中的viewport、viewBox和preserveAspectRatio
2.5 绘制基本图形
- 矩形 rect
<rect>
元素6 个基本属性 x
y
width
height
rx
ry
- x :矩形左上角的 x 轴位置
- y :矩形左上角的 y轴位置
- width :矩形的宽度
- height :矩形的高度
- rx :圆角的 x 轴方位的半径
- ry :圆角的 y 轴方位的半径 。
<rect x="60" y="10" rx="10" ry="10" width="30" height="30"></rect>
- 圆形 circle
<circle>
元素3 个基本属性。 r
cx
cy
- r:圆的半径
- cx:圆心的 x 轴位置
- cy:圆心的 y 轴位置
<circle cx="100" cy="100" r="50" fill="red"></circle>
- 椭圆 ellipse
<ellipse>
元素4 个基本属性 rx
ry
cx
cy
- rx:椭圆的 x轴半径
- ry:椭圆的 y轴半径
- cx:椭圆中心的 x轴位置
- cy:椭圆中心的 y轴位置
<ellipse cx="100" cy="100" rx="25" ry="50" fill="red"></ellipse>
- 线条 line
<line>
元素4 个基本属性
- x1:起点的 x 轴位置
- y1:起点的 y轴位置
- x2:终点的 x轴位置
- y2:终点的 y轴位置
<!-- stroke , 而不是 fill -->
<line x1="100" y1="100" x2="200" y2="100" stroke="red" stroke-width="5"></line>
- 折线 polyline
<polyline>
元素1 个基本属性
- points : 点集数列。每个数字用空白、逗号、终止命令符或者换行符分隔开。
- 每个点必须包含 2 个数字,一个是 x 坐标,一个是 y 坐标。
- 所以点列表 (0,0), (1,1) 和 (2,2) 可以写成这样:“0 0, 1 1, 2 2”。
✓ 支持格式: “0 0, 1 1, 2 2”或 “0 ,0 , 1, 1, 2, 2”或 “0 0 1 1 2 2”
<!-- 第1种写法 -->
<!-- <polyline points="20 0, 80 50, 20, 100"></polyline> -->
<polyline
points="20 0, 80 50, 20, 100"
fill="transparent"
stroke="red"
></polyline>
<!-- 第2种写法 -->
<polyline points="20 0 80 50 20 100"></polyline>
<!-- 第3种写法 -->
<polyline points="20 ,0 ,80 ,50 ,20, 100"></polyline>
- 多边形 polygon
<polygon>
元素1 个基本属性
- points :点集数列。每个数字用空白符、逗号、终止命令或者换行符分隔开。
- 每个点必须包含 2 个数字,一个是 x 坐标,一个是 y 坐标。
- 所以点列表 (0,0), (1,1) 和 (2,2) 推荐写成这样:“0 0, 1 1, 2 2”。
- 路径绘制完后闭合图形,所以最终的直线将从位置 (2,2) 连接到位置 (0,0)。
<polygon points="20 0, 80 50, 20 100" fill="transparent" stroke="red"></polygon>
- 路径 path
<path>
元素1 个基本属性
- d :一个点集数列,以及其它关于如何绘制路径的信息,必须M命令开头。
✓ 所以点列表 (0,0), (1,1) 和 (2,2) 推荐写成这样:“M 0 0, 1 1, 2 2”。
✓ 支持格式: “M 0 0, 1 1, 2 2”或 “M0 0, 1 1, 2 2” 或 “M 0 ,0 , 1, 1, 2, 2”或 “M 0 0 1 1 2 2”
<!-- 1.使用path 绘制一个三角形 -->
<!-- <path d="M 20 0, 80 50, 20 100" fill="transparent" stroke="red"></path> -->
<!-- 1.使用path 绘制一个闭合的三角形 -->
<!-- <path d="M 20 0, 80 50, 20 100 Z" fill="transparent" stroke="red"></path> -->
<!-- 1.使用 path 绘图的命令:
M moveTo
Z close path
L lineTo
-->
<path d="M 20 0,L 80 50,L 20 100 Z" fill="transparent" stroke="red"></path>
上面的 M
Z
L
都是一条命令表示 移动到某处
关闭路径
以及 连线到某处
,还有很多其他的命令,这里不讲了,遇到去查即可。
- 图片 image
在SVG中绘制一张图片,在<image>
元素的 href 属性引入图片URL
<!-- svg 1.0版本的语法 -->
<svg
version="1.0"
baseProfile="full"
width="300" height="300"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<image
x="0"
y="0"
xlink:href="../images/googlelogo_color_92x30dp.png"
width="100"
height="100"
>
</image>
</svg>
<!-- svg 2.0 + 1.0 版本的语法( 为了兼容以前的浏览器的写法 ) -->
<svg
version="1.0"
baseProfile="full"
width="300" height="300"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<image
x="0"
y="0"
xlink:href="../images/googlelogo_color_92x30dp.png"
href="../images/googlelogo_color_92x30dp.png"
width="100"
height="100"
>
</image>
</svg>
- 绘制文字 text
<text>
元素的基本属性
- x 和 y 属性决定了文本在用户坐标系中显示的位置。
- text-anchor 文本流方向属性,可以有 start、middle、end 或 inherit 值,默认值 start
- dominant-baseline 基线对齐属性 : 有 auto 、middle 或 hanging 值, 默认值:auto
<text>
元素的字体属性
- 文本的一个至关重要的部分是它显示的字体。SVG 提供了一些属性,类似于CSS 。下列的属性可以被设置为一个 SVG 属性或一个 CSS 属性:
✓ font-family、font-style、font-weight、font-variant、font-stretch、font-size、font-size-adjust、kerning、letter-spacing、word-spacing和textdecoration。
其它文本相关的元素:
<tspan>
元素用来标记大块文本的子部分,它必须是一个text元素或别的tspan元素的子元素。
✓ x 和 y 属性决定了文本在视口坐标系中显示的位置。
✓ alignment-baseline 基线对齐属性:auto 、baseline、middle、hanging、top、bottom ... ,默认是 auto
<!-- 1.在svg中绘制一个文字 -->
<!-- <text x="100" y="100" font-size="50" fill="red">Ay</text> -->
<!-- 2.文本的对齐方式 -->
<!-- <text x="100" y="100" text-anchor="middle" font-size="50" fill="red">Ay</text> -->
<!-- 3.基线对齐方式 :
有 auto 、middle 或 hanging 值, 默认值:auto
-->
<text x="100" y="100" dominant-baseline="middle" font-size="50" fill="red">Ay</text>
<!-- 4.在svg中使用tspan绘制一个文字 -->
<text x="40" y="100" font-size="20">
iPhone14
<tspan fill="red">¥100</tspan>
</text>
2.6 SVG 的组合和复用
1. 元素的组合 g
<g>
元素的属性(该元素只包含全局属性)
- 核心属性:id
- 样式属性:class 、style
- Presentation Attributes(也可说是 CSS 属性,这些属性可写在CSS中,也可作为元素的属性用):
✓ cursor, display, fill, fill-opacity, opacity,…
✓ stroke, stroke-dasharray, stroke-dashoffset, stroke-linecap, stroke-linejoin
✓ 更多表示属性:https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation
- 事件属性:onchange, onclick, ondblclick, ondrag…
- 动画属性:transform
- 更多:https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g
<!-- <circle cx="50" cy="50" r="25" fill="transparent" stroke="red"></circle>
<circle cx="80" cy="50" r="25" fill="transparent" stroke="red"></circle>
<circle cx="110" cy="50" r="25" fill="transparent" stroke="red"></circle>
<circle cx="140" cy="50" r="25" fill="transparent" stroke="red"></circle> -->
<!--
g 元素没有专有的属性,只有全局的属性
全局属性:id class style fill stroke onclick
-->
<g fill="transparent" stroke="red">
<circle cx="50" cy="50" r="25"></circle>
<circle cx="80" cy="50" r="25"></circle>
<circle cx="110" cy="50" r="25"></circle>
<circle cx="140" cy="50" r="25"></circle>
</g>
2. 元素的复用和引入 defs
和 use
<defs>
元素,定义可复用元素。
- 例如:定义基本图形、组合图形、渐变、滤镜、样式等等。
- 在
< defs >
元素中定义的图形元素是不会直接显示的。 - 可在视口任意地方用
<use>
来呈现在defs中定义的元素。 <defs>
元素没有专有属性,使用时通常也不需添加任何属性。
<use>
元素的属性
- href: 需要复制元素/片段的 URL 或 ID(支持跨SVG引用)。默认值:无
- xlink:href:(SVG2.0已弃用)需要复制的元素/片段的 URL 或 ID 。默认值:无
- x / y :元素的 x / y 坐标(相对复制元素的位置)。 默认值:0
- width / height :元素的宽和高(在引入svg或symbol元素才起作用)。 默认值:0
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- 0.样式 -->
<style>
rect{
fill: green;
}
</style>
<!-- 1.定义了一个矩形 -->
<rect id="rectangle" x="0" y="0" width="100" height="50"></rect>
<!-- 2.定义了一个组合图形 -->
<g id="logo" fill="transparent" stroke="red">
<circle cx="50" cy="50" r="25"></circle>
<circle cx="80" cy="50" r="25"></circle>
<circle cx="110" cy="50" r="25"></circle>
<circle cx="140" cy="50" r="25"></circle>
</g>
<!-- 定义渐变 -->
<!-- 滤镜 -->
</defs>
<!-- 在这里进行图形的复用 -->
<!-- <use href="#rectangle"></use> -->
<!-- <use x="100" y="100" href="#rectangle"></use> -->
<!-- <use href="#logo"></use> -->
<!-- <use x="100" y="100" href="#logo"></use> -->
</svg>
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" >
<!--
他的宽和高是没有生效的 ???? 只用use引用的图形是 svg 或 symbol 才会起作用
-->
<use href="#rectangle" width="200" height="100" ></use>
</svg>
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" >
<use href="#logo"></use>
</svg>
- 图形元素复用 symbols
<symbol>
元素和 <defs>
元素类似,也是用于定义可复用元素,然后通过 <use>
元素来引用显示。
- 在
<symbol>
元素中定义的图形元素默认也是不会显示在界面上。 <symbol>
元素常见的应用场景是用来定义各种小图标,比如:icon、logo、徽章等
<symbol>
元素的属性
- viewBox:定义当前
<symbol>
的视图框。 - x / y :symbol元素的 x / y坐标。 ;默认值:0
- width / height:symbol元素的宽度。 默认值:0
<symbol>
和<defs>
的区别
<defs>
元素没有专有属性,而<symbol>
元素提供了更多的属性
✓ 比如: viewBox、 preserveAspectRatio 、x、y、width、height等。
<symbol>
元素有自己用户坐标系,可以用于制作SVG精灵图。<symbol>
元素定义的图形增加了结构和语义性,提高文档的可访问性。
SVG ICON文件-合并成SVG精灵图:https://www.zhangxinxu.com/sp/svgo
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" >
<!-- 1.ICON previous-->
<symbol id="previous" viewBox="0 0 100 100">
<path fill="currentColor" d="M 80 0,L 20 50, L 80 100 Z"></path>
</symbol>
<!-- 2.ICON next -->
<symbol id="next" viewBox="0 0 100 100">
<polygon points="20 0, 80 50, 20 100"></polygon>
</symbol>
<!-- 复用 -->
<!-- <use href="#previous" width="100" height="100"></use> -->
</svg>
<!-- 复用 -->
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" >
<!-- 直接在use上指定ICON的 width和 hegiht -->
<use href="#previous" width="50" height="50"></use>
</svg>
<!-- 这个属于缩小 -->
<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg" >
<use href="#previous" ></use>
</svg>
<!-- 属于放大 -->
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" >
<use href="#previous" ></use>
</svg>
3. SVG 高级
3.1 填充和描边
如果想要给SVG中的元素上色,一般有两种方案可以实现:
- 第一种:直接使用元素的属性,比如:填充(fill)属性、描边(stroke)属性等。
<rect x="10" y="10" width="100" height="100" fill="currentColor" fill-opacity="0.4"></rect>
<rect x="10" y="10" width="100" height="100"
fill="transparent"
stroke="red"
stroke-width="3"
stroke-opacity="1"
></rect>
- 第二种:直接编写CSS样式,因为SVG也是HTML中的元素,也支持用CSS的方式来编写样式。
直接编写CSS样式实现填充和描边
- 除了定义元素的属性外,你也可以通过CSS来实现填充和描边(CSS样式可写在defs中,也可写在HTML头部或外部等)。
- 语法和 HTML 里使用 CSS 一样,需要注意的是:需要把 background-color、border 改成 fill 和 stroke
- 不是所有的属性都能用 CSS 来设置,上色和填充的部分是可以用 CSS 来设置。
✓ 比如,fill,stroke,stroke-dasharray 等可以用CSS设置;比如,路径的命令则不能用 CSS 设置。
哪些属性可以使用CSS设置,哪些不能呢?
- SVG规范中将属性区分成 Presentation Attributes 和 Attributes 属性。
✓ Presentation Attributes 属性( 支持CSS和元素用 ):https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation
✓ Attributes 属性(只能在元素用): https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute
✓ 提示:这些属性是不需要去记的,用多了就记住了,在忘记时测试一下就知道了。
CSS给SVG中的元素填充、描边和上色,支持如下4种编写方式:
- 方式一:内联(行内) CSS 样式,写在元素的style属性上
- 方式二:内嵌(内部) CSS 样式,写在
<defs>
中的<style>
标签中 - 方式三:内嵌(内部) CSS 样式,写在
<head>
中的<style>
标签中 - 方式四:外部 CSS 样式文件,写在 .css 文件中
CSS样式优先级别:内联的 style
> defs中的style
> 外部 / head内部
> 属性 fill
<!-- 1.行内的样式 -->
<rect x="10" y="10" width="100" height="100"
style="fill:red;"
></rect>
<!-- 2.行内的样式 -->
<defs>
<style>
.rectangle{
fill: green;
stroke: red;
}
</style>
</defs>
<rect class="rectangle" x="10" y="10" width="100" height="100"></rect>
/* 3.行内的样式 */
<style>
.rectangle{
fill: blue;
}
</style>
<rect class="rectangle" x="10" y="10" width="100" height="100"></rect>
/* 4. 引入css文件*/
<link rel="stylesheet" href="./style.css">
<rect class="rectangle" x="10" y="10" width="100" height="100"></rect>
3.2 渐变和滤镜
SVG除了可以简单的填充和描边,还支持在填充和描边上应用渐变色。渐变有两种类型:线性渐变
和 径向渐变
。
- 编写渐变时,必须给渐变内容指定一个 id 属性,use引用需用到。
- 建议渐变内容定义在
<defs>
标签内部,渐变通常是可复用的。
线性渐变,是沿着直线改变颜色。下面看一下线性渐变的使用步骤:
- 第1步:在 SVG 文件的 defs 元素内部,创建一个
<linearGradient>
节点,并添加 id 属性。 - 第2步:在
<linearGradient>
内编写几个<stop>
结点。
✓ 给 <stop>
结点指定位置 offset属性和 颜色stop-color属性,用来指定渐变在特定的位置上应用什么颜色
➢ offset 和 stop-color 这两个属性值,也可以通过 CSS 来指定。
✓ 也可通过 stop-opacity 来设置某个位置的半透明度。
- 第3步:在一个元素的 fill 属性或 stroke 属性中通过ID来引用
<linearGradient>
节点。
✓ 比如:属性fill属性设置为url( #Gradient2 )即可。
- 第4步(可选):控制渐变方向,通过 ( x1, y1 ) 和 ( x2, y2 ) 两个点控制。
✓ (0, 0) (0, 1)从上到下;(0, 0)(1, 0)从左到右。
✓ 当然也可以通过 gradientTransform 属性 设置渐变形变。比如: gradientTransform=“rotate(90)” 从上到下。
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
<!-- 定义可以复用的元素: 样式, 渐变, 图形, 滤镜... -->
<defs>
<!-- 默认的渐变色 -->
<linearGradient id="gradient1">
<stop offset="0%" stop-color="red"></stop>
<stop offset="50%" stop-color="green"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linearGradient>
<!-- 这个是制定渐变的方向 -->
<linearGradient id="gradient2" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="red"></stop>
<stop offset="50%" stop-color="green"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linearGradient>
<!-- 通过形变 渐变色(了解 ) -->
<linearGradient id="gradient3" gradientTransform="rotate(0)">
<stop offset="0%" stop-color="red"></stop>
<stop offset="50%" stop-color="green"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linearGradient>
</defs>
<rect x="0" y="0" width="100" height="50" fill="url(#gradient3)"></rect>
</svg>
在前端开发中,毛玻璃效果有几种方案来实现:
- 方案一:使用CSS的 backdrop-filter 或 filter 属性
- backdrop-filter:可以给一个元素后面区域添加模糊效果。
适用于元素背后的所有元素。为了看到效果,必须使元素或其背景至少部分透明。
- filter:直接将模糊或颜色偏移等模糊效果应用于指定的元素。
- 方案二:使用SVG的 filter 和 feGaussianBlur 元素(建议少用)
<filter>
:元素作为滤镜操作的容器,该元素定义的滤镜效果需要在SVG元素上的 filter 属性引用。
✓ x , y, width, height 定义了在画布上应用此过滤器的矩形区域。x, y 默认值为 -10%(相对自身);width ,height 默认
值为 120% (相对自身) 。
<feGaussianBlur>
:该滤镜专门对输入图像进行高斯模糊
✓ stdDeviation 熟悉指定模糊的程度
<feOffset>
:该滤镜可以对输入图像指定它的偏移量。
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" >
<defs>
<!-- 高斯模糊的 效果 -->
<filter id="blurFilter">
<!-- ...... -->
<feGaussianBlur stdDeviation="8"></feGaussianBlur>
</filter>
</defs>
<image
href="../images/avatar.jpeg"
width="200"
height="200"
filter="url(#blurFilter)"
>
</image>
</svg>
3.3 SVG 形变 transform
transform
属性支持的函数有 translate
rotate
scale
skew
matrix
1. 平移 translate
与 CSS 的 translate 相似但有区别,这里只支持 2D 变换,不需单位。
<rect
x="0"
y="0"
width="100"
height="50"
transform="translate(200, 200)"
></rect>
2. 旋转 rotate
与CSS的rotate相似但有区别。区别是:支持2D变换,不需单位,可指定旋转原点。
<rect
transform="translate(100, 0) rotate(45, 50, 25)"
x="0" y="0" width="100" height="50"
>
</rect>
3. 缩放 scale
与CSS的scale相似但有区别,这只支持2D变换,不需单位。
<rect
transform="translate(100, 100) scale(1, 2)"
x="0"
y="0"
width="100"
height="50"
></rect>
3.4 路径描边动画
stroke
是描边属性,专门给图形描边。如果想给各种描边添加动画效果,需用到下面两个属性:
- stroke-dasharray =“number [, number , ….]”: 将虚线类型应用在描边上。
✓ 该值必须是用逗号分割的数字组成的数列,空格会被忽略。比如 3,5 :
➢ 第一个表示填色区域的长度为 3
➢ 第二个表示非填色区域的长度为 5
- stroke-dashoffset:指定在dasharray模式下路径的偏移量。
✓ 值为number类型,除了可以正值,也可以取负值。
描边动画实现步骤:
- 1.先将描边设置为虚线
- 2.接着将描边偏移到不可见处
- 3.通过动画让描边慢慢变为可见,这样就产生了动画效果了。
<style>
#line1 {
/* 指定为虚线 */
stroke-dasharray: 100px;
/* 可见 */
stroke-dashoffset: 20px;
/* animation: line1Move 2s linear; */
}
@keyframes line1Move {
0% {
/* 不可见 */
stroke-dashoffset: 100px;
}
100% {
/* 可见 */
stroke-dashoffset: 0px;
}
}
</style>
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
<!--
stroke , 而不是 fill
-->
<line
id="line1"
x1="100"
y1="70"
x2="200"
y2="70"
stroke="red"
stroke-width="10"
></line>
</svg>
3.5 SMIL 动画
SMIL(Synchronized Multimedia Integration Language 同步多媒体集成语言)是W3C推荐的可扩展标记语言,用于描述
多媒体演示。
- SMIL 标记是用 XML 编写的,与HTML有相似之处。
- SMIL 允许开发多媒体项目,例如:文本、图像、视频、音频等。
- SMIL 定义了时间、布局、动画、视觉转换和媒体嵌入等标记,比如:
<head>
<body>
<seq>
<par>
<excl>
等元素
SMIL的应用
- 目前最常用的Web浏览器基本都支持 SMIL 语言。
- SVG 动画元素是基于SMIL实现(SVG中使用SMIL实现元素有:
<set>
、<animate>
、<animateMotion>
...)。 - Adobe Media Player implement SMIL playback。
- QuickTime Player implement SMIL playback。
SVG动画实现方式
- 用JS脚本实现:可以直接通过 JavaScript 在来给 SVG 创建动画和开发交互式的用户界面。
- 用CSS样式实现:自 2008 年以来,CSS动画已成为WebKit中的一项功能,使得我们可以通过CSS动画的方式来给文档对象模型(DOM) 中的 SVG 文件编写动态效果。
- 用SMIL实现:一种基于SMIL语言实现的SVG动画。
SMIL动画的优势
- 只需在页面放几个animate元素就可以实现强大的动画效果,无需任何CSS和JS代码。
- SMIL支持声明式动画。声明式动画不需指定如何做某事的细节,而是指定最终结果应该是什么,将实现细节留给客户端软件
- 在 JavaScript 中,动画通常使用 setTimeout() 或 setInterval() 等方法创建,这些方法需要手动管理动画的时间。而SMIL 声明式动画可以让浏览器自动处理,比如:动画轨迹直接与动画对象相关联、物体和运动路径方向、管理动画时间等等。
- SMIL 动画还有一个令人愉快的特点是,动画与对象本身是紧密集成的,对于代码的编写和阅读性都非常好。
SVG 中支持SMIL动画的元素:
<set>
<animate>
<animateColor>
<animateMotion>
- 更多 https://www.w3.org/TR/SVG11/animate.html#AnimationElements
1. set
元素
set元素是最简单的 SVG 动画元素。它是在经过特定时间间隔后,将属性设置为某个值(不是过度动画效果)。因此,图像不是连续动画,而是改变一次属性值。它支持所有属性类型,包括那些无法合理插值的属性类型,例如:字符串 和 布尔值。而对于可以合理插值的属性通常首选<animate>
元素。
常用属性有 attributeName
to
begin
<!-- 1. 在3秒后自动将长方形瞬间移到右边 -->
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" >
<rect x="0" y="0" width="100" height="50" fill="red">
<set
attributeName ='x'
to="200"
begin="3s"
>
</set>
</rect>
</svg>
<!-- 点击长方形后,长方形瞬间移到右边 -->
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" >
<rect id="rectangle" x="0" y="0" width="100" height="50" fill="green">
<set
attributeName ='x'
to="200"
begin="rectangle.click"
>
</set>
</rect>
</svg>
2. animate
元素
常用属性有:attributeName
from
values
begin
dur
fill
repeatCount
<svg width="300" height="200" xmlns="http://www.w3.org/2000/svg" >
<rect x="0" y="0" width="100" height="50" fill="green">
<!--
form: 0
to: 200
-->
<animate
attributeName="x"
values="0; 170; 200"
dur="3s"
repeatCount="indefinite"
>
</animate>
<animate
attributeName="fill"
values="red;green"
dur="3s"
repeatCount="indefinite"
>
</animate>
</rect>
</svg>