Skip to the content.

SVG

[SVG规范] SVG - MDN
Scalable Vector Graphics (SVG) 2 - W3C
SVG 教程 - MDN
SVG 元素参考 - MDN
SVG 属性参考 - MDN
SVG 接口参考 - MDN
SVG 工具 - MDN

目录

1.1 基础

1.1.1 SVG 的基本形式

SVG 可直接潜入 HTML 代码中,也可作为单独文件使用

SVG 的基本形式:

<svg version="1.1"
     baseProfile="full"
     width="300" height="200"
     xmlns="http://www.w3.org/2000/svg">
</svg>

SVG 作为单独文件时为 xml 文件,后缀 .svg.svgz(压缩格式,由于兼容性原因,不推荐使用)

SVG 文件的受用:

<!-- 兼容性较好 -->
<!-- object -->
<object data="image.svg" type="image/svg+xml" />
<!-- iframe -->
<iframe src="image.svg"></iframe>

<!-- 低于4.0版本的Firefox 中不起作用 -->
<!-- image -->
<img srv="image.svg">

SVG 直接嵌入 HTML - 直接将 SVG 文件的内容写入 HTML 中(支持 HTML5 时才可生效)

<svg version="1.1"
     baseProfile="full"
     width="300" height="200"
     xmlns="http://www.w3.org/2000/svg">
</svg>

1.1.2 SVG 的 世界 视野 视窗

理想情况下 视窗和视野尺寸一致,浏览器可以完美的将视野填充到视窗内;如果视窗与视野的尺寸不一致,就有如何填充的问题,可使用 preserveAspectRatio 控制。

1.1.3 SVG 的图形分组

<g /> - 把属性赋给一整个元素集合。这是它唯一的目的。

<g fill="red">
  <rect x="0" y="0" width="10" height="10" />
  <rect x="20" y="0" width="10" height="10" />
</g>

1.1.4 坐标系统

SVG 的 坐标与 Canvas 的坐标相同(计算机的绘图系统基本采用相同的坐标系统),但与数学中的坐标有较大差异。

1.1.5 四种坐标系

  1. 用户坐标系:也叫做原始坐标系,基于世界的坐标系,视野的定义时基于用户坐标系的
  2. 自身坐标系:每一个图形或者分组都会产生一个自身坐标系,自身坐标系用于定义一些自身属性
  3. 前驱坐标系:父容器的坐标系,前驱坐标系通过 transform 变换之后形成图形的自身坐标系
  4. 参考坐标系:对一个图形进行观潮测量时使用的坐标系

1.1.6 坐标变换

1.1.6.1 定义

1.1.6.2 线性变换

线性变换方程:

x` = ax + cy + e
y` = bx + dy + f

变换矩阵:

|a c e|
|b d f|
|0 0 1|

1.1.6.3 平移

···text x = 1x + 0y + 10 y = 0x + 1y + 10

|1 0 10| |0 1 10| |0 0 1| ···

1.1.6.4 旋转

使用极坐标变换矩阵

极坐标方程:

x = r*cos(α)
x = r*sin(α)

旋转 θ 度

x = r*cos(α + θ)
x = r*sin(α + θ)

X'=r⋅cos(α)cos(θ) − r⋅sin(α)sin(θ) = cos(θ)X − sin(θ)Y + 0
Y'=r⋅cos(α)sin(θ) + r⋅sin(α)cos(θ) = sin(θ)X + cos(θ)Y + 0

|cos(θ) -sin(θ) 0|
|sin(θ) cos(θ)  0|
|0      0       1|

1.1.6.5 缩放

1.1.6.6 transform 属性

定义前驱坐标系到⾃自⾝身坐标系的线性变换

transform - MDN
Chapter 8: Coordinate Systems, Transformations and Units - W3C

所有接下来的变形都会用一个元素的 transform 属性总结。变形可以连缀,只要把它们连接起来就行,用空格隔开。

如果使用了变形,你会在元素内部建立了一个新的坐标系统,应用了这些变形,你为该元素和它的子元素指定的单位可能不是 1:1 像素映射。但是依然会根据这个变形进行歪曲、斜切、转换、缩放操作。

SVG 允许你无缝嵌入别的 SVG 元素。因此你可以利用内部 SVG 元素的属性viewBox、属性 width 和属性 height 简单创建一个新的坐标系统。

<!-- 矩形将是指定的两倍大 -->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <svg width="100" height="100" viewBox="0 0 50 50">
    <rect width="50" height="50" />
  </svg>
