坐标定位
坐标系统是:以页面的左上角为 (0,0) 坐标点,坐标以像素为单位,x 轴正方向是向右,y 轴正方向是向下。
<rect x="0" y="0" width="100" height="100" />
定义一个矩形,即从左上角开始,向右延展 100px,向下延展 100px,形成一个 100*100 大的矩形。
2. 基本形状
rect 矩形 | x 矩形左上角的 x 位置 y 矩形左上角的 y 位置 width 矩形的宽度 height 矩形的高度 rx 圆角的 x 方位的半径 ry 圆角的 y 方位的半径 |
circle | r 圆的半径 cx 圆心的 x 位置 cy 圆心的 y 位置 |
line | x1 起点的 x 位置 y1 起点的 y 位置 x2 终点的 x 位置 y2 终点的 y 位置 |
ellipse | rx 椭圆的 x 半径 ry 椭圆的 y 半径 cx 椭圆中心的 x 位置 cy 椭圆中心的 y 位置 |
polyline | points 点集数列。每个数字用空白、逗号、终止命令符或者换行符分隔开。每个点必须包含 2 个数字,一个是 x 坐标,一个是 y 坐标。所以点列表 (0,0), (1,1) 和 (2,2) 可以写成这样:“0 0, 1 1, 2 2”。 |
polygon | points 点集数列最后首尾相连 |
path | d 一个点集数列以及其他关于如何绘制路径的信息。 |
3.路径
每一个命令都用一个关键字母来表示,比如,字母“M”表示的是“Move to”命令,当解析器读到这个命令时,它就知道你是打算移动到某个点。跟在命令字母后面的,是你需要移动到的那个点的 x 和 y 轴坐标。比如移动到 (10,10) 这个点的命令,应该写成“M 10 10”。这一段字符结束后,解析器就会去读下一段命令。每一个命令都有两种表示方式,一种是用大写字母,表示采用绝对定位。另一种是用小写字母,表示采用相对定位(例如:从上一个点开始,向上移动 10px,向左移动 7px)。
直线命令 | “Move to”命令 | M20 20/m 10 10 | 点移动到(20,20)/点向x移动10,向y移动10 |
"Line to”命令 | L30 30/L10 10 | 与点(30,30)相连/与当前位置向x轴移动10,向y轴移动10的点相连 | |
绘制水平线 | H 20/h20 | 与水平方向,x轴坐标为20的点相连/水平方向延伸20 | |
绘制垂直线 | V30/v30 | 与垂直方向,y轴坐标为30的点相连/垂直方向延伸30 | |
连接头尾 | Z | 连接头尾两点 | |
曲线命令 | 三次贝塞尔曲线 | C 20 20, 40 20, 50 10/ c 20 20,40 20,50 10 | 三次贝塞尔曲线需要定义一个点和两个控制点 |
三次贝塞尔曲线延伸 | S x2 y2, x y (or) s dx2 dy2, dx dy | S 命令可以用来创建与前面一样的贝塞尔曲线,但是,如果 S 命令跟在一个 C 或 S 命令后面,则它的第一个控制点会被假设成前一个命令曲线的第二个控制点的中心对称点。如果 S 命令单独使用,前面没有 C 或 S 命令,那当前点将作为第一个控制点。 | |
二次贝塞尔曲线 | Q x1 y1, x y (or) q dx1 dy1, dx dy | 只需要一个控制点,用来确定起点和终点的曲线斜率。 | |
二次贝塞尔曲线延伸 | T x y (or) t dx dy | 在你的第一个控制点后面,可以只定义终点,就创建出一个相当复杂的曲线。T 命令前面必须是一个 Q 命令,或者是另一个 T 命令,才能达到这种效果。如果 T 单独使用,那么控制点就会被认为和终点是同一个点,所以画出来的将是一条直线。 | |
弧形 | A rx ry x-axis-rotation large-arc-flag sweep-flag x y a rx ry x-axis-rotation large-arc-flag sweep-flag dx dy | rx 椭圆x半径 ry 椭圆y半径 x-axis-rotation 该椭圆在x轴的偏移角度 large-arc-flag 0/1 0为弧度在180内1为弧度大于180 sweepflag 0/1 0从起点到终点逆时针,1从起点到终点顺时针 |
4.填充和边框(fill 与 stroke)
上色
可以通过在元素上设置两个属性来搞定:fill属性和stroke属性。fill属性设置对象内部的颜色,stroke属性设置绘制对象的线条的颜色。
<rect x="10"y="10"width="100"height="100"stroke="blue"fill="purple"fill-opacity="0.5"stroke-opacity="0.8"/>
描边
除了颜色属性,还有其他一些属性用来控制绘制描边的方式。
<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="black"stroke-width="20"stroke-linecap="butt"/>
<line x1="40"x2="120"y1="60"y2="60"stroke="black"stroke-width="20"stroke-linecap="square"/>
<line x1="40" x2="120"y1="100"y2="100"stroke="black"stroke-width="20"stroke-linecap="round"/></svg>
stroke-width属性定义了描边的宽度。注意,描边是以路径为中心线绘制的,在上面的例子里,路径是粉红色的,描边是黑色的。如你所见,路径的每一侧都有均匀分布的描边。
第二个影响描边的属性是stroke-linecap属性,如上所示。它控制边框终点的形状。
stroke-linecap属性的值有三种可能值:
- butt用直边结束线段,它是常规做法,线段边界 90 度垂直于描边的方向、贯穿它的终点。
- square的效果差不多,但是会稍微超出实际路径的范围,超出的大小由stroke-width控制。
- round表示边框的终点是圆角,圆角的半径也是由stroke-width控制的。
还有一个stroke-linejoin属性,用来控制两条描边线段之间,用什么方式连接。
每条折线都是由两个线段连接起来的,连接处的样式由stroke-linejoin属性控制,它有三个可用的值:
- miter是默认值,表示用方形画笔在连接处形成尖角
- round表示用圆角连接,实现平滑效果。
- bevel,连接处会形成一个斜接。
可以通过指定stroke-dasharray属性,将虚线类型应用在描边上.
stroke-dasharray属性的参数,是一组用逗号分割的数字组成的数列,注意,和path不一样,这里的数字必须用逗号分割(空格会被忽略)。每一组数字,第一个用来表示填色区域的长度,第二个用来表示非填色区域的长度。
使用CSS
除了定义对象的属性外,你也可以通过 CSS 来样式化填充和描边。语法和在 HTML 里使用 CSS 一样,只不过你要把background-color、border改成fill和stroke。注意,不是所有的属性都能用 CSS 来设置。上色和填充的部分一般是可以用 CSS 来设置的,比如fill,stroke,stroke-dasharray等,但是不包括下面会提到的渐变和图案等功能。
CSS 可以利用 style 属性插入到元素的行间:
<rect x="10"height="180"y="10"width="180"style="stroke: black; fill: red;"/>
或者,它可以被移到你所包含的一个特殊的样式部分。不过,我们不会像 HTML 那样把这样的部分塞进 <head> 部分,而是把它包含在一个叫做 <defs> 的区域。
<defs> 表示定义,这里面可以定义一些不会在 SVG 图形中出现、但是可以被其他元素使用的元素。
<?xml version="1.0" standalone="no"?>
<svg width="200"height="200"xmlns="http://www.w3.org/2000/svg"version="1.1">
<defs>
<style>
<![CDATA[
#MyRect {
stroke: black;
fill: red;
}
]]>
</style>
</defs>
<rect x="10"height="180"y="10"width="180"id="MyRect"/></svg>
5.渐变
线性渐变
<linearGradient> 元素还需要一些其他的属性值,它们指定了渐变的大小和出现范围。渐变的方向可以通过两个点来控制,它们分别是属性 x1、x2、y1 和 y2,这些属性定义了渐变路线走向。渐变色默认是水平方向的,但是通过修改这些属性,就可以旋转该方向。下例中的 Gradient2 创建了一个垂直渐变。
<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<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 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>
<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)"/>
径向渐变
径向渐变与线性渐变相似,只是它是从一个点开始发散绘制渐变。创建径向渐变需要在文档的defs中添加一个<radialGradient>元素
<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>
spreadMethod属性,该属性控制了当渐变到达终点的行为,但是此时该对象尚未被填充颜色。这个属性可以有三个值:pad、reflect 或 repeat。Pad 就是目前我们见到的效果,即当渐变到达终点时,最终的偏移颜色被用于填充对象剩下的空间。reflect 会让渐变一直持续下去,不过它的效果是与渐变本身是相反的,以 100% 偏移位置的颜色开始,逐渐偏移到 0% 位置的颜色,然后再回到 100% 偏移位置的颜色。repeat 也会让渐变继续,但是它不会像 reflect 那样反向渐变,而是跳回到最初的颜色然后继续渐变。