乐趣区

数据可视化系列svg入门基础一

一、前言

1、SVG(Scalable Vector Graphics)可伸缩矢量图形

特点:

(1)使用 xml 格式来定义图形;

(2)用来定义 web 上的使用的矢量图;

(3)改变图像尺寸,图片质量不受损;

(4)所有元素属性可以使用动画;

(5)继承了 W3C 标准,在 html 中使用方式,html 直接嵌入 svg 内容,或者直接引入 svg 文件。

/ svg 标签,这里的 rect 为矩形,在后面的图形元素中会详细说明 /
<svg width=”200″ height=”200″>
<rect width=”20″ height=”20″ fill=”red”></rect>
</svg>

/ 引入后缀名为.svg 的文件 /
<img src=”demo.svg” alt=” 测试 svg 图片 ”>
注意:svg 为 inline 水平元素。且需要绘制的所有图形都应被包含在 <svg></svg> 标签内。

2、SVG 坐标系

特点:(1)y 轴向下;(2)顺时针方向的角度是正值。

注意:元素的所有操作都是相对自身坐标系进行的

3、颜色 RGB 和 HSL

RGB: 三个分量:红色、绿色、蓝色,每个分量的取值范围[0, 255],优点是显示器更容易解析。

HSL: 三个分量:颜色 h、饱和度 s%、亮度 l%,每个分量的取值范围分别是[0, 359], [0, 100%], [0, 100%],,其中,h= 0 表示红色,h= 0 表示 120 绿色,h= 0 表示 240 蓝色。

基于 HSL 的配色方案:http://paletton.com/

二、特殊元素

1、foreignObject

foreignObject 元素通常被用来在 svg 代码中嵌入 html 节点。注意:该属性对 IE 不支持。<foreignObject> 元素的作用是可以在其中使用具有其它 XML 命名空间的 XML 元素,换句话说借助 <foreignObject> 标签,我们可以直接在 SVG 内部嵌入 XHTML 元素。通常会与标签一起使用,在用户浏览器不支持时,告知用户。

举个例子:

<svg xmlns="http://www.w3.org/2000/svg">
  <foreignObject width="120" height="50">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p> 文字测试 foreignObject 的功能 </p>
      </body>
    </foreignObject>
</svg>

可以看到 <foreignObject> 标签里面有一个设置了 xmlns=”http://www.w3.org/1999/xhtml” 命名空间的 <body> 标签,此时 <body> 标签及其子标签都会按照 XHTML 标准渲染,实现了 SVG 和 XHTML 的混合使用。

这种混合特性有什么作用呢?作用很多,其中之一就是轻松实现 SVG 内的文本自动换行。

1.1 文本自动换行

SVG 要实现文本换行,往往需要手动阻断

<svg xmlns="http://www.w3.org/2000/svg">
  <text font-size="12">
    <tspan x="0" y="10"> 一段需要 word wrap</tspan>
    <tspan x="0" y="26"> 的文字。</tspan>
  </text>
</svg>

需要 2 个 <tspan> 元素,这一点都不工程。

但是如果使用 <foreignObject> 元素,则自动换行就是小菜:

<svg xmlns="http://www.w3.org/2000/svg">
  <foreignObject width="120" height="50">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p style="font-size:12px;margin:0;"> 一段需要 word wrap 的文字。</p>
      </body>
    </foreignObject>
</svg>

1.2 将页面上的 DOM 元素轻松变成图片

SVG <foreignObject> 元素还有其他更高级的应用,就是可以将页面上的 DOM 元素轻松变成图片。

原理:

1、获取对应 DOM 元素的 outerHTML 代码;

2、放在 <foreignObject> 元素中;

3、图片方式显示我们的 SVG 图形;

4、上一步的图片本质还是 SVG,我们可以借助 canvas drawImage()方法将图片放在画布上,然后使用 canvas.toDataURL()方法转换成 png 或 jpg 图片。

三、作用于 svg 标签的属性

1、viewport

表示 svg 的可见区域的大小:width 和 height,控制 svg 的宽度和高度

2、viewBox