</svg> 
<rect x="0" y="0" width="10" height="10" transform="translate(30,40)" />
<rect x="20" y="20" width="20" height="20" transform="rotate(45)" />

1.1.7 坐标观察

2.1 基本形状

2.1.1 矩形 - <rect>

<rect />

2.1 基本形状 矩形

2.1.1 rect

<rect x="10" y="10" width="30" height="30" />
<rect x="60" y="10" rx="10" ry="10" width="30" height="30" />

2.1.2 圆形 - <circle>

<circle />

2.1 基本形状 圆形

2.1.2 circle

<circle cx="25" cy="75" r="20" />

2.1.3 椭圆 - <ellipse>

<ellipse />

2.1 基本形状 椭圆

2.1.3 ellipse

<ellipse cx="75" cy="75" rx="20" ry="5" />

2.1.4 线条 - <line>

<line />

2.1 基本形状 线条

2.1.4 line

<line x1="10" x2="50" y1="110" y2="150" />

2.1.5 折线 - <polyline>

<polyline />

2.1 基本形状 折线

2.1.5 polyline

<polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145" />

2.1.6 多边形 - <polygon>

<polygon />

2.1 基本形状 多边形

2.1.6 polygon

<polygon points="50 160, 55 180, 70 180, 60 190, 65 205, 50 195, 35 205, 40 190, 30 180, 45 180" />

2.1.7 路径 - <path>

<path />

<path d="M 20 230 Q 40 205, 50 230 T 90230" />

<path> 非常强大,但导致 d 的使用非常多样,这是灵活的代价。

2.1 基本形状 路径

2.2 - d

以下元素可以使用 d 属性:

<path>
<glyph>

同样的规则可以应用到 <animate> 动画路径上。

属性 d 实际上是一个字符串,包含了一系列路径描述。这些路径由下面这些指令组成:

这些命令是大小写敏感的;

可以指定一个负数值作为命令的参数:

2.2.1 Moveto

作用:

用一个 Moveto 命令开始一个路径是好的作法,因为如果没有一个初始化的 Moveto,执行命令时开始点会是上一个操作发生过的地方,这样可能造成不确定的行为。

语法:

<!-- 位于绝对位置x=50, y= 100: -->
<path d="M50,100..." />
<!-- 往右移50,往下移100: -->
<path d="m50,100..." />

2.2 d d - 画直线

2.2.2 Lineto

作用:

语法:

2.2 d d - 画直线

2.2.3 Curveto

作用:

有两种类型的贝塞尔曲线:立方曲线和二次方曲线。

语法:

为了连缀平滑的贝塞尔曲线,还可以使用 TS 命令。它们的语法比别的Curveto 命令简单,因为它假定第一个控制点是从前一个控制点关于前一个点的反射,或者说如果没有前一个控制点的话它实际上就是前一个点。

2.2 d d - 画曲线

2.2.4 Arcto

作用:

语法:

2.2 d d - 画弧线

2.2.5 ClosePath

作用:

它是最简单的命令,而且不带有任何参数。它沿着到开始点的最短的线性路径,如果别的路径落在这路上,将可能路径相交。

语法:

2.2.6 综合d

d=" M37,17 || v15 || H14 || V17 || H37 ||z // M50,0 || H0 || v50 || h50 || V0 || z"

2.2 d d - 属性的综合示例

2.3 基本属性

  1. 可以使用在 HTML 中的 CSS颜色 命名方案定义 fillstroke 的颜色,比如说颜色名(red)、rgb值(rgb(255,0,0))、十六进制值、rgba值,等等
  2. 出于兼容性考虑,不要使用 rgba 颜色,透明度可通过 fill-opacitystroke-opacity 设置,不要混用 rgba 颜色 和 *-opacity,会有意想不到的结果,造成混乱

2.3.1 填充

2.3.2 描边

描边是以路径为中心线绘制的,路径的每一侧都有均匀分布的描边

<?xml version="1.0" standalone="no"?>
<svg width="160" height="140" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <line x1="40" x2="120" y1="20" y2="20" stroke="#333" stroke-width="20" stroke-linecap="butt"/>
  <text x="40" y="45">stroke-linecap="butt"</text>

  <line x1="40" x2="120" y1="60" y2="60" stroke="#333" stroke-width="20" stroke-linecap="square"/>
  <text x="40" y="85">stroke-linecap="square"</text>

  <line x1="40" x2="120" y1="100" y2="100" stroke="#333" stroke-width="20" stroke-linecap="round"/>
  <text x="40" y="125">stroke-linecap="round"</text>
