3

一、栅格图形和矢量图形

栅格图形:也称位图,图像由一组二维像素网格表示。
Canvas 2d API 就是一款栅格图形 API。通过 Canvas API 绘制图形,其实是更新 Canvas 的像素。PNG 和 JPEG 是两种栅格图形的格式。即 PNG 和 JPEG 图像中的数据也同样代表着像素。
矢量图形:图像由数学描述的几何形状表示。矢量图像包括使用高级几何形状(比如线和形状)绘制图像所需的全部信息。
SVG 是矢量图形的一种,同 HTML 一样,SVG 是一种文件格式,有自己的 API。SVG 同 DOM API 结合形成了一种矢量图形 API。尽管可以将 PNG 等栅格图形嵌入到 SVG 中,但从根本上讲,SVG 是一种矢量格式。

二、理解 SVG

SVG 的本质特征是它基于 XML。HTML5 引入了内连 SVG,所以 SVG 元素可以直接出现在 HTML 标记中。

SVG 和 Canvas 的重要差异:
(1)SVG 绘制的文本可选,而 Canvas 不能(因为 Canvas 文本用像素绘制,是图像的一部分);
(2)SVG 上的文本是可搜索的,Canvas 上的文本无法被搜索引擎获取。

HTML 是用来定义页面结构的声明性语言,而 SVG 是用来创建视觉结构的语言。通过 DOM API ,你可以与 SVG 和 HTML 进行交互。SVG 文档是元素构成的树状结构,同 HTML 一样,它支持脚本操作和添加样式,还可以向 SVG 元素添加事件处理函数。

图形 API 设计方面存在两个派系:
一是即时模式(immediate-mode):图形提供了绘图接口,由 API 接口调用引起的绘制行为会即时发生。如 Canvas。
二是保留模式(retained-mode):在保留模式图形中,有一个与场景中的视觉对象对应的模型,它会随着时间的推移而保留下来。可以使用 API 操作场景图形,当其改变时,图形引擎会重绘场景。SVG 是一种保留模式图形,其场景图形就是文档。用于操作 SVG 的 API 是 W3C DOM API。

SVG 文档在呈现时会保留构成它的矢量信息,缩放 SVG 时,渲染程序会立即重绘所有构成图像的线条。所以,缩放 SVG 不会导致其质量下降。而 Canvas 缩放时图像会模糊,原因是图像由像素组成,且只能在更高分辨率下重新采样。

三、使用 SVG 创建 2D 图形

(1)在页面中添加 SVG

添加内联 SVG 到 HTML 页面中如同添加其他元素一样简单。svg 标签的开始标记和结束标记之间,可以添加一些形状和其他视觉对象。还可以在 HTML 中以静态图像的方式引用 SVG 文件,例如:


    <img src="example.svg">

不过这种方式的缺点是:SVG 文档不能像内联 SVG 内容那样集成到 DOM 中,即无法编写与 SVG 元素进行交互的脚本。
(2)简单的形状
SVG 语言包含了基本的形状元素,如矩形、圆形和椭圆。形状元素的尺寸和位置被定义成了属性。如:矩形的属性有 width 和 height。圆形有一个表示半径的 r 属性。和 css 一样,距离单位包括 px,em 等。
示例:


    <svg width="200" height="200">
         <rect x="10" y="10" width="100" height="80" stroke="red" fill="#ccc" />
        <circle cx="120" cy="80" r="40" stroke="#00f" fill="none" stroke-width="8" />
    </svg>

SVG 绘制形状对象时是按对象在文档中出现的顺序进行的。
SVG 实用的坐标系统与 Canvas API 相同,svg 元素的左上角位置的坐标是(0,0)。
(3)变换 SVG 元素
SVG 中有些组织元素,可用于将多个元素结合起来,使它们作为一个整体进行变换或链接。<g> 元素代表“组”(group)。组可以用来结合多个相关的元素。组内成员可由通用 ID 来引用。此外,组也可以作为一个一个整体进行变换。
示例:


    <svg width="200" height="200">
         <g transform="translate(-10, 350)"
          stroke-width="20"
          stroke-linejoin="round">
            <path d="M0,0 Q170,-50 260, -190 Q310, -250 410,-250"
              fill="none" />
          </g>
    </svg>

(4)复用内容
SVG 中的 <defs> 元素用于定义留待将来使用的内容(折合 react/vue 中的组件功能类似)。SVG 中的 <use> 元素用于链接到 <defs> 元素定义的内容。借助这两个元素。可以多次复用同一内容,消除冗余。
示例:


    <svg width="200" height="200">
      <defs>
        <g id="shapeGroup">
          <rect x="10" y="10" width="100" height="80" stroke="red" fill="#ccc" />
          <circle cx="120" cy="80" r="40" stroke="#00f" fill="none" stroke-width="8" />
        </g>
      </defs>
      <use xlink:href="#shapeGroup" transform="translate(20,0) scale(0.5)" />
      <use xlink:href="#shapeGroup" transform="translate(50,0) scale(0.7)" />
      <use xlink:href="#shapeGroup" transform="translate(80,0) scale(0.25)" />
    </svg>

(5)图案和渐变
图案类似于 Canvas 中的背景图做法。渐变也分为线性渐变和放射性渐变,和 Canvas 类似。
示例:


    <svg width="200" height="200">
      <defs>
        <pattern id="GravelPattern" patternUnits="userSpaceOnUse" x="0" y="0" width="100" height="67" viewBox="0 0 100 67">
        <image x="0" y="0" width="100" height="67" xlink:href:"gravel.jpg"></image>
        </pattern>
        <linearGradient id="Gradient">
          <stop offset="0%" stop-color="#000"></stop>
          <stop offset="100%" stop-color="#f00"></stop>
        </linearGradient>
      </defs>
      <rect x="10" y="10" width="100" height="80" stroke="red" fill="url(#Gradient)" />
     <circle cx="120" cy="80" r="40" stroke="#00f" fill="url(#GravelPattern)" stroke-width="8" />
    </svg>

(6)SVG 路径
SVG 不仅包含简单的形状,还包含自由形态的路径。path 元素有一个 d 属性。d 代表数据(data)。在 d 属性的值中,你能够指定一系列的路径绘制命令。每条命令都可能带有坐标参数。一些命令的含义为:M 代表移至(moveto),L 代表划线至(lineto),Q 代表二次曲线, Z 代表闭合曲线。
(7)SVG 文本
示例:


<svg width="200" height="200">
  <text x="10" y="80" font-family="Droid Sans" stroke="#00f" fill="#00f" font-size="18px">
   hello SVG
  </text>
</svg>

四、组合场景

完整示例:
https://jsfiddle.net/linda102...


linda102
26 声望3 粉丝

前端,阅读,书法,摄影