2

背景

最近一直在做报表之类的需求,用highcharts比较多。highcharts使用svg进行绘图,所以学习了一下svg,稍微记录一下。

概况

svg是XML语言的一种形式。SVG可以通过定义必要的线和形状来创建一个图形,也可以修改已有的位图,或者将这两种方式结合起来创建图形。图形和其组成部分可以变形,可以合成,还可以通过滤镜完全改变外观。可能不太准确的简单来说,"就是可以绘图的html"。

用法

坐标

svg的坐标系统与html的一样,都是以元素的左上角为(0, 0)坐标。

根元素

首先声明一个根元素svgsvg元素上的属性是必不可少的。

<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来设置。比如,widthheight等,就不能使用css来设置,必须写在svg元素上,如<rect width="30" height="30" style="stroke: black; fill: red;"/>

那么哪些属性可以通过css来设置呢?

在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这个属性。之前就被深深地坑过。

已经有文章说得很详细了,这里就不一一说明了。文章地址:

  1. https://www.zhangxinxu.com/wo...
  2. 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操作,没有任何问题。

svgcanvas的比较

两者在作用上都是一样的,都是在h5页面上进行图像的绘制。但是两者还是有显著的区别。

  • svg是用xml来描述图形的,而canvas使用js来绘制图形。这点上,svg更简单。
  • svg支持事件处理器,canvas不支持事件处理器。
  • svg是基于矢量的,可以很好的处理图像大小变化。而canvas是基于位图的,无法进行大小变化。
  • canvas提供的功能更原始,适合像素处理,动态渲染和大数据量绘制。当元素特别多的时候,canvas的性能更好。毕竟10000多个dom元素的svg,浏览器肯定吃不消。
  • 等等...

结束语

也是最近老接触svg,所以稍微研究了一下。前端可视化是一个充满挑战,也是一个十分有意思的方向,值得深入研究。


CoyPan
3.8k 声望3.7k 粉丝

FE