</svg>

<?xml version=”1.0” standalone=”no”?>

stroke-linecap="butt" stroke-linecap="square" stroke-linecap="round"

<?xml version=”1.0” standalone=”no”?>

stroke-linejoin="miter" stroke-linejoin="round" stroke-linejoin="bevel"
<?xml version="1.0" standalone="no"?>
<svg width="200" height="150" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <path d="M 10 75 Q 50 10 100 75 T 190 75" stroke="#333"
    stroke-linecap="round" stroke-dasharray="5,10,5" fill="none"/>
    
  <path d="M 10 75 L 190 75" stroke="red"
    stroke-linecap="round" stroke-width="1" stroke-dasharray="5,5" fill="none"/>
</svg>

<?xml version=”1.0” standalone=”no”?>

在上面的例子里,第二个路径会先做5个像素单位的填色,紧接着是5个空白单位,然后又是5个单位的填色。如果你想要更复杂的虚线模式,你可以定义更多的数字。第一个例子指定了3个数字,这种情况下,数字会循环两次,形成一个偶数的虚线模式(奇数个循环两次变偶数个)。所以该路径首先渲染5个填色单位,10个空白单位,5个填色单位,然后回头以这3个数字做一次循环,但是这次是创建5个空白单位,10个填色单位,5个空白单位。通过这两次循环得到偶数模式,并将这个偶数模式不断重复。

2.3.3 使用 CSS

所有的SVG元素的初始display值都是inline。

除了定义对象的属性外,也可以通过 CSS 来样式化填充和描边。语法和在 html 里使用 CSS 一样,只不过你要把 background-colorborder 改成 fillstroke。注意,不是所有的属性都能用 CSS 来设置。上色和填充的部分一般是可以用 CSS 来设置的,比如 fillstrokestroke-dasharray 等,但是不包括渐变和图案等功能。另外,widthheight,以及路径的命令等等,都不能用 CSS 设置

SVG规范 将属性区分成 properties 和其他 attributes ,前者是可以用 CSS 设置的,后者不能。

<rect x="10" height="180" y="10" width="180" style="stroke: black; fill: red;"/>
<?xml version="1.0" standalone="no"?>
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <style type="text/css"><![CDATA[
       #MyRect {
         stroke: black;
         fill: red;
       }
    ]]></style>
  </defs>
  <rect x="10" height="180" y="10" width="180" id="MyRect"/>
</svg>

<?xml version=”1.0” standalone=”no”?>

<?xml version="1.0" standalone="no"?>
<?xml-stylesheet type="text/css" href="style.css"?>

<svg width="200" height="150" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <rect height="10" width="10" id="MyRect"/>
</svg>

2.4 渐变

2.4.1 线性渐变

x1y1 \ x2y2

<linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">

xlink:href

 <linearGradient id="Gradient1">
   <stop id="stop1" offset="0%"/>
   <stop id="stop2" offset="50%"/>
   <stop id="stop3" offset="100%"/>
 </linearGradient>
 <linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1"
    xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#Gradient1"/>

<stop>

<stop offset="100%" stop-color="yellow" stop-opacity="0.5"/>

线性渐变内部有几个 <stop> 结点,这些结点通过指定位置的 offset(偏移)属性和 stop-color(颜色中值)属性来说明在渐变的特定位置上应该是什么颜色

<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
      <!-- 通过 style 设置渐变 -->
      <linearGradient id="Gradient1">
        <stop class="stop1" offset="0%"/>
        <stop class="stop2" offset="50%"/>
        <stop class="stop3" offset="100%"/>
      </linearGradient>
      <!-- 直接设置渐变属性 -->
      <linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
        <stop offset="0%" stop-color="red"/>
        <stop offset="50%" stop-color="black" stop-opacity="0"/>
        <stop offset="100%" stop-color="blue"/>
      </linearGradient>
      <!-- style -->
      <!-- 通过 Id 关联 -->
      <style type="text/css"><![CDATA[
       #rect1 { fill: url(#Gradient1); }
        .stop1 { stop-color: red; }
        .stop2 { stop-color: black; stop-opacity: 0; }
        .stop3 { stop-color: blue; }
      ]]></style>
  </defs>
 
 <!-- 通过 style 设置渐变 -->
  <rect id="rect1" x="10" y="10" rx="15" ry="15" width="100" height="100"/>
  <!-- 直接设置渐变属性 -->
  <rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#Gradient2)"/>
  
