基本概念和使用
SVG 意为可缩放矢量图形(Scalable Vector Graphics),它是一种用于描述二维矢量图形的 XML 标记语言。与传统的栅格图像不同,SVG 图像可以无限缩放而不会失真,同时也支持交互和动画等特性。
SVG 代码写在根元素 <svg>
标签中,表示图形容器的大小和属性。其中,width 和 height 属性指定画布的宽度和高度,viewBox 属性指定可视范围的位置和大小。
SVG 的优点和缺点
- 优点:
- 矢量图形缩放不会失真(像素点数量不变而导致图像出现模糊、锯齿等),而光栅图形(PNG、JPG)缩放会导致失真。
1.矢量图形
:基于矢量的点、线、形状和数学公式来构建的图形,该图形是没有像素的,放大缩小不会失真。
2.光栅图形
:由像素点构建的图像—微小的彩色方块,大量像素点可以形成高清图像,比如照片。图像像素越多,质量越高。 - 其他优点:灵活(JS 和 CSS 操作);支持动画;轻量(尺寸小);可打印(不会失真);利于 SEO(会被搜索引擎索引);可压缩;易于编辑等。
- 缺点:
- 不适合高清图片制作(非像素级渲染);
- SVG 图像变得复杂时,加载会比较慢;
- 存在部分浏览器兼容问题。
SVG 的应用场景
- SVG 非常适合显示矢量徽标(Logo)、图标(ICON)和其他几何设计。
- SVG 适合应用在需适配多种尺寸的屏幕上展示,因为SVG的扩展性更好。
- 当需要创建简单的动画时,SVG 是一种理想的格式。
1. SVG 可以与 JS 交互来制作线条动画、过渡和其他复杂的动画。
2. SVG 可以与 CSS 动画交互,也可以使用自己内置的 SMIL 动画。 - SVG 也非常适合制作各种图表(条形图、折线图、饼图、散点图等等),以及大屏可视化页面开发。
标签属性:
1. svg标签属性
height
| width
| style
高 | 宽 | 定义css属性
viewBox
可视范围
version
定义所使用的 SVG 版本
xmlns
定义 SVG 命名空间
2. circle、ellipse标签属性
cx、cy
圆心坐标
r
半径
rx、ry
垂直半径(椭圆)
fill
| fill-opacity
| fill-rule
填充色 | 填充透明度 | 图形填充规则
stroke-width
| stroke
| stroke-opacity
边框宽 | 边框颜色 | 边框颜色透明度
3. line标签属性
x1、y1
| x2、y2
直线起点坐标 | 直线终点坐标
4. rect标签绘制矩形
x、y
矩形的宽度和高度
5. polyline标签绘制折线
points
指定每个端点的坐标,横、纵坐标之间与逗号分隔,点与点之间用空格分隔。
6. path标签绘制路径
d
表示绘制顺序,值为一个长字符串,每个字母表示一个绘制动作,后面跟着坐标
M
移动到(moveto)
L
画直线到(lineto)
Z
闭合路径
例:<path d=" M 18,3 L 46,3 L 46,40 Z "></path>
7. text标签绘制文本
x、y
表示文本区块基线(baseline)起点的横坐标和纵坐标。文字的样式可以用class或style属性指定
8. 更多属性
id
用于引用这个模式的唯一ID,必需
xlink:href
指定所要复制的节点
stroke-linecap
定义不同类型的开放路径的终结(线段两个端点的形状)
stroke-dasharray
绘制虚线,短横线长度,空白长度…
svg 坐标系和单位
坐标系是以左上角为 (0,0) 坐标原点,坐标以像素为单位,x 轴正方向是向右,y 轴正方向是向下。
SVG 坐标系统,分为视口坐标系和用户坐标系,默认以像素为单位,也可以手动指明坐标系的单位。
-
视口坐标系(视口-viewport)
:视口坐标系是在视口上建立的坐标系,原点在视口左上角的点(0, 0),x轴正向向右,y轴正向下。 -
用户坐标系(视图框-viewBox)
:用户坐标系是建立在 SVG 视口上的坐标系。该坐标系最初与视口坐标系相同——它的原点位于视口的左上角。使用 viewBox 属性,可以修改初始用户坐标系,使其不再与视口坐标系相同。
svg 的 viewBox和width、height
viewBox(左上角横坐标,左上角纵坐标,视口宽度,视口高度):决定可视范围
- 可以将
viewBox
理解为svg画布
大小。如果画布变大,里面的形状就显得小;如果画布变小,就有可能将里面的形状裁切。 - svg 的
width
、height
属性设置的是svg
这个 html元素 的大小。因为 svg 是矢量图形,所以 svg 的viewBox
,包括viewBox
中的内容会等比缩放,但并不会变形。当然,width
、height
要和viewBox
等比例,否则会出现裁切。 - css 中的
width
、height
会覆盖 svg 标签本身的width
、height
属性,也就是 css 的宽高具有更高的优先级。
在制作svg图形时,可以任意定义viewBox
大小,并在其中放置各种形状,这些形状(包括文字等)的定位都相对viewBox
。而svg实际应用后的大小,取决于width
、height
属性,或者css
样式。
svg 预定义元素
常见的 SVG 形状:矩形(rect)、圆形(circle)、椭圆形(ellipse)、线段(line)、折线(polyline)、多边形(polygon)
常见的 SVG 元素还包括:
- path:路径
- image:图片
- text、tspan:文字
- g 、defs、use、symbols:图形组合和复用
1. <g>
-分组
g 是'group'的简写,它能把多个元素放在一组里,对 g 标记实施的样式和渲染会作用到这个分组内的所有元素上。组内的所有元素都会继承 g 标记上的所有属性。用定义的分组还可以使用 use 进行复制使用。
<svg width="200" height="100" viewBox="0 0 200 100">
<g fill="pink" id="myClip">
<circle cx="30" cy="30" r="20"/>
<circle cx="100" cy="70" r="30"/>
</g>
</svg>
2. <use>
-深度复用
use 标记的作用是能从 SVG 文档内部取出一个节点,克隆它,并把它输出到别处。跟‘引用’很相似,但它是深度克隆。
<svg width="200" height="200" viewBox='0 0 60 60'>
<defs>
<g id="Port">
<circle style="fill:inherit" r="5"/>
</g>
</defs>
<use x="10" y="10" xlink:href="#Port" style="fill:orange" />
<use x="30" y="10" xlink:href="#Port" style="fill:pink"/>
<use x="50" y="10" xlink:href="#Port" style="fill:green"/>
</svg>
3. <defs>
-模板
defs 元素用于预定义一个元素使其能够在 SVG 图像中重复使用,和 g 结合使用。
<svg width="300" height="300" viewport="0 0 300 300">
<defs>
<g id="shape">
<rect x="25" y="50" width="25" height="25" />
<circle fill="pink" cx="25" cy="50" r="25" />
<circle fill="orange" cx="25" cy="50" r="5" />
</g>
</defs>
<use xlink:href="#shape" x="50" y="25" />
<use xlink:href="#shape" x="150" y="25" />
<use xlink:href="#shape" x="50" y="100" />
<use xlink:href="#shape" x="150" y="100" />
</svg>
4. <symbol>
-模板
symbol 标记的作用是定义一个图像模板,相当于 g 和 defs 的结合,可以使用 use 标记实例化它,然后在 SVG 文档中反复使用,这种用法非常的高效。symbol 本身不会输出任何图像,只有使用 use 实例化后才会显示。
<svg viewBox="0 0 150 150" height="300">
<symbol id="sym01" viewBox="0 0 150 110">
<circle cx="50" cy="50" r="40" stroke-width="8" stroke="#2ECC71" fill="#A3E4D7" />
<circle cx="90" cy="60" r="40" stroke-width="8" stroke="pink" fill="white" />
</symbol>
<use xlink:href="#sym01" x="0" y="0" width="100" height="50" />
<use xlink:href="#sym01" x="0" y="50" width="75" height="38" />
<use xlink:href="#sym01" x="0" y="100" width="50" height="25" />
</svg>
5. <clipPath>
裁剪
<svg width="120" height="120" viewPort="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="myClip">
<circle cx="30" cy="30" r="20" />
<circle cx="100" cy="70" r="30" />
</clipPath>
</defs>
<rect x="10" y="10" width="100" height="100" clip-path="url(#myClip)" fill="pink" />
</svg>
6. <text>
定义文本
<svg width="200" height="400">
<!-- y 设置为 0 是看不到的 -->
<text x="10" y="5" fill="green">hello world !</text>
<text x="10" y="25" fill="blue">hello world !</text>
<!-- 旋转文本 -->
<text x="0" y="50" fill="red" transform="rotate(30 20,40)">hello world !</text>
<!-- 文本组 -->
<text x="10" y="105" style="fill:red;">文本组:
<tspan x="10" y="125">第一行文字。</tspan>
<tspan x="10" y="145">第二行文字。</tspan>
</text>
<!-- 加超链接 -->
<a xlink:href="https://blog.csdn.net/fuhanghang/article/details/105200772" target="_blank">
<text x="10" y="170" fill="orange">超链接 !</text>
</a>
<!-- 按路径渲染文本 -->
<defs>
<path id="path1" d="M10,190 a1,1 0 0,0 100,0" />
</defs>
<text x="10" y="185" style="fill:red;">
<textPath xlink:href="#path1">I love SVG I love SVG</textPath>
</text>
<!-- x 的值定义距离上一个文本的 x 的绝对距离,dx 定义相对距离 -->
<text x="10 30 50" dx="-10 0 20" y="280 300 280" fill="red">hello world !</text>
<!-- letter-spacing, 定义每一个文本的距离 -->
<text x="10" y="330" letter-spacing="10" fill="red">hello world !</text>
<!-- text-anchor, 定义文本相对于 x 坐标的处理方法 -->
<text x="100" y="360" text-anchor="middle" fill="red">hello world !</text>
<text x="100" y="390" text-anchor="end" fill="red">hello world !</text>
</svg>
svg 渐变
css 样式优先级为:内联的 style > defs 中的 style > 外部 / head 内部 > 属性 fill
SVG中有两种主要的渐变类型:线性渐变和径向渐变。 学习地址:zhuanlan.zhihu.com/p/590107236
1. 线性渐变
线性渐变用 linearGradient
元素来定义,它必须嵌套在 defs 标签中,可以实现水平渐变、垂直渐变或角度渐变。
它有两组坐标属性:x1, y1, x2, y2,用于定义线性渐变的开始位置和结束位置。
- 当 y1 和 y2 相等,而 x1 和 x2 不等时,就会产生水平渐变。
- 当 x1 和 x2 相等,而 y1 和 y2 不等时,就会产生垂直渐变。
- 当 x1 和 x2 不等,y1 和 y2 也不等时,就会产生角度渐变。
线性渐变的颜色范围可以由两种或多种颜色组成。每种颜色都用一个 stop
标签来指定,一般需要定义两个属性:
- offset 属性,用于定义渐变颜色的开始和结束位置,属性值是一个描述相对位置的百分比。 (10%)
- stop-color 属性,用于定义渐变的颜色,取值为任何一个合法的颜色值。
<svg width="400" height="150">
<defs>
<!-- 定义渐变的效果 -->
<linearGradient x1="0%" y1="0%" x2="100%" y2="0%" id="gradient1">
<stop offset="0%" stop-color="rgb(255,255,0)"></stop>
<stop offset="100%" stop-color=" rgb(255,0,0)"></stop>
</linearGradient>
</defs>
<!-- 绘制椭圆形 -->
<ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#gradient1)"></ellipse>
<!-- 添加文本 -->
<text x="150" y="86" fill="#fff" font-size="45">SVG</text>
</svg>
2. 径向渐变
径向渐变应用 radialGradient
元素来定义,也必须嵌套在 defs 标签中。
有几个重要的属性:
- id 属性,定义了渐变的唯一名称。
- cx、cy 和 r 属性,定义了最外面的圆。fx 和 fy 属性,定义了最里面的圆。
- 径向渐变的颜色范围可以由两种或多种颜色组成,和线性渐变一样。
<svg width="400" height="150" style="background-color: #f2f3f4">
<defs>
<radialGradient cx="50%" cy="50%" r="50%" fx="50%" fy="50%" id="gradient2">
<stop offset="0%" stop-color="rgb(255,255,255)"></stop>
<stop offset="100%" stop-color="rgb(0,0,255)"></stop>
</radialGradient>
</defs>
<ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#gradient2)"></ellipse>
<text x="150" y="86" fill="#fff" font-size="45">SVG</text>
</svg>
PS: 修改 radialGradient 标签的 cx,cy,fx,fy 的值,可以调整高光的位置。比如全部修改为30%,高光的位置会移动到左上角。
学习地址:
blog.csdn.net/IAIPython/a…
blog.csdn.net/fuhanghang/…
blog.csdn.net/qq_45801837…
zhuanlan.zhihu.com/p/590107236