定义用户视野的位置以及大小,即定义用来观察 SVG 视图一个矩形区域,更形象的解释就是:SVG 就像是我们的显示器屏幕,viewBox 就是截屏工具选中的那个框框,最终的呈现就是把框框中的截屏内容再次在显示器中全屏显示!

如:viewBox =’20 20 100 100’,前两个参数表示 viewBox 视野相对 svg 视图的 x y 坐标,后两个参数表示 viewBox 的大小。

与 svg 实际大小的关系如下:

如上图所示,用户可以看到的部分是蓝色的星星,而星星的另一侧是看不到的。

viewBox 的使用案例:

1、绘制矩形

<svg width="200" height="200" style="border: 2px solid #58a">
  <rect x="30" y="30" width="100" height="100" fill="#fb3" stroke="none"></rect>
</svg>

2、增加视野 viewBox viewBox=’0 0 100 100’,相当于用户只能看到 SVG 视图中 viewBox 定义的区域,即下图红色框内区域:

viewBox=”x, y, width, height” // x: 左上角横坐标,y: 左上角纵坐标,width: 宽度,height: 高度

   <svg width="200" height="200" style="border:2px solid #58a" viewBox='0 0 100 100'>
        <rect x="30" y="30" width="200" height="200" fill="#fb3" stroke="none"></rect>
   </svg>

最终效果图:

3、preserveAspectRatio 属性

这个属性也是作用于 <svg> 元素上,且作用对象都是 viewBox。

比如:

preserveAspectRatio="xMidYMid meet"

属性值为空格分隔的两个值组合而成。第一个值表示:viewBox 如何 viePort 对齐;第二个值表示:如何维持高宽比(可以为空)。

其中,第一个值又分为两个部分组成。前半部分表示 x 方向的对齐。后半部分表示 y 方向对齐。

值 含义
xMin viewport 和 viewBox 左边对齐
xMid viewport 和 viewBox 的 x 轴中心对齐
xMax viewport 和 vieBox 右边对齐
YMin viewport 和 viewBox 上边缘对齐。注意:Y 是大写
YMid viewport 和 viewBox 的 y 轴中心点对齐。注意:Y 是大写
YMax viewport 和 viewBox 下边缘对齐。注意:Y 是大写
xMaxYMax 表示右 - 下

xMidYMid 表示中 - 中

第二个值属性值支持

值 含义
meet 保持纵横比缩放 viewBox 适应 viewport,受
slice 保持纵横比,同时比例小的方向放大填满 viewport,攻
none 扭曲纵横比,充分适应 viewport,变态

1、图 1:红色区域为不设置 preserveaspectRatio 时的可视区域;

2、图 2: 采用与 x 轴左边对齐、与 y 轴上边缘对齐的方式,保持纵横比缩放;

3、图 3:保持纵横比的同时,以比例小的方向即 x 轴等比放大,填充 svg 区域

4、图 4:preserveaspectRatio=”none”,变形充分适应 svg

四、作用于 svg 内部元素的样式

svg 支持 css 选择器给元素添加样式

/* 定义样式 */
.rectStyle {fill: yellow;}
<svg width="200" height="200">
  <rect class="rectStyle" width="20" height="20"></rect>
</svg>

也可以直接在元素中设置样式:

<svg width="200" height="200">
  <rect width="20" height="20" fill="yellow"></rect>
</svg>

或者写成 style

<svg width="200" height="200">
  <rect style="fill: yellow;" width="20" height="20"></rect>
</svg>

常见的样式说明:

1、填充

(1)fill:定义填充颜色和文字颜色;

(2)fill-opacity:定义填充颜色的透明度;

(3)fill-rule:指定填充规则,符合填充规则才可被填充,取值:[nonzero | evenodd | inherit],默认值为 nonzero。

nonzero:该规则判断点任意方向的射线与图形路径的相交情况,默认为数值 0,射线从左到右时,每穿过一条路径,数值加 1;从右到左时,每穿过一条路径,数值减 1,最后结果若为 0,则表示点不在图形内部,不能填充。

evenodd:该规则判断点任意方向的射线与图形路径的相交情况,相交个数为奇数,则点在图形内部,可进行填充;反之在外部,不进行填充。

好像比较难理解这个,fill-rule 到底是为了解决什么问题?