</svg>

2.4 渐变 渐变 - 线性渐变

2.4.2 径向渐变

<?xml version=”1.0” standalone=”no”?>

(fx,fy) (cx,cy)
<?xml version="1.0" standalone="no"?>
<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
      <radialGradient id="RadialGradient1">
        <stop offset="0%" stop-color="red"/>
        <stop offset="100%" stop-color="blue"/>
      </radialGradient>
      <radialGradient id="RadialGradient2" cx="0.25" cy="0.25" r="0.25">
        <stop offset="0%" stop-color="red"/>
        <stop offset="100%" stop-color="blue"/>
      </radialGradient>
  </defs>
 
  <rect x="10" y="10" rx="15" ry="15" width="100" height="100" fill="url(#RadialGradient1)"/> 
  <rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#RadialGradient2)"/> 
  
</svg>

<?xml version=”1.0” standalone=”no”?>

2.4 渐变 渐变 - 径向渐变

2.4.3 通用属性

线性渐变和径向渐变都需要一些额外的属性用于描述渐变过程

<?xml version=”1.0” standalone=”no”?>

Pad Repeat Reflect

2.4 渐变 渐变 - 径向渐变

2.5 笔刷

跟渐变一样,[](https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/pattern) 需要放在SVG文档的 `` 内部。 `pattern` 元素内部你可以包含任何之前包含过的其它基本形状,并且每个形状都可以使用之前学习过的任何样式样式化,包括渐变和半透明。

<?xml version="1.0" standalone="no"?>
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <linearGradient id="Gradient1">
      <stop offset="5%" stop-color="white"/>
      <stop offset="95%" stop-color="blue"/>
    </linearGradient>
    <linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
      <stop offset="5%" stop-color="red"/>
      <stop offset="95%" stop-color="orange"/>
    </linearGradient>
    <pattern id="Pattern" x="0" y="0" width=".25" height=".25">
      <rect x="0" y="0" width="50" height="50" fill="skyblue"/>
      <rect x="0" y="0" width="25" height="25" fill="url(#Gradient2)"/>
      <circle cx="25" cy="25" r="20" fill="url(#Gradient1)" fill-opacity="0.5"/>
    </pattern>

  </defs>

  <rect fill="url(#Pattern)" stroke="black" x="0" y="0" width="200" height="200"/>
</svg>

如果对象改变了大小,pattern 会自适应其大小,但是对象里面的内容不会自适应。通过改变 patternContentUnits 属性,我们可以把所有的元素放到相同的单元系统中,

参考:<pattern>

2.5 笔刷

2.6 文字

2.6.1 <text />

形状元素和文本元素都可以引用渐变或图案

设置字体属性 - 下列每个属性可以被设置为一个SVG属性或者成为一个 CSS 声明:
font-familyfont-stylefont-weightfont-variantfont-stretchfont-sizefont-size-adjustkerningletter-spacingword-spacingtext-decoration

<text x="10" y="10">Hello World!</text>

2.6.2 <tspan />

该元素用来标记大块文本的子部分,它必须是一个 text 元素或别的 tspan 元素的子元素。一个典型的用法是把句子中的一个词变成粗体红色。

此外还有属性 y 和属性 dy 作垂直转换。

<text>
  <tspan font-weight="bold" fill="red">This is bold and red</tspan>
</text>

2.6.3 <tref />

该元素允许引用已经定义的文本,高效地把它复制到当前位置。可以独立于源样式化它、修改它的外观。

<text id="example">This is an example text.</text>

<text>
    <tref xlink:href="#example" />
</text>

2.6.4 <textPath />

<path id="my_path" d="M 20,20 C 40,40 80,40 100,20" fill="transparent" />
<text>
  <textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#my_path">
    This text follows a curve.
  </textPath>
</text>

2.7 剪切和遮罩

擦除已经创建的元素的部分内容

Clipping 用来移除在别处定义的元素的部分内容。任何半透明效果都是不行的。它只能要么显示要么不显示。
Masking 允许使用透明度和灰度值遮罩计算得的软边缘。遮罩的效果最令人印象深刻的是表现为一个渐变。如果你想要让一个元素淡出,你可以利用遮罩效果实现。

2.7.1 剪切

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <clipPath id="cut-off-bottom">
      <rect x="0" y="0" width="200" height="100" />
    </clipPath>
  </defs>

  <circle cx="100" cy="100" r="100" clip-path="url(#cut-off-bottom)" />
