SVG学习笔记

173 阅读6分钟

一、前言

学习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

图一.png

2、优先级

既然svg中存在两种设置样式的方式,那么很容易想到,如果同时采用两种方式去设置样式,实际的效果会以谁为准呢?还是以上面的矩形举个例子:

<svg>
  <rect width='100' style='width: 200; height:100; fill: skyblue; stroke-width: 1; stroke:#ffff00'/>
</svg>

效果如图所示:

图 2.2.1

image.png

从图中可以看到,生效的是 style属性 内的width,因此优先级上style会高些

3、一些常用属性介绍

  • fill:定义填充颜色(rgb 值、颜色名或者十六进制值)
  • fill-opacity:定义填充颜色透明度(合法的范围是:0 - 1)
  • stroke-width:定义边框宽度
  • stroke:定义边框颜色
  • stroke-dasharray:创建虚线
  • stroke-opacity:定义边框颜色的透明度(合法的范围是:0 - 1)

注意:所有stroke属性,可应用于任何种类的线条,文字和元素就像一个圆的轮廓。

三、svg中的坐标系

image.png

四、预定义的形状元素

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

image.png

如图 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

image.png

如图4.1.2所示,rx 和 ry 设置后会同时作用于矩形的四个角,产生的圆弧类似于图4.1.3,该圆弧会作用于四个角

图 4.1.3

image.png

对于 rx 和 ry 的其他介绍,可以参考 图4.1.4 和 链接

图 4.1.4

image.png

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

image.png

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

image.png

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

image.png

从效果图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

image.png

从 图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

image.png

从图中我们看到,虽然四个坐标还是和原先一样,但是,得到的几何图形却有了很大的差别,我的理解是 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

image.png

在多边形中,还有一个重要的概念就是多边形的内部和外部,也就是 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

image.png

从图4.5.4 中我们可以看到,当改变 fill-rule 的属性后,五角星颜色的填充发生了改变,也就是对于多边形内与外的定义发生了改变,那么fill-rule 的属性有哪些,又是怎么去判断多边形内界与外界呢?

首先,我们来看看fill-rule 的属性有哪些

属性值是否默认备注
nonzero
evenodd
inherit继承父级

关于 nonzero 值,字面意思是“非零”。按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点情况。从0开始计数,路径从左向右穿过射线则计数加1从右向左穿过射线则计数减1。得出计数结果后,如果结果是0,则认为点在图形外部,否则认为在内部。图4.5.5 演示了nonzero规则:

图 4.5.5

image.png

从图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…