一、前言
学习d3可视化的过程中,了解到其中对svg的使用,因此,借此机会学习一下svg。学习的知识来自菜鸟教程,本文只是一篇笔记。
二、关于样式
1、设置方式
在svg中,可以通过style属性注入样式,也可以将属性独立出来进行设置,举一个简单的例子
<svg>
<!-- 第一种方式 -->
<rect width='100' height='100' fill='skyblue' stroke-width='1' stroke='#ffff00'/>
<!-- 第二种方式 -->
<rect style="width: 100; height:100; fill: skyblue; stroke-width: 1; stroke: #ffff00"/>
</svg>
这两种写法实现的效果如下图所示
图 2.1.1
2、优先级
既然svg中存在两种设置样式的方式,那么很容易想到,如果同时采用两种方式去设置样式,实际的效果会以谁为准呢?还是以上面的矩形举个例子:
<svg>
<rect width='100' style='width: 200; height:100; fill: skyblue; stroke-width: 1; stroke:#ffff00'/>
</svg>
效果如图所示:
图 2.2.1
从图中可以看到,生效的是 style属性 内的width,因此优先级上style会高些
3、一些常用属性介绍
- fill:定义填充颜色(rgb 值、颜色名或者十六进制值)
- fill-opacity:定义填充颜色透明度(合法的范围是:0 - 1)
- stroke-width:定义边框宽度
- stroke:定义边框颜色
- stroke-dasharray:创建虚线
- stroke-opacity:定义边框颜色的透明度(合法的范围是:0 - 1)
注意:所有stroke属性,可应用于任何种类的线条,文字和元素就像一个圆的轮廓。
三、svg中的坐标系
四、预定义的形状元素
1、rect (矩形)
- 作用:用来创建矩形以及矩形的变种
- 属性:
- x:矩形起始 x 轴坐标(矩形左上角,默认为 0)
- y:矩形起始 y 轴坐标(矩形左上角,默认为 0)
- rx:定义水平方向圆角尺寸
- ry:定义垂直方向圆角尺寸
注意点:当未指定矩形的 width 或 height 属性时,矩形不展示
举几个例子说明一下
<svg width='400' height='400' style='display: block'>
<rect width='100' height='100' x='10' y='10' fill='blue'/>
<rect width='100' height='100' x='140' y='10' fill='yellow'/>
<rect width='100' height='100' x='10' y='140' fill='red'/>
</svg>
图 4.1.1
如图 4.1.1所示,通过改变 x 和 y 属性的值,改变了矩形在 svg 中的位置。
rx、ry的使用
还是先举个例子,在上面的基础上加入 rx、ry属性
<svg width='400' height='400' style='display: block'>
<rect width='100' height='100' x='10' y='10' rx='10' fill='blue'/>
<rect width='100' height='100' x='140' y='10' rx='10' ry='30' fill='yellow'/>
<rect width='100' height='100' x='10' y='140' rx='10' ry='70' fill='red'/>
<rect width='100' height='100' x='140' y='140' rx='70' ry='70' fill='pink'/>
</svg>
图 4.1.2
如图4.1.2所示,rx 和 ry 设置后会同时作用于矩形的四个角,产生的圆弧类似于图4.1.3,该圆弧会作用于四个角
图 4.1.3
对于 rx 和 ry 的其他介绍,可以参考 图4.1.4 和 链接
图 4.1.4
2、circle (圆形)
- 作用:用来创建圆形
- 属性:
- cx:圆形圆心 x 轴坐标(默认为 0)
- cy:圆形圆心 y 轴坐标(默认为 0)
- r:定义圆的半径
举个例子
<svg width='200' height='200' style='display: block; background-color: #333'>
<circle cx='0' cy='60' r='40' fill='blue'/>
<circle cx='120' cy='60' r='40' fill='yellow'/>
<circle cx='120' cy='180' r='40' fill='red'/>
</svg>
图 4.2.1
3、ellipse(椭圆)
- 作用:用来创建圆形
- 属性:
- cx:定义椭圆中心的 x 坐标(默认为 0)
- cy:定义椭圆中心的 y 坐标(默认为 0)
- rx:定义椭圆的水平半径
- ry:定义椭圆的垂直半径
举个例子
<svg width='300' height='300' style='display: block; background-color: #333'>
<ellipse rx="100" ry="40" fill='yellow'/>
<ellipse cx="150" cy="150" rx="100" ry="40" style="fill:red" />
</svg>
图 4.3.1
4、line(直线)
- 作用:用来创建直线
- 属性:
- x1:直线起点 x 坐标
- y1:直线起点 y 坐标
- x2:直线终点 x 坐标
- y2:直线终点 y 坐标
举个例子
<svg width='200' height='200' style='display: block; background-color: #333'>
<line x1='10' y1='10' x2='180' y2='50' stroke='yellow'stroke-width='3'/>
<line x1='10' y1='100' x2='180' y2='150' stroke='yellow'
stroke-width='3' stroke-dasharray='10,5'/>
<line x1='10' y1='130' x2='180' y2='170' stroke='yellow'
stroke-width='3' stroke-dasharray='10,5,6'/>
</svg>
图 4.4.1
从效果图4.4.1中我们可以看到 stroke-dasharray 对线条的影响。我的理解是虚线总是 “实虚实虚实虚……”这样轮回出现,stroke-dasharray 后的数据就代表每一段实线或虚线的长度,这里采用数组(仅描述对应关系,与真实原理无关)的方式展示一下
// 以 stroke-dasharray='10,5' 为例
const line = [
{
state: '实线',
length: 10
},
{
state: '虚线',
length: 5
},
{
state: '实线',
length: 10
},
{
state: '虚线',
length: 5
}
// …………
]
对于 stroke-dasharray='5' 这样的情况,等同于 stroke-dasharray='5, 5'。 同样的,对于第三条线的 stroke-dasharray, 我们也采用数组的方式展示,展示如下
const line = [
{
state: '实线',
length: 10
},
{
state: '虚线',
length: 5
},
{
state: '实线',
length: 6
},
{
state: '虚线',
length: 10
},
{
state: '实线',
length: 5
},
{
state: '虚线',
length: 6
},
{
state: '实线',
length: 10
},
{
state: '虚线',
length: 5
}
// …………
]
5、polygon(多边形)
- 作用:用来创建含有不少于三个边的图形
- 属性:
- points:定义多边形每个角的 x 和 y 坐标
举个例子
<svg width='300' height='300' style='display: block; background-color: #333'>
<polygon points='60,60 60,210 210,210 210, 60 ' fill='yellow'/>
</svg>
图 4.5.1
从 图4.5.1 中,我们可以看到再给定了四个坐标后,绘制了一个矩形,那么问题来了,不同坐标的顺序可不可以更改呢?假设我们更改一下 (210, 60)和(210, 210)的坐标,得到的结果会不会相同? 更改后的svg如下
<svg width='300' height='300' style='display: block; background-color: #333'>
<polygon points='60,60 60,210 210, 60 210,210' fill='yellow'/>
</svg>
图 4.5.2
从图中我们看到,虽然四个坐标还是和原先一样,但是,得到的几何图形却有了很大的差别,我的理解是 points 连线走向与坐标顺序一致,当连完最后一个坐标后,polygon 会将末级坐标与首坐标连线,形成闭合,若是不希望末级与首级连线,可以改用 polyline 标签,如图 4.5.3 所示,对于黄色的正方形边框进行了首尾相连,但是另一个并没有。
polyline 与 polygon 区别
<svg width='300' height='300' style='display: block; background-color: #333'>
<polyline points='50,20 110,20 110,80 50,80'
stroke-width='5'
fill='#eee' stroke='red'/>
<polygon points='70,130 130,130 130,190 70,190'
stroke-width='5'
fill='yellow' stroke='red'/>
</svg>
图 4.5.3
在多边形中,还有一个重要的概念就是多边形的内部和外部,也就是 fill-rule 的作用规则,这里以菜鸟教程中的两个五角星为例
<svg height="210" width="500" style='background-color: #333'>
<text x="5" y="20" fill="#eee" font-size='12'>五角星1号</text>
<polygon points="100,10 40,198 190,78 10,78 160,198"
style="fill:yellow;stroke:#eee;stroke-width:5;fill-rule:nonzero;" />
<text x="265" y="20" fill="#eee" font-size='12'>五角星2号</text>
<polygon points="350,10 290,198 440,78 260,78 410,198"
style="fill:yellow;stroke:#eee;stroke-width:5;fill-rule:evenodd;" />
</svg>
图 4.5.4
从图4.5.4 中我们可以看到,当改变 fill-rule 的属性后,五角星颜色的填充发生了改变,也就是对于多边形内与外的定义发生了改变,那么fill-rule 的属性有哪些,又是怎么去判断多边形内界与外界呢?
首先,我们来看看fill-rule 的属性有哪些
| 属性值 | 是否默认 | 备注 |
|---|---|---|
| nonzero | 是 | |
| evenodd | ||
| inherit | 继承父级 |
关于 nonzero 值,字面意思是“非零”。按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点情况。从0开始计数,路径从左向右穿过射线则计数加1,从右向左穿过射线则计数减1。得出计数结果后,如果结果是0,则认为点在图形外部,否则认为在内部。图4.5.5 演示了nonzero规则:
图 4.5.5
从图4.5.5 中可以看到,我们设置的五角星1号的坐标点绘制的图形路径是 A >> B >> C >> D >> E,整体是一个逆时针的走向,我们在五角星内任取一点,向外做射线(不考略平行、交点的情况),得到的结果都不为0,因此 fill 会填充整个五角星。
关于 evenodd 值,字面意思是“奇偶”。按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点的数量。如果结果是奇数则认为点在内部,是偶数则认为点在外部。
还是以图4.5.5为例(由于是任意射线,还是不考虑平行、交点等特殊情况),在五角星的每个角内区域取点做射线,得到的交点结果为 1 或 3,因此每个角属于内部。在中心的五边形区域内取点做射线,得到的交点数为 2,因此中心五边形区域属于外部,所以 fill 不填充该区域,效果图为图4.5.4五角星2号。
6、path(路径)
-
作用:用来定义一条路径
-
部分属性:
- M:路径起始
- L:L命令将会在当前位置和新位置(L前面画笔所在的点)之间画一条线段。
- H:绘制一条经过当前点的水平线
- V:绘制一条经过当前点的垂直线
- Q: 二次贝塞尔曲线
- Z: 路径闭合。命令会从当前点画一条直线到路径的起点
贝塞尔曲线示例:www.cnblogs.com/hnfxs/p/314…
贝塞尔理论讲解:juejin.cn/post/697063…