# SVG
SVG 即可缩放矢量图形
SVG元素:圆形
, 矩形
, 曲线
一个简单的SVG文档由<svg>
根元素和基本的形状元素构成。另外还有一个g元素
,它用来把若干个基本形状编成一个组
绘制SVG要注意几点:
SVG是一种
XML
语言, SVG的元素和属性必须按标准格式书写,因为XML是区分大小写的(这一点和html不同)XML
语言里的属性值必须用引号引起来,就算是数值也必须这样做SVG的渲染顺序是“后来居上”,越后面的元素越可见
g
包含的子元素如果使用transform
(无论是属性还是style
设置的),g
的大小将被受影响SVG的使用方式
如果HTML是XHTML并且声明类型为
application/xhtml+xml
,可以直接把SVG嵌入到XML源码中如果HTML是HTML5并且浏览器支持HTML5,同样可以直接嵌入SVG。然而为了符合HTML5标准,可能需要做一些语法调整
可以通过 object 元素引用SVG文件:
<object data="image.svg" type="image/svg+xml" />
类似的也可以使用
iframe
元素引用SVG文件:<iframe src="image.svg"></iframe>
理论上同样可以使用 img 元素,但是在低于4.0版本的Firefox 中不起作用
最后SVG可以通过JavaScript动态创建并注入到HTML DOM中。 这样具有一个优点,可以对浏览器使用替代技术,在不能解析SVG的情况下,可以替换创建的内容。
简单例子:
// demo.svg
<svg version="1.1"
baseProfile="full"
width="300" height="200"
xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="red" />
<circle cx="150" cy="100" r="80" fill="green" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
</svg>
# SVG 元素
# react-矩形
<rect x="60" y="10" rx="10" ry="10" width="30" height="30"/>
x
: 矩形左上角的x位置
y
: 矩形左上角的y位置
width
: 矩形的宽度height
: 矩形的高度rx
: 圆角的x方位
的半径ry
: 圆角的i方位
的半径
# circle-圆形
<circle cx="25" cy="75" r="20"/>
r
: 圆的半径cx
: 圆心的x位置cy
: 圆心的y位置
# Ellipse-椭圆
Ellipse 给制椭圆
<ellipse cx="75" cy="75" rx="20" ry="5"/>
rx
: 椭圆的x半径ry
: 椭圆的y半径cx
: 椭圆中心的x位置cy
: 椭圆中心的y位置
# line-线条
Line 绘制直线。它取两个点的位置作为属性,指定这条线的起点和终点位置。
<line x1="10" x2="50" y1="110" y2="150"/>
x1
: 起点的x位置y1
: 起点的y位置x2
: 终点的x位置y2
: 终点的y位置
# polyline-折线
Polyline是一组连接在一起的直线。因为它可以有很多的点,折线的的所有点位置都放在一个points属性中:
<polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/>
points
:点集数列。每个数字用空白、逗号、终止命令符或者换行符分隔开。每个点必须包含2个数字,一个是x坐标,一个是y坐标。 所以点列表(0,0)
,(1,1)
和(2,2)
可以写成这样:“0 0, 1 1, 2 2”
# polygon-多边形
polygon和折线很像,它们都是由连接一组点集的直线构成。不同的是,polygon的路径在最后一个点处自动回到第一个点。需要注意的是,矩形也是一种多边形,如果需要更多灵活性的话,你也可以用多边形创建一个矩形
<polygon points="50 160, 55 180, 70 180, 60 190, 65 205, 50 195, 35 205, 40 190, 30 180, 45 180"/>
points
:
# path-路径
你可以用path元素绘制矩形(直角矩形或者圆角矩形)、圆形、椭圆、折线形、多边形,以及一些其他的形状,例如贝塞尔曲线、2次曲线等曲线。 因为path很强大也很复杂,所以会在下一章进行详细介绍。这里只介绍一个定义路径形状的属性
d
: 是一个命令+参数
的序列, 描述于如何绘制路径的信息,以下是在d
中使用的命令:M x y
:表示的是“Move to”命令,当解析器读到这个命令时,它就知道你是打算移动到某个点,跟在命令字母后面的,是你需要移动到的那个点的x和y轴坐标 比如移动到(10,10)这个点的命令,应该写成M 10 10
L x y
: L命令将会在当前位置和新位置(L前面画笔所在的点)之间画一条线段<path d="M10 10 L90 90" stroke="black"/>
H x
: 绘制水平线,只需一个参数V y
: 绘制垂直线,只需一个参数Z
: 闭合路径命令,Z命令会从当前点画一条直线到路径的起点, Z命令不用区分大小写
<path d="M 10 10 L 90 90 H 50 L 10 10" stroke="black" fill="transparent"/>
等同于:<path d="M 10 10 L 90 90 H 50 Z" stroke="black" fill="transparent"/>
C
: 贝塞尔曲线,C x1 y1, x2 y2, x y (or c dx1 dy1, dx2 dy2, dx dy)
- 最后一个坐标(x,y)表示的是曲线的终点,(x1,y1)是起点的控制点,(x2,y2)是终点的控制点
S
:
每一个命令都有两种表示方式,一种是用大写字母,表示采用绝对定位。另一种是用小写字母,表示采用相对定位, 除了Z
- ``
# SVG属性
fill
:内容填充stroke
: 线条的颜色fill-opacity
:控制填充色的不透明度stroke-opacity
: 控制描边的不透明度
# svg和canvas区别
从图像类别区分,Canvas是基于像素的位图,而SVG却是基于矢量图形
从结构上说,Canvas没有图层的概念,所有的修改整个画布都要重新渲染,而SVG则可以对单独的标签进行修改
从操作对象上说,Canvas是基于HTML canvas标签,通过宿主提供的Javascript API对整个画布进行操作的,而SVG则是基于XML元素的。
从渲染模式上来说,Canvas属于 即时模式,而SVG则是 保留模式 ,这两种模式的区别可以参见 cshao 的博文:
http://www.lifelaf.com/blog/?p=354
从搜索引擎角度分析,由于svg是有大量标签组成,所以可以通过给标签添加属性,便于爬虫搜索
# 适用场景
Canvas 提供的绘图能力更底层,适合做到像素级的图形处理,能动态渲染和绘制大数据量的图形。而 SVG 抽象层次更高,声明描述式的接口功能更丰富,内置了大量的图形、滤镜和动画等,方便进行文档元素的维护,也能导出为文件脱离浏览器环境使用
# 性能差异
之前网上有不少 Canvas 和 SVG 性能对比的文章,得出的结论大体是“Canvas 性能更好,适合更大量数据的渲染”。 其实这么说是有失偏颇的。性能对比要看场景。从底层来看,Canvas 的性能受画布尺寸影响更大,而 SVG 的性能受图形元素个数影响更大
# 定制和交互
比较流行的看法是 SVG 做定制和交互更有优势,因为有类似 DOM 的结构,能快速应用浏览器底层的鼠标事件、CSS 样式、CSS3 动画等。不过基于 Canvas 做上层封装后也能实现类似的定制和交互,并且自由度更高
# 小结
如果单就图表库的视角来看,选择 Canvas 和 SVG 各有千秋。小画布、大数据量的场景适合用 Canvas,譬如热力图、大数据量的散点图等。 如果画布非常大,有缩放、平移等高频的交互,或者移动端对内存占用量非常敏感等场景,可以使用 SVG 的方案。