Skip to content

SVG基础与应用

Published:

简介

SVG指的是可缩放矢量图(Scalable Vector Graphics),它使用 XML 格式定义图形,在改变尺寸后仍能保持图形质量。SVG在2003年1月14日被确立为W3C标准。

svg、canvas、img对比

canvas

使用html + js来绘制图形,可用于图片、动画、游戏、数据可视化和实时视频处理。canvas默认开启硬件加速。(使用chrome://gpu/可进行查看)

<html>
 <head>
  <script>
    function draw() {
      var canvas = document.getElementById("canvas");
      if (canvas.getContext) {
        var ctx = canvas.getContext("2d");
        ctx.fillStyle = "#000";
        ctx.fillRect (10, 10, 20, 40);
      }
    }
  </script>
 </head>
 <body onload="draw()">
   <canvas id="canvas" width="150" height="150"></canvas>
 </body>
</html>

优点

canvas与img对比

svg

使用html + css来绘制图形,用于描述矢量图像的XML语言,可以理解为是一个HTML片段

优点

svg与img对比

基本属性

CSS

SVG形状

通用

矩形

<rect width="100" height="100" x="5" y="5" rx="10" ry="50" fill="black" fill-opacity="0.5" stroke="red" stroke-width="10" stroke-opacity="0.3" stroke-dasharray="40,20" style="stroke-dashoffset: 100" />

圆形

<circle r="50" cx="55" cy="55" fill="black" fill-opacity="0.5" stroke="red" stroke-width="10" stroke-opacity="0.3" />

椭圆

<ellipse rx="50" ry="40" cx="55" cy="45" fill="black" fill-opacity="0.5" stroke="red" stroke-width="10" stroke-opacity="0.3" />

线条

<line x1="0" y1="55" x2="100" y2="55" stroke="red" stroke-width="10" stroke-opacity="0.3" />

stroke-linecap: butt | round | square | inherit

stroke-linejoin:arcs | bevel | miter | miter-clip | round

多边形

<polygon points="220,100 300,210 170,250 123,234" fill="black" fill-opacity="0.5" stroke="red" stroke-width="10" stroke-opacity="0.3" />

折线

<polyline points="220,100 300,210 170,250 123,234" fill="black" fill-opacity="0.5" stroke="red" stroke-width="10" stroke-opacity="0.3" />

路径[1]

下面的命令可用于路径数据(大写表示绝对路径,小写表示相对路径):

<path d="M250 150 L150 350 L350 350 Z" />

<path d="M153 334 C153 334 151 334 151 334 C151 339 153 344 156 344 C164 344 171 339 171 334 C171 322 164 314 156 314 C142 314 131 322 131 334 C131 350 142 364 156 364 C175 364 191 350 191 334 C191 311 175 294 156 294 C131 294 111 311 111 334 C111 361 131 384 156 384 C186 384 211 361 211 334 C211 300 186 274 156 274" fill="none" stroke="red" stroke-width="2" />

SVG渐变[3]

SVG中渐变颜色的设置,不能像css那样,直接写fill="linear-gradient(color1, color2)",而要使用专门的渐变标签:<linearGradient>(线性渐变) 和 <radialGradient>(径向渐变或放射渐变)。一个SVG元素上只能有一个渐变。

<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
	<defs>
		<linearGradient id="orange_red" x1="0%" y1="0%" x2="100%" y2="0%">
			<stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
			<stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
		</linearGradient>
	</defs>
	<ellipse cx="200" cy="190" rx="85" ry="55" style="fill:url(#orange_red)" />
</svg>
<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
		<radialGradient id="grey_blue" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
			<stop offset="0%" style="stop-color:rgb(200,200,200);stop-opacity:0" />
			<stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1" />
		</radialGradient>
	</defs>
	<ellipse cx="230" cy="200" rx="110" ry="100" style="fill:url(#grey_blue)" />
</svg>

SVG滤镜[4]

用来给形状和文本添加特殊效果,如:模糊、阴影、扭曲、图像合成叠加等,一个SVG元素上可以同时使用多个滤镜。

CSS提供的内置滤镜有:

SVG提供的滤镜有:

<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
	<defs>
		<filter id="Gaussian_Blur">
			<feGaussianBlur in="SourceGraphic" stdDeviation="3" />
    </filter>
	</defs>
	<ellipse cx="200" cy="150" rx="70" ry="40" style="fill:#ff0000;stroke:#000000;stroke-width:2;filter:url(#Gaussian_Blur)" />
</svg>

其他常见标签

应用场景

  1. 直接作为矢量图片使用
  2. 内联SVG为组件添加背景
  3. 内联SVG + CSS / JS为组件添加动画
  4. 手动绘制简单图形,如:点线面图例、线路图(可绘制阴影)等

其他应用

  1. 如果想让父元素来控制svg颜色,可将 fillstroke 属性设为 currentColor
    <div style="width: 100px; height: 100px; color: blue">
      <svg viewBox="0 0 24 24" style="fill: currentColor; stroke: currentColor">
        <circle r="10" cx="10" cy="10" />
        <line x1="0" y1="10" x2="10" y2="10" />
      </svg>
    </div>
    
  2. 当viewBox属性固定,默认修改svg标签的宽高,svg都会按比例缩放。如果不想按比例缩放,需要svg撑满整个画面,只需为svg标签添加属性:preserveAspectRatio=“none”
  3. 获取路径或线条的长度
    const path = document.querySelector('path'); 
    const length = path.getTotalLength();
    
  4. 第三方库:echarts[5]d3

附录

[1] SVG path

[2] 贝塞尔曲线

[3] SVG 渐变

[4] SVG 滤镜

[5] Echarts Canvas or SVG

参考资料

  1. MDN
  2. svg教程
  3. img,canvas,svg对比,总结,代码实现

Previous Post
flex布局
Next Post
Regex Cheatsheet