Svg葵花宝典
概念:可缩放矢量图形(英语:Scalable Vector Graphics,SVG)是一种基于可扩展标记语言(XML),用于描述二维矢量图形的图形格式。SVG由W3C制定,是一个开放标准。
与canvas相比
| 内容 | Canvas | Svg |
|---|---|---|
| 历史 | 较新,apple技术发展而来 | 历史悠久,2003年成为w3c标准 |
| 功能 | 功能简单,2D绘图api | 功能丰富,各种图形、滤镜、动画等 |
| 特点 | 像素,只能脚本驱动,修改部分需全部重新绘制 | 矢量,xml、css、脚本均可,修改部分只需修改部分属性就行 |
| 支持 | 主流浏览器,ie9+ | 主流浏览器,ie9+,其他svg阅读器 |
| 操作对象 | 基于像素(动态) | 基于图形元素 |
| 元素 | 单个html元素 | 多个图形元素(rect,circle,line...) |
应用场景
- 很多设计工具或者站点都支持导出svg格式;
- 制作高保真图片、logo
- 一些海报(html -> svg)的高保真打印
简单demo
<svg width="200" height="200" id="mysvg">
<circle r="50" cx="0" cy="0" fill="red" stroke="green" stroke-width="5"/>
</svg>
解析:
- svg是行内元素(同canvas)
- svg默认宽高是300*150
- svg内每个标签都是可以通过dom进行操作来改变图形的呈现(canvas只能操作canvas标签)
- 一般含有图形意义的标签不允许嵌套(g,defs,animate)
常用(图形)标签
通用图形属性
stroke: 描边填充颜色stroke-width: 描边宽度x/y: 点在svg面板中的坐标
直线
<svg class="svg-pannel">
<line
x1="10"
y1="10"
x2="40"
y2="40"
stroke="red"
stroke-width="2"
stroke-linecap="round"
></line>
</svg>
x1/y1、x2/y2: 分别对应直线的两点点坐标stroke-linecap: 直线两端的形状,枚举值有butt、square、round
曲线(折线)
<svg class="svg-pannel" fill="green">
<polyline
class="polyline"
points="10,10 30,10 30,30 10,30 10,50 30,50"
></polyline>
</svg>
points: 折线连接点坐标字符串,每个坐标点x/y逗号分割,各个坐标空格分
路径
<svg version="1.1" class="box">
<path d="M150 0 L75 100 L150 100 Z" />
</svg>
(绘制)文本
<svg
xmlns="http://www.w3.org/2000/svg"
version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<text x="10" y="100" style="fill:red;">
I love SVG I love SVG
</text>
</svg>
I love SVG I love SVG
I love SVG I love SVG
I love SVG I love SVG
矩形
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="box">
<rect x="100" y="100" width="50" height="50" />
</svg>
圆形
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="box">
<circle
cx="100"
cy="50"
r="40"
stroke="white"
stroke-width="10"
fill="red"
/>
</svg>
cx/cy: 圆的x/y坐标y: 圆的半径
画一个虚线段
<svg>
<line
x1="100"
y1="300"
x2="400"
y2="300"
stroke="black"
stroke-width="10"
/>
<line
x1="100"
y1="300"
x2="400"
y2="300"
stroke-width="10"
stroke="pink"
stroke-dasharray="20,40"
/>
</svg>
stroke-dasharray: 值为数字字符串,各个数字用,分割,其中第奇数个数字表示实线(段/圆弧)的长度,第偶数个表示实线(段/圆弧)的间距,svg解析的时候会重复复制其值(repeat),直到超过(无法继续排了)整个直线(圆弧)为止,例如直线长100,stroke-dasharray值为20,40,实际复制之后的值是20,40,20,40(20+40+20+40 > 100)
画一圆弧
思路:画一个指定角度x的圆弧,我们只要求出其长度,然后设置
stroke-dasharray第一个值为其长度,圆弧线段之间的距离超过2*Math.pi*r*(360-x)/360即可
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="box">
<circle
cx="150"
cy="150"
r="100"
stroke="black"
stroke-width="10"
fill="red"
stroke-dasharray="314,1000000"
/>
</svg>
妹学会?尝试一下 [画一个椭圆]](codesandbox.io/s/tuoyuan-4…)
defs与g标签
在我们开发中,对于一些经常使用的模块我们都会,将其单独封装定义以使后面可以直接拿来用,同理在
svg中ddefs就是完成类似功能,defs定义的图形(模版)并不会渲染,而是通过use标签使用之后才会渲染,当然即使不用defs也可以使用use,但那样defs定义的模版图形会立即渲染(加上use标签共计渲染两次),而g标签对包裹图形进行组合成一个整体(图层),后面对g标签对所有操作都会对所有子元素生效,例如整体的渲染,填充色等
<svg class="box">
<defs>
<g id="my-svg-group" stroke="white">
<circle id="rect1" r="50" cx="200" cy="200" />
<circle
id="rect2"
stroke="white"
r="10"
cx="175"
cy="180"
fill="blue"
/>
<circle
id="rect3"
stroke="white"
r="10"
cx="225"
cy="180"
fill="blue"
/>
<circle id="rect4" r="30" cx="200" cy="200" fill="transparent" />
</g>
</defs>
<use xlink:href="#my-svg-group" x="110" />
</svg>
由于g标签本身不支持x/y坐标但是可以配合内嵌svg标签来实现设置坐标的功能
<svg class="box">
<g transform="translate(200,200)">
<rect
y="10"
width="100"
height="100"
style="stroke: #777; stroke-width: 3; fill: #07B492;"
/>
<text x="0" y="130" style="stroke: pink; fill: white">SVG</text>
</g>
</svg>
最后
本文的所有demo都可以在这里找到