我们看上图,图中有一个路径 A -B-C-D-E-F-G-H-I,当我们用 fill 填充它的时候,我们会发现其中有一个重叠的区域 S,那么这个重叠的区域到底填不填充呢?这,就是 fill-rule 所干的事。

分析:沿着 A -B-C-D-E-F-G-H- I 方向走,我们会发现重叠区域 S 外部为 A -B-C-D-A,形成方向为顺时针方向。重叠外部区域 S 的形成方向为逆时针 H -I-A,所以重叠区域 S 不显示。这个和 fill-rule 设置无关,这是默认的。

来看一下经典的五角星问题:

相同的,这里有一个重叠区域 S,不过如何才能知道是重叠区域呢?其实很简单,就是重叠区域的外面还有东西,而它们都还在整个形状之内。

我们可以发现五角星的重叠区域 S 的形成方向和外部是一样的,这种情况下,fill-rule 就起作用了,如果是 nonzero,区域 S 是显示的,如果是 evenodd,区域 S 则不显示。

2、边框

(1)stroke:边框颜色;

(2)stroke-width:边框宽度;

(3)stroke-opacity:边框透明,取值[0,1];

(4)stroke-linecap:单条线端点样式,一般应用于直线或者路径,取值:[butt | square | round],分别是对接、方形和圆形

(5)stroke-dasharray:虚线边框,可以设置每段虚线的长度和间隔,之间使用逗号分隔或者空格分隔,如:

stroke-dasharray="10, 5, 5, 10"

(6)stroke-dashoffset:设置虚线描边偏移量,使图案向前移动

 <svg width="200" height="200" viewBox='0 0 300 300'>
    <line x1="20" y1="20" x2="120" y2="20"
        stroke="red" stroke-width="5" stroke-linecap="butt"
        stroke-dasharray="20 5 5 10">
    </line>
    <line x1="20" y1="60" x2="120" y2="60"
        stroke="red" stroke-width="5" stroke-linecap="butt"
        stroke-dasharray="20 5 5 10" stroke-dashoffset="10">
    </line>
   </svg>

虚线的样式为 20 5 5 10,偏移量为 10,根据下图可发现第二个虚线,整体向前移动了 10 个单位

(7)sroke-linejoin:两条线段之间衔接点的样式,取值:[miter | round | bevel],分别是尖角 (图左一)、圆角(图左二) 和斜角(图左三)

(8)sroke-miterlimit:默认值 4,当 miterLength / stroke-width < stroke-miterlimit 时,stroke-linejoin 值会变成换成 bevel 斜角。如下图中,stroke-width 为 15,根据计算公式,miterLength / stroke-width 约等于 5.2,即当 stroke-miterlimit 小于 6 时,stroke-linejoin 值会变成 bevel 斜角。

3、透明度

opacity:定义整个图形的透明度

4、字体

(1)font-size:字体大小;

(2)font-family:字体系列的名称;

(3)font-weight:字体粗细;

(4)font-style:字体样式,斜体和正常;

(5)text-decoration:下划线样式;

(6)text-anchor:设置文本的排列属性,属性值[start | middle | end | inherit],如:middle 表示,将文字定位原点移动至文字中心。

5、变换

基础概念同 css。

(1)transform:同 css,默认是左上角为旋转中心,如:transform=”rotate(30)”;

(2)transform-origin:同 css,设置旋转的操作中心;

(3)rotate:设置文字元素的旋转角度,正值为顺时针旋转,注意区分 rotate 和 transform 中的 rotate,如 rotate=”30″

而 transform 中的 rotate 是对整个元素进行旋转操作。

 <svg width="200" height="200">
    <text x="10" y="10" dx="10" dy="10" textLength="100" rotate="20"> 示例文字 1 </text>
   </svg>
   <svg width="200" height="200">
    <text x="10" y="10" dx="10" dy="10" textLength="100" transform="rotate(20)"> 示例文字 2 </text>
   </svg>

五、参考

1、http://www.runoob.http://www.runoob.com/svg/svg-tutorial.html

2、http://qiutianaimeili.com/htm…

【谢谢关注和阅读,后续新的文章首发:sau 交流学习社区:https://www.mwcxs.top/】

退出移动版