SVG
可缩放矢量图形(Scalable Vector Graphics,SVG),是一种用来描述二维矢量图形的 XML 标记语言。不同于光栅图像格式(例如 JPG、PNG 用像素值来描绘的矩阵),矢量图放大缩小都不会失真。
SVG 与 Flash 类似,都是用于二维矢量图形,二者的区别在于,SVG 是一个 W3C 标准,基于 XML,是开放的,而 Flash 是封闭的基于二进制格式的。SVG 与其他的 W3C 标准,比如 CSS、DOM 和 SMIL 等能够协同工作。
注意
- IE9+ 浏览器支持
- SVG 的元素和属性必须按标准格式书写,因为 XML 是区分大小写的(这一点和html不同)
- SVG 里的属性值必须用引号引起来,就算是数值也必须这样做。
- 各浏览器是有差异的,很可能你制作了一个 SVG 图形,并且用一个工具调试正常后,却在另外一个浏览器中无法正常显示。
HTML引用 SVG 的常用方法
- 直接嵌入 SVG
- 通过 img 标签
- JavaScript 动态创建
基本操作API
- 创建图形
- document.createElementNS(ns,tagName)
- 添加图形
- element.appendChild(childElement)
- 设置/获取属性
- element.setAttribute(name,value)
- element.getAttribute(name)
基本结构
从一个简单的例子开始,看一下下面代码:
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="#F2EFE6" />
<circle cx="150" cy="100" r="80" fill="#4da1bd" />
<text x="150" y="110" font-size="20" text-anchor="middle" fill="#fff">AitSchool</text>
</svg>
绘制流程包括以下几步:
svg 根元素
- 属性 version 和属性 baseProfile 属性是必不可少的,供其它类型的验证方式确定 SVG 版本。
- width 和 height 属性可设置此 SVG 文档的宽度和高度。
- 作为 XML 的一种方言,SVG 必须正确的绑定命名空间 (在xmlns属性中绑定)。
绘制一个完全覆盖图像区域的矩形 rect ,把背景颜色设为灰色。
绘制一个半径 80px 的 蓝色圆圈 circle 在红色矩形的正中央 (向右偏移150px,向下偏移100px)。
绘制文字“AitSchool”。文字被填充为白色,通过设置居中的锚点把文字定位到期望的位置。
基本属性
- fill 属性设置对象内部的颜色
- fill-rule 用于定义如何给图形重叠的区域上色
- fill-opacity 控制填充色的不透明度
- stroke 属性设置绘制对象的线条的颜色
- stroke-opacity 控制线条的透明度
- stroke-width 定义了描边的宽度
- stroke-linecap 它控制边框终点的形状
- butt 直边结束线段,线段边界90度垂直于描边的方向、贯穿它的终点
- square 会稍微超出实际路径的范围,超出的大小由stroke-width控制
- round 边框的终点是圆角,圆角的半径也是由stroke-width控制的
- stroke-linejoin 控制两条描边线段之间,用什么方式连接
- miter 默认值,表示用方形画笔在连接处形成尖角
- round 圆角连接,实现平滑效果
- bevel 连接处会形成一个斜接
- stroke-dasharray 将虚线类型应用在描边上
- stroke-dashoffset 定义虚线开始的位置
<svg width="200" height="150" xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect x="10" y="10" width="100" height="100" stroke="blue" fill="purple" fill-opacity="0.5" stroke-opacity="0.8"/>
</svg>
<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="black"
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>
坐标、视窗、世界、视野
对于所有元素,SVG 使用的坐标系统或者说网格系统。这种坐标系统是:以页面的左上角为(0,0)坐标点,坐标以像素为单位,x轴正方向是向右,y轴正方向是向下。
- SVG 标签的 width 和 height 控制视窗大小。
- SVG 里的元素代码内容代表着世界。
- viewBox、preserveAspectRatio 控制视野
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="#F2EFE6" />
<circle cx="150" cy="100" r="80" fill="#4da1bd" />
</svg>
- 定义一个矩形,即从左上角开始,绘制一个 150 * 100 的矩形。
- 定义一个圆形,右偏移150px,向下偏移100px 的点为圆心,半径为 80 绘制。
viewBox 属性表示 SVG 可见区域的大小,可以改变我们对 SVG 元素里面的能见度。
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 100">
<rect width="150" height="100" fill="#F2EFE6" />
<circle cx="150" cy="100" r="80" fill="#4da1bd" />
</svg>
这里定义的画布尺寸是300 * 200px。但是,viewBox属性定义了画布上可以显示的区域:从(0,0)点开始,150宽 * 100高的区域。这个150 * 100的区域,会放到300 * 200的画布上显示。于是就形成了放大两倍的效果。
preserveAspectRatio
当viewBox 和 SVG 宽高比例不一致时候。可以使用 preserveAspectRatio 属性描述 viewBox 在 SVG 中对其与缩放的展示的方式。preserveAspectRatio属性的值为空格分隔的两个值组合而成。
第1个值表示,viewBox如何与SVG viewport对齐:
横行对齐方式
- xMin viewport和viewBox左边对齐
- xMid viewport和viewBox x轴中心对齐
- xMax viewport和viewBox右边对齐
垂直对齐方式
- YMin viewport和viewBox上边缘对齐。注意Y是大写。
- YMid viewport和viewBox y轴中心点对齐。注意Y是大写。
- YMax viewport和viewBox下边缘对齐。注意Y是大写。
组合
- none 元素的边界完全匹配视图矩形。
- xMinYMin
- 将SVG元素的viewbox属性的X的最小值与视图的X的最小值对齐。
- 将SVG元素的viewbox属性的Y的最小值与视图的Y的最小值对齐。
- xMidYMin
- 将SVG元素的viewbox属性的X的中点值与视图的X的中点值对齐。
- 将SVG元素的viewbox属性的Y的最小值与视图的Y的最小值对齐。
- xMaxYMin
- 将SVG元素的viewbox属性的X的最小值+元素的宽度与视图的X的最大值对齐。
- 将SVG元素的viewbox属性的Y的最小值与视图的Y的最小值对齐。
- xMinYMid
- 将SVG元素的viewbox属性的X的最小值与视图的X的最小值对齐。
- 将SVG元素的viewbox属性的Y的中点值与视图的Y的中点值对齐。
- xMidYMid (默认值)
- 将SVG元素的viewbox属性的X的中点值与视图的X的中点值对齐。
- 将SVG元素的viewbox属性的Y的中点值与视图的Y的中点值对齐。
- xMaxYMid
- 将SVG元素的viewbox属性的X的最小值+元素的宽度与视图的X的最大值对齐。
- 将SVG元素的viewbox属性的Y的中点值与视图的Y的中点值对齐。
- xMinYMax
- 将SVG元素的viewbox属性的X的最小值与视图的X的最小值对齐。
- 将SVG元素的viewbox属性的Y的最小值+元素的高度与视图的Y的最大值对齐。
- xMidYMax
- 将SVG元素的viewbox属性的X的中点值与视图的X的中点值对齐。
- 将SVG元素的viewbox属性的Y的最小值+元素的高度与视图的Y的最大值对齐。
- xMaxYMax
- 将SVG元素的viewbox属性的X的最小值+元素的宽度与视图的X的最大值对齐。
- 将SVG元素的viewbox属性的Y的最小值+元素的高度与视图的Y的最大值对齐。
第2个值表示,如何维持高宽比(可选):
- meet 保持纵横比缩放viewBox适应viewport
- slice 保持纵横比同时比例小的方向放大填满viewport
以下SVG的宽高比为 3:2,viewBox 的为 1:1 。preserveAspectRatio不同情况事例如下:
- 不设置 preserveAspectRatio ,默认值 xMidYMid meet
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg" viewBox="70 20 80 80">
<rect width="150" height="100" fill="#F2EFE6" />
<circle cx="150" cy="100" r="80" fill="#4da1bd" />
</svg>
- preserveAspectRatio 为 none ,扭曲纵横比以充分适应
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg" viewBox="70 20 80 80" preserveAspectRatio="none">
<rect width="150" height="100" fill="#F2EFE6" />
<circle cx="150" cy="100" r="80" fill="#4da1bd" />
</svg>
- preserveAspectRatio 为 xMinYMin meet ,viewport和viewBox,左上两边对齐,保持纵横比缩放viewBox适应viewport。
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg" viewBox="70 20 80 80" preserveAspectRatio="xMinYMin meet">
<rect width="150" height="100" fill="#F2EFE6" />
<circle cx="150" cy="100" r="80" fill="#4da1bd" />
</svg>
- preserveAspectRatio 为 xMaxYMin meet ,viewport和viewBox,右上两边对齐,保持纵横比缩放viewBox适应viewport。
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg" viewBox="70 20 80 80" preserveAspectRatio="xMaxYMin meet">
<rect width="150" height="100" fill="#F2EFE6" />
<circle cx="150" cy="100" r="80" fill="#4da1bd" />
</svg>
形状
要想插入一个形状,你可以在文档中创建一个元素。不同的元素对应着不同的形状,并且使用不同的属性来定义图形的大小和位置。SVG 一些预定义的形状元素:
- 矩形 rect
- 圆形 circle
- 椭圆 ellipse
- 线 line
- 折线 polyline
- 多边形 polygon
- 路径 path
<svg width="200" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg">
<!-- 正方形 -->
<rect x="10" y="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/>
<rect x="60" y="10" rx="10" ry="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/>
<!-- 圆形椭圆形 -->
<circle cx="25" cy="75" r="20" stroke="red" fill="transparent" stroke-width="5"/>
<ellipse cx="75" cy="75" rx="20" ry="5" stroke="red" fill="transparent" stroke-width="5"/>
<!-- 线 和 折线 -->
<line x1="10" x2="50" y1="110" y2="150" stroke="orange" fill="transparent" stroke-width="5"/>
<polyline points="60 110 65 120 70 115 75 130 80 125 85 140 90 135 95 150 100 145"
stroke="orange" fill="transparent" stroke-width="5"/>
<!-- 多边形 -->
<polygon points="50 160 55 180 70 180 60 190 65 205 50 195 35 205 40 190 30 180 45 180"
stroke="green" fill="transparent" stroke-width="5"/>
<!-- 路径 -->
<path d="M20,230 Q40,205 50,230 T90,230" fill="none" stroke="blue" stroke-width="5"/>
</svg>
矩形
参数:
- x 矩形左上角的x位置
- y 矩形左上角的y位置
- width 矩形的宽度
- height 矩形的高度
- rx 圆角的x方位的半径
- ry 圆角的y方位的半径
<rect x="60" y="10" rx="10" ry="10" width="30" height="30"/>
圆形
参数:
- r 圆的半径
- cx 圆心的x位置
- cy 圆心的y位置
<circle cx="25" cy="75" r="20"/>
椭圆
- rx 椭圆的x半径
- ry 椭圆的y半径
- cx 椭圆中心的x位置
- cy 椭圆中心的y位置
<ellipse cx="75" cy="75" rx="20" ry="5"/>
线条
它取两个点的位置作为属性,指定这条线的起点和终点位置。
- x1 起点的x位置
- y1 起点的y位置
- x2 终点的x位置
- y2 终点的y位置
<line x1="10" x2="50" y1="110" y2="150"/>
折线
Polyline是一组连接在一起的直线。因为它可以有很多的点,折线的的所有点位置都放在一个points属性中:每个数字用空白、逗号、终止命令符或者换行符分隔开。每个点必须包含2个数字,一个是x坐标,一个是y坐标。所以点列表 (0,0), (1,1) 和(2,2)可以写成这样:“0 0, 1 1, 2 2”。
<polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/>
多边形
polygon和折线很像,它们都是由连接一组点集的直线构成。不同的是,polygon的路径在最后一个点处自动回到第一个点。
<polygon points="50 160, 55 180, 70 180, 60 190, 65 205, 50 195, 35 205, 40 190, 30 180, 45 180"/>
路径
path可能是SVG中最常见的形状。你可以用path元素绘制矩形(直角矩形或者圆角矩形)、圆形、椭圆、折线形、多边形,以及一些其他的形状,例如贝塞尔曲线、2次曲线等曲线。
- d 一个点集数列以及其它关于如何绘制路径的信息,是一个“命令+参数”的序列。
<path d="M 20 230 Q 40 205, 50 230 T 90230"/>
每一个命令都用一个关键字母来表示,比如,字母“M”表示的是“Move to”命令,当解析器读到这个命令时,它就知道你是打算移动到某个点。跟在命令字母后面的,是你需要移动到的那个点的x和y轴坐标。比如移动到(10,10)这个点的命令,应该写成“M 10 10”。这一段字符结束后,解析器就会去读下一段命令。每一个命令都有两种表示方式,一种是用大写字母,表示采用绝对定位。另一种是用小写字母,表示采用相对定位(例如:从上一个点开始,向上移动10px,向左移动7px)。
- 直线命令 M x y
- 曲线命令 C x1 y1, x2 y2, x y
- 弧形 A rx ry x-axis-rotation large-arc-flag sweep-flag x y
分组
g 标签创建分组,属性定义坐标变换
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
<g stroke="green" fill="#4da1bd" >
<rect x="100" y="50" width="100" height="50" />
<rect x="140" y="100" width="20" height="120"/>
</g>
</svg>
渐变
线性渐变
线性渐变沿着直线改变颜色,要插入一个线性渐变,你需要在 SVG 文件的 defs 元素内部,创建一个 linearGradient 节点。
线性渐变内部有几个 stop 结点,这些结点通过指定位置的 offset(偏移)属性和 stop-color(颜色中值)属性来说明在渐变的特定位置上应该是什么颜色;可以直接指定这两个属性值,也可以通过CSS来指定他们的值。
gradientUnits 属性的默认值为 objectBoundingBox 用包容的盒子来描述。当值为 userSpaceOnUse 时,用户可自定义渐变坐标范围。这时候 x1、y1、x2、y2 相对SVG画布的开始点和结束点坐标。
<svg width="400" height="150" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="Gradient1" gradientUnits="objectBoundingBox">
<stop offset="0%" stop-color="#1497fc"/>
<stop offset="50%" stop-color="#a469be"/>
<stop offset="100%" stop-color="#ff8c00"/>
</linearGradient>
<linearGradient id="Gradient2" gradientUnits="userSpaceOnUse" x1="150" y1="0" x2="350" y2="150">
<stop offset="0%" stop-color="#1497fc"/>
<stop offset="50%" stop-color="#a469be"/>
<stop offset="100%" stop-color="#ff8c00"/>
</linearGradient>
</defs>
<rect rx="15" ry="15" width="150" height="150" fill="url(#Gradient1)"/>
<rect x="200" y="0" rx="15" ry="15" width="150" height="150" fill="url(#Gradient2)"/>
</svg>
径向渐变
径向渐变与线性渐变相似,只是它是从一个点开始发散绘制渐变。创建径向渐变需要在文档的defs中添加一个 radialGradient 元素。
- cx、cy 表示渐变开始的坐标
- r 表示半径
- fx、fy 表示焦点的坐标。
<svg width="400" height="150" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="Gradient3" cx="0.5" cy="0.5" r="0.5">
<stop offset="0%" stop-color="#1497fc"/>
<stop offset="50%" stop-color="#a469be"/>
<stop offset="100%" stop-color="#ff8c00"/>
</radialGradient>
<radialGradient id="Gradient4" cx="0.5" cy="0.5" r="0.5" fx="0.8" fy="0.8">
<stop offset="0%" stop-color="#1497fc"/>
<stop offset="50%" stop-color="#a469be"/>
<stop offset="100%" stop-color="#ff8c00"/>
</radialGradient>
</defs>
<rect rx="15" ry="15" width="150" height="150" fill="url(#Gradient3)"/>
<rect x="200" y="0" rx="15" ry="15" width="150" height="150" fill="url(#Gradient4)"/>
</svg>
文字
文本的一个至关重要的部分是它显示的字体。SVG提供了一些属性,类似于它们的CSS同行,用来激活文本选区。下列每个属性可以被设置为一个SVG属性或者成为一个CSS声明:font-family、font-style、font-weight、font-variant、font-stretch、font-size、font-size-adjust、kerning、letter-spacing、word-spacing和text-decoration。
创建文本标签
使用 text、tspan 创建文本,使用 textpath创建路径文本
- x、y 定位
- dx、dy 偏移
- style 设置样式
- text-anchor 文本流水平的对齐方向。(start|middle|end|inherit)
- dominant-baseline 文本流垂直对齐方向。(...)
- textpath 中,超出路径的文字将不再进行渲染,可以通过 startOffset 属性控制开始位置
- 可以使用 a 标签定义超链接,可以添加到任何图形上
<svg width="400" height="150" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="grid" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<path stroke="#e4e4e4" fill="none" d="M0,0H20V20V"></path>
</pattern>
</defs>
<!-- 定义网格 -->
<rect width="400" height="150" fill="url(#grid)"/>
<!-- 定义参照线 -->
<path d="M100,0V200M0,100H200" stroke="red" />
<!-- 定义文本路径 -->
<path id="textpath_path_1" d="M 10 20 Q 20 10 30 20 T 50 20" stroke="red" fill="none"/>
<!-- 定义文本,水平对齐 -->
<text x="100" y="20" text-anchor="start">start</text>
<text x="100" y="40" text-anchor="middle">Middle</text>
<text x="100" y="60" text-anchor="end">end</text>
<!-- 定义文本,垂直对齐 -->
<text x="100" y="100">A</text>
<text x="120" y="100" dominant-baseline="hanging">B</text>
<text x="140" y="100" dominant-baseline="middle">C</text>
<text x="160" y="100" dominant-baseline="central">D</text>
<text x="100" y="100" dx="20" dy="40" style="font-size:20px;">Hello,AitSchool!</text>
<!-- 定义路金文本 -->
<text>
<textPath startOffset="20%" xlink:href="#textpath_path_1" style="font-size: 12px;">0123456789</textPath>
</text>
<!-- 定义超链接 -->
<a xlink:href="https://www.baidu.com" xlink:title="点我跳百度" target="_blank">
<rect x="300" y="0" width="100" height="100" fill="blue"/>
</a>
</svg>
图形引用
use 标签创建图形引用,使用 xlink:href 属性引用一个具有一个唯一的ID属性和重复的图形元素。
<svg width="400" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg" >
<!-- 绘制背景 -->
<rect width="100%" height="100%" fill="#333" />
<g id="star-group">
<defs>
<!-- 绘制多边形星星 -->
<polygon id="star" points="0 -10 2 -2 10 0 2 2 0 10 -2 2 -10 0 -2 -2" fill="white" />
</defs>
<!-- 多次引用星星 -->
<use xlink:href="#star" x="60" y="150"/>
<use xlink:href="#star" x="80" y="80" />
<use xlink:href="#star" x="150" y="30"/>
<use xlink:href="#star" x="200" y="120"/>
<use xlink:href="#star" x="350" y="120"/>
</g>
</svg>
使用 polygon 绘制出星星,然后使用 use 标签对星星进行不断的引用。通过JS甚至可以创造出众多不同位置、不同大小、透明度不一的星星 ✨。
剪切
clipPath 用来移除在别处定义的元素的部分内容。在这里,任何半透明效果都是不行的。它只能要么显示要么不显示。
- 我们先绘制以下几个图形,分别是灯塔、灯光、还有灯光范围。
<svg width="400" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg" >
<!-- 绘制背景 -->
<rect width="100%" height="100%" fill="#333" />
<!-- 灯塔分组 -->
<g id="light-tower" transform="translate(300, 150)">
<!-- 灯光射线 -->
<polygon points="0 0 -120 -15 -120 15" fill="rgba(255,255,255,0.5)"></polygon>
<!-- 灯塔三角形 -->
<polygon points="0 0 5 50 -5 50" fill="rgba(255,255,255,.5)"/>
<!-- 灯塔原点灯 -->
<circle cx="0" cy="0" r="2" fill="rgba(255,255,255,.5)"></circle>
<!-- 灯光范围 -->
<ellipse cx="0" cy="0" rx="100" ry="50" fill="rgba(255,255,255,.5)"></ellipse>
</g>
</svg>
- 我们希望显示灯光和灯光范围重叠的部分,并在 fill 上填充进渐变背景图像。使用 clipPath 创建剪裁区,然后在灯光范围椭圆元素内使用 clip-path 引用。
<svg width="400" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg" >
<rect width="100%" height="100%" fill="#333" />
<g id="light-tower" transform="translate(300, 150)">
<defs>
<!-- 灯塔渐变颜色 -->
<linearGradient id="tower">
<stop offset="0" stop-color="#999"></stop>
<stop offset="1" stop-color="#333"></stop>
</linearGradient>
<!-- 灯光径向渐变颜色 -->
<radialGradient id="light" cx="0.5" cy="0.5" r="0.5">
<stop offset="0" stop-color="rgba(255,255,255,0.6)"></stop>
<stop offset="1" stop-color="rgba(255,255,255,0)"></stop>
</radialGradient>
<!-- 裁切 -->
<clipPath id="light-mask">
<!-- 灯光射线 -->
<polygon points="0 0 -120 -15 -120 15" fill="rgba(255,0,0,0.5)">
<!-- 动画 -->
<animateTransform
attributeName="transform"
attributeType="XML"
type="rotate"
from="0"
to="360"
dur="10s"
repeatCount="indefinite">
</animateTransform>
</polygon>
<!-- 灯塔原点 -->
<circle cx="0" cy="0" r="2"></circle>
</clipPath>
</defs>
<!-- 灯塔 -->
<polygon points="0 0 5 50 -5 50" fill="url(#tower)"/>
<!-- 灯光 -->
<ellipse cx="0" cy="0"
rx="100" ry="50"
fill="url(#light)"
clip-path="url(#light-mask)"></ellipse>
</g>
</svg>
遮罩
遮罩的效果最令人印象深刻的是表现为一个渐变。如果你想要让一个元素淡出,你可以利用遮罩效果实现这一点。
<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>
你看到有一个绿色填充的矩形在底层,一个红色填充的矩形在上层。后者有一个mask属性指向一个mask元素。mask元素的内容是一个单一的rect元素,它填充了一个透明到白色的渐变。作为红色矩形继承mark内容的alpha值(透明度)的结果,我们看到一个从绿色到红色渐变的输出。
- 首先创建出两个圆形区域。
<svg width="400" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg" >
<rect width="100%" height="100%" fill="#333" />
<g id="moon-group">
<circle cx="80" cy="80" r="40" fill="rgba(255,255,255,0.5)"></circle>
<circle cx="100" cy="60" r="40" fill="rgba(255,255,255,0.5)"></circle>
</g>
</svg>
- 以创建的区域添加到遮罩的区域
事例
<svg width="400" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg" >
<!-- 背景 -->
<rect width="100%" height="100%" fill="#333" />
<!-- 星星 -->
<g id="star-group">
<defs>
<polygon id="star"
points="0 -10 2 -2 10 0 2 2 0 10 -2 2 -10 0 -2 -2"
fill="white" />
</defs>
<use xlink:href="#star" x="60" y="150"/>
<use xlink:href="#star" x="80" y="80" />
<use xlink:href="#star" x="150" y="30"/>
<use xlink:href="#star" x="200" y="120"/>
<use xlink:href="#star" x="350" y="120"/>
</g>
<!-- 灯塔 -->
<g id="light-tower" transform="translate(300, 150)">
<defs>
<linearGradient id="tower">
<stop offset="0" stop-color="#999"></stop>
<stop offset="1" stop-color="#333"></stop>
</linearGradient>
<radialGradient id="light" cx="0.5" cy="0.5" r="0.5">
<stop offset="0" stop-color="rgba(255,255,255,0.6)"></stop>
<stop offset="1" stop-color="rgba(255,255,255,0)"></stop>
</radialGradient>
<clipPath id="light-mask">
<polygon points="0 0 -120 -15 -120 15" fill="rgba(255,0,0,0.5)">
<animateTransform attributeName="transform"
attributeType="XML"
type="rotate"
from="0"
to="360"
dur="10s"
repeatCount="indefinite">
</animateTransform>
</polygon>
<circle cx="0" cy="0" r="2"></circle>
</clipPath>
</defs>
<polygon points="0 0 5 50 -5 50" fill="url(#tower)" x="100" y="100"/>
<ellipse cx="0" cy="0"
rx="100" ry="50"
fill="url(#light)"
clip-path="url(#light-mask)">
</ellipse>
</g>
<!-- 月亮 -->
<g id="moon-group">
<mask id="moon-mask">
<circle cx="80" cy="80" r="40" fill="yellow"></circle>
<circle cx="100" cy="60" r="40" fill="black"></circle>
</mask>
<circle cx="80" cy="80" r="40" fill="yellow" mask="url(#moon-mask)"></circle>
</g>
</svg>
变形
- 平移 你能把元素移动一段距离,甚至你可以根据相应的属性定位它。translate()变形方法专门效力于这个目的。
<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)" />