</svg>

在 (100,100) 创建一个圆形,半径是 100。属性 clip-path 引用了一个带单个 rect 元素的 <clipPath> 元素。它内部的这个矩形将把画布的上半部分涂黑。

注意,clipPath 元素经常放在一个 defs 元素内。
rect 不会被绘制。它的象素数据将用来确定:圆形的哪些像素需要最终呈现出来。因为矩形只覆盖了圆形的上半部分,所以下半部分将消失了。

2.7.2 遮罩

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <linearGradient id="Gradient">
      <stop offset="0" stop-color="white" stop-opacity="0" />
      <stop offset="1" stop-color="white" stop-opacity="1" />
    </linearGradient>
    <mask id="Mask">
      <rect x="0" y="0" width="200" height="200" fill="url(#Gradient)"  />
    </mask>
  </defs>

  <rect x="0" y="0" width="200" height="200" fill="green" />
  <rect x="0" y="0" width="200" height="200" fill="red" mask="url(#Mask)" />
</svg>

注意的是描边将绘制在填充的上面。因此,如果你在一个元素上设置了描边透明度,但它同时设有填充,则描边的一半应用填充色,另一半将应用背景色。

<svg  width="200" height="200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
  <rect x="0" y="0" width="200" height="200" fill="blue" />
  <circle cx="100" cy="100" r="50" stroke="yellow" stroke-width="40" stroke-opacity=".5" fill="red" />
</svg>

红色的圆形在蓝色的背景上,黄色描边设置为50%不透明度,导到双色描边的效果。

2.8 嵌入内容

2.8.1 嵌入光栅图像

SVG 有一个 image 元素,与 HTML 中的 img 元素同样的目的。可以利用它嵌入任意光栅(以及矢量)图像。它的规格要求应用至少支持 PNG、JPG 和 SVG 格式文件。嵌入的图像变成一个普通的 SVG 元素。可以在其内容上用剪切、遮罩、滤镜、旋转以及其它 SVG 工具。

<svg version="1.1"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     width="200" height="200">
  <image x="90" y="-65" width="128" height="146" transform="rotate(45)"
     xlink:href="..."/>
</svg>

2.8.2 嵌入任意 XML

SVG 是一个 XML 应用,所以总是可以在 SVG 文档的任何位置嵌入任意 XML。
<foreignObject> 用来在 SVG 中嵌入 XHTML。如果你有更长的文本,HTML 布局比 SVG text 元素更适合。另一个经常被引用的用例是用 MathML 写的方程式。对于 SVG 的在科学方面的应用。
因为 foreignObject 是一个 SVG 元素,所以可以像用图像那样,在其内容上使用各种 SVG 工具。

2.9 滤镜效果

滤镜(Filter)是 SVG 中用于创建复杂效果的一种机制。
滤镜通过 <filter> 元素进行定义,并且置于 <defs> 区块中。在 filter 标签中提供一系列图元(primitives),以及在前一个基本变换操作上建立的另一个操作(比如添加模糊后又添加明亮效果)。如果要应用所创建的滤镜效果,只需要为 SVG 图形元素设置 filter 属性即可。

<svg width="250" viewBox="0 0 200 85"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <!-- Filter declaration -->
    <filter id="MyFilter" filterUnits="userSpaceOnUse"
            x="0" y="0"
            width="200" height="120">

      <!-- offsetBlur -->
      <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
      <feOffset in="blur" dx="4" dy="4" result="offsetBlur"/>

      <!-- litPaint -->
      <feSpecularLighting in="blur" surfaceScale="5" specularConstant=".75" 
                          specularExponent="20" lighting-color="#bbbbbb"  
                          result="specOut">
        <fePointLight x="-5000" y="-10000" z="20000"/>
      </feSpecularLighting>
      <feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut"/>
      <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" 
                   k1="0" k2="1" k3="1" k4="0" result="litPaint"/>

      <!-- merge offsetBlur + litPaint -->
      <feMerge>
        <feMergeNode in="offsetBlur"/>
        <feMergeNode in="litPaint"/>
      </feMerge>
    </filter>
  </defs>

  <!-- Graphic elements -->
  <g filter="url(#MyFilter)">
      <path fill="none" stroke="#D90000" stroke-width="10" 
            d="M50,66 c-50,0 -50,-60 0,-60 h100 c50,0 50,60 0,60z" />
      <path fill="#D90000" 
            d="M60,56 c-30,0 -30,-40 0,-40 h80 c30,0 30,40 0,40z" />
      <g fill="#FFFFFF" stroke="black" font-size="45" font-family="Verdana" >
        <text x="52" y="52">SVG</text>
      </g>
  </g>
