SVG的粗谈
背景
最近一直在做报表之类的需求,用highcharts比较多。highcharts使用svg进行绘图,所以学习了一下svg,稍微记录一下。
概况
svg是XML语言的一种形式。SVG可以通过定义必要的线和形状来创建一个图形,也可以修改已有的位图,或者将这两种方式结合起来创建图形。图形和其组成部分可以变形,可以合成,还可以通过滤镜完全改变外观。可能不太准确的简单来说,"就是可以绘图的html"。
用法
坐标
svg的坐标系统与html的一样,都是以元素的左上角为(0, 0)坐标。
根元素
首先声明一个根元素svg。svg元素上的属性是必不可少的。
<svg version="1.1"
baseProfile="full"
width="300" height="200"
xmlns="http://www.w3.org/2000/svg">
</svg>
1、version和baseProfile确定svg的版本
2、width、height指定svg的宽高
3、xmlns指定命名空间。
绘制图形
// 在坐标为(10,10)的地方,绘制宽高为30,轮廓宽5(黑色),用白色填充的矩形
<rect x="10" y="10" width="30" height="30" stroke="black" fill="#ffffff" stroke-width="5"/>
// 绘制半径为80,圆心位置为(150,100), 填充为绿色的圆
<circle cx="150" cy="100" r="80" fill="green" />
// 连接(10,50)和(110,150)两个点的一条线
<line x1="10" x2="50" y1="110" y2="150"/>
// 绘制椭圆。中心为:(75,75),长半径为:20,短半径为:5
<ellipse cx="75" cy="75" rx="20" ry="5"/>
// 绘制折线,points为折线上的点。
<polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/>
// 路径。d代表的是:一个点集数列以及其它关于如何绘制路径的信息。highcharts的曲线就是使用path画的。path很强大,很复杂,需要一定的数学基础。这里就不详细说了。
<path d="M 20 230 Q 40 205, 50 230 T 90230"/>
等等...
g元素
元素g是用来组合对象的容器。添加到g元素上的变换会应用到其所有的子元素上。添加到g元素的属性会被其所有的子元素继承。此外,g元素也可以用来定义复杂的对象,之后可以通过use元素来引用它们。
<svg width="100%" height="100%" viewBox="0 0 95 50"
xmlns="http://www.w3.org/2000/svg">
<g stroke="green" fill="white" stroke-width="5">
<circle cx="25" cy="25" r="15" />
<circle cx="40" cy="25" r="15" />
<circle cx="55" cy="25" r="15" />
<circle cx="70" cy="25" r="15" />
</g>
</svg>
use元素
use元素在SVG文档内取得目标节点,并在别的地方复制它们。use元素就相当于html中的模板。
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<style>
.classA { fill:red }
</style>
<defs>
<g id="Port">
<circle style="fill:inherit" r="10"/>
</g>
</defs>
<text y="15">black</text>
<use x="50" y="10" xlink:href="#Port" />
<text y="35">red</text>
<use x="50" y="30" xlink:href="#Port" class="classA"/>
<text y="55">blue</text>
<use x="50" y="50" xlink:href="#Port" style="fill:blue"/>
</svg>
在svg中使用CSS
在svg中是可以使用css控制样式的,跟html没什么区别。但是,并不是所有的属性都可以用css来设置。比如,width 、height等,就不能使用css来设置,必须写在svg元素上,如<rect width="30" height="30" style="stroke: black; fill: red;"/>
那么哪些属性可以通过css来设置呢?
可以使用css来设置:https://www.w3.org/TR/SVG/pro...
不能使用css来设置:https://www.w3.org/TR/SVG/att...
在svg中,也是可以像html一样使用class的,比如:
<text x="8" class="test" y="20">
<tspan>12:48</tspan>
</text>
.test {
font-size:12px;
color:#333333;
fill:#333333;
}
svg中使用CSS需要注意的地方
注意,svg中的css和html的css还是有不一样的地方。最重要,也是最容易出错的,就是transform这个属性。之前就被深深地坑过。
已经有文章说得很详细了,这里就不一一说明了。文章地址:
https://www.zhangxinxu.com/wo...
https://css-tricks.com/transf...
在svg中使用DOM操作
在svg中使用DOM操作和在html中是一样的。比如:
<rect width="30" height="30" style="stroke: black; fill: red;"/>
const rect = document.querySelector('rect');
rect.getAttribute('x');
rect.setAttribute('x', '100');
rect.addEventListener('click', _ => { console.log(1) });
...
只需要将svg看成html一样来进行DOM操作,没有任何问题。
svg 与canvas的比较
两者在作用上都是一样的,都是在h5页面上进行图像的绘制。但是两者还是有显著的区别。
svg是用xml来描述图形的,而canvas使用js来绘制图形。这点上,svg更简单。
svg支持事件处理器,canvas不支持事件处理器。
svg是基于矢量的,可以很好的处理图像大小变化。而canvas是基于位图的,无法进行大小变化。
canvas提供的功能更原始,适合像素处理,动态渲染和大数据量绘制。当元素特别多的时候,canvas的性能更好。毕竟10000多个dom元素的svg,浏览器肯定吃不消。
等等...
结束语
也是最近老接触svg,所以稍微研究了一下。前端可视化是一个充满挑战,也是一个十分有意思的方向,值得深入研究。