svg
起因-最近因为可视化大屏,要做一些线条动画,就边做边学了一下以前不怎么接触的svg,在这也就总结一些svg的知识点
svg是什么,你可以看到svg是一些类似html的一些标签,也叫做xml,可以简单的理解,其实svg是一些标签,你可以给它用css,也可以用js来操作它,所以你也能理解为什么说svg图形是矢量图形,放大不失真,你见过html标签的东西失真的吗
使用
- 是标签嘛,你可以直接在html里面用
- css背景图片的方式
- img标签的方式
还有些其他的,但用的较少
基础
path
我先讲这玩意,这个是svg的灵魂,你看见的所有图形都是通过path描绘出来的
<svg width="300" height="300" style="border: 1px solid red;">
<path
d="M 10 10 50 40 100 10"
stroke="blue"
fill="none"
>
</path>
</svg>
大部分svg标签就是这个样子,里面的path的d属性就是具体描述位置的路径
图上 坐标10,10 到 50,40 到100,10 三个点的连线就是整个图形的大致路径,
但我并不会花大量时间去了解path d里面的具体规则,例如曲线绘制等,因为工作你不可能自己去写path路径,都是通过svg编辑器,画出路径导出来就行了
基础图形
svg自带一些封装好的图形,常见的矩形,圆形等标签,本质上还是path描述出来的,只是封装好了
矩形
<svg width="300" height="300" style="border: 1px solid red;">
<rect width="200" height="100"></rect>
</svg>
圆形
<svg width="300" height="300" style="border: 1px solid red;">
<circle
cx="60"
cy="80"
r="50"
>
</circle>
</svg>
椭圆
<svg width="300" height="300" style="border: 1px solid red;">
<ellipse
cx="100"
cy="40"
rx="80"
ry="30"
>
</ellipse>
</svg>
直线
<svg width="300" height="300" style="border: 1px solid red;">
<line
x1="30"
y1="40"
x2="200"
y2="180"
stroke="blue"
>
</line>
</svg>
折线
<svg width="300" height="300" style="border: 1px solid red;">
<polyline
points="10 10, 200 80, 230 230"
stroke="#000"
fill="none"
>
</polyline>
</svg>
多边形
<svg width="300" height="300" style="border: 1px solid red;">
<polygon points="10 10, 200 80, 230 230"></polygon>
</svg>
文本图形
<svg width="400" height="400" style="border: 1px solid red;">
<text
y="60"
font-size="60"
font-weight="normal"
>
雷猴啊
</text>
</svg>
还有其他的a标签啊 image标签啊 跟html用法差不多
特殊的标签
defs 封装图形
SVG 允许我们定义以后需要重复使用的图形元素。建议把所有需要再次使用的引用元素定义在defs元素里面,你可以在你的视口的任意地方利用 use标签 呈现这些元素
<svg width="80px" height="30px" viewBox="0 0 80 30"
xmlns="http://www.w3.org/2000/svg">
<defs>
<g id="Port">
<circle style="fill:inherit" r="10"/>
</g>
</defs>
<use x="50" y="10" xlink:href="#Port" />
</svg>
<g> 组合
其实是group的缩写,也就是个图形的集合,添加到g元素上的变换会应用到其所有的子元素上。添加到g元素的属性会被其所有的子元素继承,亦可用use来复用,
直接写defs和g有啥区别呢
我理解的是区别不大,但defs的标签不会显示再页面上,相当于一个声明
<g id="browser" stroke="green" fill="white" stroke-width="5">
<rect x="3" y="3" width="80" height="60"></rect>
<line x1="3" y1="19" x2="83" y2="19"></line>
<line x1="20" y1="3" x2="20" y2="17"></line>
</g>
<use href="#browser"></use>
基础属性
<svg width="300" height="300" style="border: 1px solid red;">
<rect x="100" y="100" width="200" height="100" stroke="blue" fill='red'></rect>
</svg>
大部分属性,其实顾名思义就能理解意思
width height 宽高
x y 坐标
fill 填充色
fill-opacity 透明度
stroke 描边的颜色
stroke-opacity 描边颜色的透明度
stroke-width 描边宽度
stroke-dasharray 虚线描边
dash array嘛可以接收多个数字
例如 stroke-dasharray='10 20 30' 表示 10(线的长度) 20(空隙长度) 30(线的长度)以此类推
stroke-dasharray 接收一串数字,这串数字可以用来代表,线的长度和空隙的长度,数字之间用逗号或者空格分隔。
stroke-dashoffset 虚线偏移量
stroke-linecap butt/round/square 线条端口图形
stroke-linejoin miter/round/bevel 线条拐角图形(折线通常有)
preserveAspectRatio 是否强制进行统一缩放,https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute/preserveAspectRatio
shape-rendering 指定 SVG 元素<path>的渲染模式(例如一些反锯齿模式)。 https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute/shape-rendering
动画属性
css3 svg 适用于css3的大部分属性,所以你可以选择animation去写动画 尤其svg,利用stroke-dasharray stroke-dashoffset path这些属性能够很简单的做描边的动画
进度条
利用stroke-dasharray你可以很简单的绘制出进度图,前面说过stroke-dasharray 虚线描边,如果你写整个轨迹的长度,就表示整个轨迹描边,可以写多个数字
进度条的逻辑
当然stroke-dasharray两个数字就可以表示比例了瑟,假如整个轨迹长100 stroke-dasharray:50,100 不就表示50%了么
直线进度条
圆形进度条
轨迹动画
svg本身的stroke-dasharray(描边) stroke-dashoffset(偏移量)这两属性,要绘制整个图形的轨迹是很简单的事情
上面的例子你可以看明白要做一个简单的轨迹动画 首先需要知道path,然后是轨迹的长度,这里我随便写的一个长度stroke-dashoffset:500,然后利用stroke-dashoffset制造偏移量,
简单的逻辑
- stroke-dasharray设置成轨迹长度表示默认描整个轨迹的边
- stroke-dashoffset设置成设置成轨迹长度,表示默认偏移长度等于整个轨迹,那么默认就不会有图形了
- 然后利用改变stroke-dashoffset偏移量去逐渐显示图形
但其实可以通过js获取到整个轨迹真实的长度
const path = document.querySelector('.path');
// 获取总长度
const totalLength = path.getTotalLength();
// 设置 stroke-dasharray
path.style.strokeDasharray = totalLength;
// 设置 stroke-dashoffset
path.style.strokeDashoffset = totalLength;
飞线图例子
不知道大家有没有观察echart的飞线图,当飞线图例放大你可以看见那条移动的轨迹其实是很多从大到小的圆圈组合形成的,参考下面的例子类似的原理,你多加一些圆圈拼接就能画出有轨迹动效的飞线图了
-
css3
当然svg也提供了一些动画标签
- animateMotion
其实svg动画不止animateMotion标签 还有animate animateTransform等标签,包括标签上的属性,这个后续有机会再细说了 developer.mozilla.org/zh-CN/docs/…