</svg>

步骤一

<feGaussianBlur 
  in="SourceAlpha"
  stdDeviation="4"
  result="blur"/>

设置 <feGaussianBlur> 中的 in 属性为 "SourceAlpha" 值,即原图像的 alpha 通道,并设置了模糊度为 4 以及把 result 保存在了一个名为 "blur" 的临时缓冲区中。

步骤二

<feOffset 
  in="blur"
  dx="4" dy="4"
  result="offsetBlur"/>

<feOffset> 设置 in 的值为 "blur",即我们前面保存 result 的那个临时缓冲区。然后设置相对坐标,向右偏移 4,向下偏移 4。最后把结果 result 保存到名为 "offsetBlur" 的缓冲区中。步骤1、2其实是创建图形阴影的两个图元。

步骤三

<feSpecularLighting
  in="offsetBlur"
  surfaceScale="5" 
  specularConstant=".75" 
  specularExponent="20" 
  lighting-color="#bbbbbb"
  result="specOut">
  <fePointLight x="-5000" y="-10000" z="20000"/>
</feSpecularLighting>

<feSpecularLighting> 设置输入源 in"offsetBlur",将会生成一个光照效果,并将结果 result 保存在 "specOut" 中。

步骤四

<feComposite 
  in="specOut" 
  in2="SourceAlpha"
  operator="in"
  result="specOut"/>

第一个 <feComposite> 元素设置输入源为 "specOut",第二个输入源(in2)为 "SourceAlpha",将 "specOut" 的结果效果遮盖掉,以致于最后的结果不会大于 "SourceAlpha"(源图像),最后覆盖输出结果 result"specOut"

步骤五

<feComposite 
  in="SourceGraphic" 
  in2="specOut"
  operator="arithmetic" 
  k1="0" k2="1" k3="1" k4="0"
  result="litPaint"/>

第二个 <feComposite> 设置 in 为 "SourceGraphic""specOut",即在 "SourceGraphic" 之上添加 "specOut" 的效果,复合模式为 "arithmetic",然后保存结果为 "litPaint"

步骤六

<feMerge>
  <feMergeNode in="offsetBlur"/>
  <feMergeNode in="litPaint"/>
</feMerge>

最后,<feMerge> 元素合并了阴影效果 "offsetBlur" 和源图像的光照效果 "litPaint"

2.10 SVG 字体

SVG 字体当前只在 Safari 和 Android 浏览器中受支持。

2.10.1 定义字体

定义一个SVG字体的基础是 <font> 元素。

<font id="Font1" horiz-adv-x="1000">
  <font-face font-family="Super Sans" font-weight="bold" font-style="normal"
      units-per-em="1000" cap-height="600" x-height="400"
      ascent="700" descent="300"
      alphabetic="0" mathematical="350" ideographic="400" hanging="500">
    <font-face-src>
      <font-face-name name="Super Sans Bold"/>
    </font-face-src>
  </font-face>
  <missing-glyph><path d="M0,0h200v200h-200z"/></missing-glyph>
  <glyph unicode="!" horiz-adv-x="300"><!-- Outline of exclam. pt. glyph --></glyph>
  <glyph unicode="@"><!-- Outline of @ glyph --></glyph>
  <!-- more glyphs -->
</font>
<!-- 指示用户代理把“A”和“V”字符放得比标准的字符间距更靠近一些 -->
<hkern u1="A" u2="V" k="20" />

2.10.2 使用字体

<font>
  <font-face font-family="Super Sans" />
  <!-- and so on -->
</font>

<text font-family="Super Sans">My text uses Super Sans</text>

2.10.3 引用字体

<!-- 引用(远程)字体 -->
<font id="Super_Sans">
  <!-- and so on -->
</font>

<style type="text/css">
@font-face {
  font-family: "Super Sans";
  src: url(#Super_Sans);
}
</style>

<text font-family="Super Sans">My text uses Super Sans</text>
<!-- 引用远程字体 -->
<font>
  <font-face font-family="Super Sans">
    <font-face-src>
      <font-face-uri xlink:href="fonts.svg#Super_Sans" />
    </font-face-src>
  </font-face>
</font> 

2.11 基本操作 API