作为一只前端,只懂 Vue、React 感觉已经和大家拉不开距离了。
可视化、机器学习等领域 JS 都有涉及到,而可视化方面已经被很多领域用到,比如大屏项目。
可视化领域相关的技术有 canvas 和 SVG ,而这两个东东是迟早要接触的了。
在我接触 SVG 之前,我觉得这是一个很高深的东西,有点恐惧。我第一次接触 SVG 是在 iconfont网站,我没理它是什么东西,反正就跟着教程用。第二次接触就是在 《CSS揭秘(图灵出品)》 这本书,里面会讲到 SVG 相关的内容,而我选择了跳过这部分内容。。。
之后是怎么学会的我也忘了。
最近时间比较多,就把我懂的知识用人话整理出来,方便查询。
本文主要把 “可视” 方面的内容整理出来,操作交互方面(动画、交互事件等) 的内容留到下一篇~
什么是SVG
在学习 SVG 之前,首先要了解 位图 和 矢量图 的区别。
简单来说:
我在 知乎 上找了一个图对说明一下。
左边是位图,右边是矢量图
那么 SVG 是什么呢?它是矢量图的其中一种格式。它是用 XML 来描述图形的。
对于初学 SVG 的前端来说,可以简单的理解为 “SVG 是一套新标签”。
所以可以使用 CSS 来设置样式,也可以使用 JS 对 SVG 进行操作。
SVG的使用方式使用方法
SVG 的使用方式有很多种,我最推荐直接在 HTML 中直接使用,也就是直接当 HTML 标签使用。
我在 《SVG 在前端的7种使用方法》 里记录了几种使用方法:
在浏览器直接打开内嵌到 HTML 中(推荐)CSS 背景图(推荐)使用 img 标签引入(推荐)使用 iframe 标签引入(不推荐)使用 embed 标签引入(不推荐)使用 object 标签引入(不推荐)
SVG默认宽高
在 HTML 中使用 SVG ,直接用
在不给
设置矩形位置
通过 x 和 y 可以设置矩形位置
圆角矩形
rx 是设置x轴的半径,ry 设置y轴的半径。
rx 的最大值是矩形宽度的一半,ry 的最大值是矩形高度的一半。
当只设置 rx 或者 ry 其中一个值时,另一个属性也会使用一样的值。
比如
此时 rx 和 ry 都是 30。
rect版的圆形
圆角的概念和 CSS 的 border-radius 有点像,所以有没有一种可能,用 也可以画圆形呢?
只要把宽高设成一样,圆角设成宽度的一半就能实现圆形。这是在 HTML 里的实现方式之一。
同理也用 实现椭圆,但在 SVG 中是不会这样做的。因为 SVG 里有专门的圆形和椭圆的标签。
圆形 circle
圆形使用 标签,基础属性有:
椭圆 ellipse
椭圆使用 标签,基础属性有:
和 差不多,只是将半径拆成x轴和y轴的。
直线 line
直线使用 标签,基础属性有:
只有 x1 和 x2 ,没有 x3 ,也没有 y3 。
需要注意的是, 需要使用设置 stroke 属性才会有绘制效果。
折线 polyline
使用
可以绘制折线,基础属性有:
points 接受的值是一串点集,点集是两两一组表示一个坐标。
其实点集完全不需要用逗号隔开,上面的例子中我使用了逗号隔开,完全是为了让自己阅读代码时比价易懂。一个逗号分隔一个 xy 坐标。
在绘制折线是,我通常是将 fill 设置成 none ,因为 fill 默认值是黑色,如果不设置成 none 会出现以下效果:
将 fill 设置成 none 后,必须设置 stroke 为一个有颜色的值,不然不会有渲染效果。
多边形 polygon
多边形使用
标签,基础属性和
差不多:
会自动闭合(自动将起始点和结束点链接起来)。
直线路径 path
其实在 SVG 里,所有基本图形都是
的简写。所有描述轮廓的数据都放在 d 属性里,d 是 data 的简写。
d 属性又包括以下主要的关键字(注意大小写!):
概念说了一堆,还是用写 demo 的方式来展示会更加直观。
基础版
上面的例子里,通过1个 M 和3个 L 描绘了3个点。
使用 stroke 设置描边的颜色,使用 fill="none" 将填充色改成透明。最后就形成上图的效果。
简写
如果全是使用大写 L 来描述每个点的位置,那可以把 L 也去掉,直接写点集。
上面的 d="M 10 10 50 40 100 10" 等同于 d="M 10 10 L 50 40 L 100 10" 。
闭合路径
在 d 的数据集里,使用 Z 可以闭合路径。
轮廓坐标相对位置 l
使用 L 的小写方式 l 可以实现相对位置写法。
上面的代码中,d="M 10 10 l 50 40 l 100 10 Z" 等同于 d="M 10 10 L 60 50 L 160 60 Z" 。
l 里的参数会与前一个点的 x 和 y 进行相加,得到一个新的坐标。
H 和 h
H 后面只需传入 X坐标 即可,它的 Y坐标 与前一个点相同。
上面的代码中,d="M 10 10 H 100" 等同于 d="M 10 10 L 100 10"
而 h 和 H 的作用差不多,只不过传入的数据会和前一个点的 X坐标 相加,形成一个新的点,这就是相对位置。
可以讲 H 和 h 的例子产生的图片对照一下。
V 和 v
V 后面只需传入 Y坐标 即可,它的 X坐标 与前一个点相同。
v 和 V 的作用差不多,小写 v 是一个相对位置。
曲线 - 椭圆弧路径 path
在 SVG 中,画曲线其实有很多种方法。我觉得最简单的是 椭圆弧曲线,其实还有 贝塞尔曲线、三次贝塞尔曲线 等一系列复杂的曲线。但我觉得这对初学者来说可能一下子难以接受,所以我在 《Canvas 从入门到劝朋友放弃(图解版)》 里也没写。之后打算再写一篇贝塞尔曲线相关的文章骗点赞~
什么是椭圆弧?
前面讲到的 直线路径 path 是比较好理解的,它把所有点都用直线连接起来即可。只要确定2个点就可以画出一根线段。
但如果只用两个点,可以产生无数条曲线。所以需要添加更多的参数来确定如何绘制一条曲线。而在种种方法中,我认为 椭圆弧曲线 是最简单的。
椭圆弧曲线,顾名思义就是和椭圆有关的。如果在椭圆上选择两个点,就可以截取2条曲线。
比如这样,红线处就将椭圆截取成2段弧线。
椭圆弧公式
在 SVG 中可以使用 path 配合 A属性 绘制椭圆弧。
A(rx, ry, xr, laf, sf, x, y)
上面的公式中并没有开始点,开始点是由 M 决定的。
也就是说,确定2个点,再确定椭圆半径,就可画出2个椭圆
通过开始点和结束点裁切,可以得到4条弧线,也就是说2个点可以确定2个相同旋转角度的椭圆的位置,可以切出4条弧线。
绘制弧线是比较抽象的,通常我是不会手动绘制的,我会使用 Illustrator 绘制,然后生成 SVG 来使用。
设置样式的方法
设置 SVG 元素样式其实和 CSS 差不多,常见的方法有4种。
属性样式
直接在元素属性上设置样式,比如将矩形填充色改成粉红
内联样式
把所有样式写在 style 属性里
内部样式
将样式写在 标签里
外部样式
将样式写在 .css 文件里,然后在页面中引入该 CSS 文件。
常用样式设置
SVG 设置样式的属性和 CSS 稍微有点不同,但初学时不需要了解太深入,我们只需将常用的学会即可。
比如填充色、描边颜色等。
说到颜色,SVG 和 CSS 支持的颜色值其实差不多的,比如:
接下来讲到的所有常规属性,除了在元素属性上设置之外,都支持在 CSS 中设置。
填充 fill
要填充图案颜色,可以设置 fill 属性。这个属性在前面的例子也使用过多次。
fill 默认是 #000000 ,也就是黑色。
也可以使用 none 或者 transparent 将填充色设置成透明。
填充色的不透明度 fill-opacity
如果想让填充色有点 半透明 的感觉,可以设置 fill-opacity 属性,也可以在 fill 属性中使用 RGBA 或者 HSLA。
本例使用 fill-opacity 设置,它的取值是 0 - 1,0 代表完全透明,1 代表完全不透明。小于 0 的值会被改为 0,大于 1 的值会被改为 1 。
fill 属性中使用 RGBA 或者 HSLA 的方式你自己动手试试看~
描边颜色 stroke
可以通过 stroke 属性设置描边的颜色,之前也使用过。如果不设置 stroke ,图形默认是没有描边颜色的。
我将填充色设置成透明,方便观察蓝色边框。
描边颜色的不透明度 stroke-opacity
和 fill-opacity 差不多,只不过 stroke-opacity 是设置描边的不透明度
描边宽度 stroke-width
如果需要调整描边的宽度,可以使用 stroke-width,它接收一个数值
虚线描边 stroke-dasharray
边框的 点线 或者 虚线 样式,可以使用 stroke-dasharray 设置,这和 Canvas 里设置虚线的操作其实是差不多。
stroke-dasharray 接收一串数字,这串数字可以用来代表 线的长度和空隙的长度,数字之间用逗号或者空格分隔。
建议传入偶数个数字。但如果你传入了奇数个数字,SVG 会将这串数字重复一遍,使它的数量变成 偶数个 。
虚线偏移量 stroke-dashoffset
虚线还可以通过 stroke-dashoffset 属性设置偏移量,它接收一个数值类型的值。
我加粗了虚线,方便观察偏移量。
线帽 stroke-linecap
线帽就是线的起始点和结束点的位置,用 stroke-linecap 属性可以设置线帽样式。
线帽有3个值:
可以看到 square 比 butt 要稍微长一丢丢。
拐角 stroke-linejoin
拐角就是折线的交接点,可以使用 stroke-linejoin 设置,它接收以下属性:
消除锯齿 shape-rendering
如果你觉得 SVG 在浏览器显示出来的图像有点模糊,那可能是开启了 反锯齿 功能,可以通过 CSS 属性关闭该功能。
shape-rendering: crispEdges;
将该属性设置到对应的 svg 元素上,就会关闭反锯齿功能,突显看起来就会清晰很对,但在某些情况关闭了该功能会让图像看起来有点毛躁的感觉。
如果想开启反锯齿功能,可以这样设置:shape-rendering: geometricPrecision;
文本元素 text
SVG 可以使用 标签渲染文本。文本是有 “基线” 概念的,这个概念和 CSS 的一样。这里推荐 AndyHu 的文章,可以快速搞懂基线。《彻底搞懂vertical-align 底线、基线、中线的含义》
基础版
和 Canvas 一样,SVG 的文本对齐方式是以第一个字基线的左下角为基准。
可以看到,文字跑去左上角了。但这并不是我们想要的效果。
SVG 如果没设置字号,它会跟随父元素的字号,一直往上跟跟跟上去。
在本例中,默认字号是跟随了浏览器的,也就是 16px 。
如果我们想看到文本,就需要将文字往下移动 16px,因为本文的对齐方式是以第一个字的基线的左下角为参考,默认的位置坐标是 (0, 0) ,现在要将y轴坐标改成 16px 才能完整显示文本
设置字号 font-size
粗体 font-weight
使用 font-weight 可以将文本设置成粗体。
这和 CSS 是一样的
装饰线 text-decoration
和 CSS 一样,可以使用 text-decoration 设置装饰线
水平对齐方式 text-anchor
可以通过 text-anchor 属性设置文本水平对齐方式。
如果本子是从左向右书写,那这几个参数的意思就是:
多行文本
多行文可以使用本 标签辅助实现
要放在 里,而且会继承 设置的样式。
如果在 里设置的样式和 的样式有冲突,最后会使用 的样式。
水平对齐方式
垂直对齐方式 dominant-baseline
可以通过 dominant-baseline 属性设置文本垂直对齐方式
纵向文字 writing-mode
将 writing-mode 设置成 tb 就可以让文字纵向排列。
需要注意英文和中文的文字角度!
有些教程里面会讲 glyph-orientation-vertical 属性可以旋转文字方向,但不推荐这个方法,因为现在的浏览器可能不再支持它了。
可以看看这个文档的说明:《glyph-orientation-vertical》
超链接
和 HTML 一样,超链接可以使用 标签实现。
在 SVG 里,链接要放在 xlink:href 属性里。
如果希望鼠标放到链接上出现提示信息,可以在 xlink:title 属性里编写提示信息。
如需在新窗口打开链接,可以设置 target="_blank" 。
此时点击图片上的链接就会跳到对应的页面。
标签里除了可以包裹文本外,还可以包裹各种图形和图片等元素。
图片 image
在 SVG 中可以使用 标签加载图片,包括位图。
是使用 xlink:href 属性获取图片的
图片标签其实没什么好说的,和 HTML 的
标签用法差不多。
总结
通过上面这么多例子应该对 SVG 有一个大致的了解了。SVG 在前端编码中,感觉就像一堆新的标签。我们只要当它是 HTML 那样使用就行了。
本文记录的所有知识点都是 SVG 基础中的基础。
下一篇会介绍进阶的标签。比如实现渐变、分组,还会介绍比较难理解的坐标系统。
代码仓库
雷猴 SVG
