—– 后记:SVG系列已经更新到语雀平台:看起来更清晰:—-
语雀地址: https://www.yuque.com/ada87/svg
本文地址: https://www.xdnote.com/svg1
小说一下历史
SVG很久以前就存在了,但是从来没有使用过。在没有HTML5之前,占据图形展示的主角是 Flash。还有就是应用程序通过字节流绘制的,比如PHP的GD库,Java的Graphx等等。
后来 HTML5 发布,Canvas(画布) 走向了前端,很多图形工具框架出现了,直到现在仍然是主流,很欣喜的是,国内在基于画布的开源项目已经非常成熟,一点也不比国外的差,比如百度的 ECharts, 阿里的 G2,G6 等等,都是非常不错的Canvas框架。
也多亏了浏览器大战,Canvas 很快都支持了WebGl,ThreeJs 应声而出。也是基于Canvas的种实现,使用opengl,通过硬件渲染支持复杂的3D图形显示。
当然想起了写个SVG的教程,我们还是把主角光环移回 SVG 身上来。直到现在,SVG占据的图形化编程市场也并不算多,有学习的的必要吗?
我的回答是:看需要,任何技术都有它的适用性。
简单介绍:你可能并不需要SVG
上面说到的一些图形框架比如 EChart, G2,已经抽象的很不错了,我相信一般的需求基本上通过少量简单的代码即可实现。
SVG是一个基于XML的失量图形文档系统,SVG规范在1999年就由W3C制定了。(建议先对失量图了解一下)
那么,在什么情况下,我才不使用简单好用的框架,转而使用SVG呢,个人总结几点:
- 需要自由控制交互事件:在画布里面,由于只存在一个DOM节点,所以很多操作只能通过模拟事件,并自建数据索引的方式来实现每个节点的交互。
- 需要自由控制每个节点:使用一些框架后,可以像 JQuery 操作 DOM 一样来操作操作SVG,相当方便。另外, SVG是支持CSS的,这也使得样式从程序中剥离。
- 细节要求高:通常来说,即使像 EChart,G2 这样的优秀的框架,也并不是万能的,只能抽像到到一定程度后,就比较难再往更细的水平上优化了。(当然框架还是提供了一些原生绘图context之类的可以进行发挥,但一般比较困难)
- 需要更高的灵活度:由于SVG相对来说粒度比较细,比起画布来更加灵活。
什么场景适用Canvas,什么场景上适用 SVG:
个人认为最值得关注点:由于是基于DOM的原因,如果你的图像中有成千上万结点组成,那么,请不要使用SVG,会导致浏览器卡死。(其实我是想说,一般情况下,不要去纠结一些微不足道的差异)
从一个框架说起: d3
按官方的描述, d3 是一个数据驱动文档的工具包,没有提到SVG,因为它可以驱动任何文档,SVG仅是其中一种。(还包括了DOM,CSV,JSON 等等)
这么说来,D3 实际上和 SVG 并没有太大关系,但我们知道 SVG 实际上是 XML文档,由于SVG在显示器上的显示的图形是文档驱动,可以理解为 D3 就是数据驱动了 SVG的图形显示!SVG因为有了D3而大放异彩,可以说D3就是为了SVG而生!
以下是 d3 的一些优点。
- D3 简单清晰,仅需几个小时即可了解D3基础的API,大部分的API看方法名即可理解。
- D3 粒度细,刚已经说过了。
- D3 使用方便,除了基础API外,D3提供了大量的数据组合结构,大量图形构造器,比例尺,Effect 等等,可以很方便的组合编程。
总之,即使你不准备使用SVG,我个人也建议你去学习一下D3,里面有很多编程思想值得借鉴。
关于D3就说到这,希望你能知道D3和SVG的关系,后面肯定还会把D3再拿出来说事的。
SVG 科普
刚说了SVG,是基于XML的,先简单来一段:
<?xml version="1.0" encoding="UTF-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect x="25" y="25" width="200" height="200" fill="lime" stroke-width="4" stroke="pink" />
<circle cx="125" cy="125" r="75" fill="orange" />
<polyline points="50,150 50,200 200,200 200,100" stroke="red" stroke-width="4" fill="none" />
<line x1="50" y1="50" x2="200" y2="200" stroke="blue" stroke-width="4" />
</svg>
你可以看到这样的图形:
和普通的PNG,JPG之类不同就是,你能完全通过明文,看出这个形状,很容易进行属性修改而改变图形的显示的效果。和 Canvas 的区别主要是你不需要以 2dcontext的方式进行绘制,而是像写HTML一样写标签的方式进行绘制,比如这两个API的区别:
//使用画布(JavaScript)
context.strokeStyle = "pink";
context.fillStyle = "lime";
context.fillRect(10, 10, 50, 50);
//SVG (HTML)
<rect x="10" y="10" width="50" height="50" fill="lime" stroke="pink" />
小结
先怀一下旧,在两年多前,本人也研究过一段时日的Canvas,还写过两个小游戏(甚至还抽象出一个玩具级别的游戏引擎 https://coding.net/u/ada87/p/xGame/git),当时感觉 Canvas 的提供的API还是相当简单的,但只要一慢下来,过一段时间不用,基本上马上就会忘的一干二净。
但是SVG不一样,它是标准的图形化语言,用过一段时间后不用,你会忘记D3代码怎么写,但你不大会忘记SVG,你像你可以会忘记JQuery和bootstrap一样,但你不会忘记HTML.
另外,由于我自己也就是简单使用,估计掌握度也就五成左右的火候。外加一些通俗的工具书内容不会写到,所以要解决系统性的问题,你可以依靠自己的智慧和无所不能的Google来完成剩下的部分,谢谢。
SVG系列总览: