o'Reill的SVG精髓(第二版)学习笔记——第四章
第四章:基本形状
4.1线段
SVG可以使用<line>元素画出一条直线段。使用时只需要指定线段起止点的x和y坐标即可。指定坐标时可以不带单位,此时会使用用户坐标,也可以带上单位,如em、in等。
<line x1="start-x" y1="start-y" x2="end-x" y2="end-y" />
<svg width = "200px" height = "200px" viewBox = "0 0 200 200" xmlns="http://www.w3.org/2000/svg"> <!-- 水平线段 --> <line x1="40" y1="20" x2="80" y2="20" style="stroke: black;" /> <!-- 垂直线段 --> <line x1="0.7cm" y1="1cm" x2="0.7cm" y2="2.0cm" style="stroke: black;"/> <!-- 对角线段 --> <line x1="30" y1="30" x2="85" y2="85" style="stroke: black;"> </svg>
效果图:
4.2笔画特性
线段可以看作在画布上画出的笔画。笔画的尺寸、颜色和风格都会影响线段的表现。这些特性都可以在style属性中指定。
4.2.1 stroke-width
上述例子添加stroke-width:
<svg width = "200px" height = "200px" viewBox = "0 0 200 200" xmlns="http://www.w3.org/2000/svg"> <!-- 水平线段 --> <line x1="40" y1="20" x2="80" y2="20" style="stroke: black;stroke-width:10;" /> <!-- 垂直线段 --> <line x1="0.7cm" y1="1cm" x2="0.7cm" y2="2.0cm" style="stroke: black;stroke-width:10;"/> <!-- 对角线段 --> <line x1="30" y1="30" x2="85" y2="85" style="stroke: black;stroke-width:10;"> </svg>
效果图:
4.2.2画笔颜色
你可以通过以下几种方式指定画笔颜色
① 基本的颜色关键字:aquq、black、blue、fuchsia、gray、green、lime、maroon、navy、olive、purple、red、silver、teal、white和yellow。也可以使用SVG规范第4.2节中规定的颜色关键字(http:www.w3.org/TR/SVG/types.html#ColorKeywords)
② 由6位十六进制数字指定的颜色,形式为#rrggbb,其中rr表示红色,gg表示绿色,bb表示蓝色,它们的范围都是00-ff。
③由3位十六进制数字指定的颜色,形式为#rgb,其中r表示红色,g表示绿色,b表示蓝色。它们的范围都是0-f。这是前一种方式的简写,与之等效的6位数字写法是将每位重复一次,也就是#d6e与#dd66ee是一样的。
④通过rgb(red-value,green-value,blue-value)形式指定的rgb颜色值,每个值的取值范围是整数0-255或者百分比0%-100%。
⑤currentColor关键字,表示当前元素应用的CSS属性color的值。color是用来给HTML的文本设置颜色的,会被子元素继承,但对SVG没有直接效果。如果使用内联SVG图标的话,使用currentColor可以让图标使用它周围文本的颜色。
<svg width = "200px" height = "200px" viewBox = "0 0 200 200" xmlns="http://www.w3.org/2000/svg"> <line x1="10" y1="10" x2="50" y2="10" style="stroke: red;stroke-width:5;" /> <line x1="10" y1="20" x2="50" y2="20" style="stroke: #9f9;stroke-width:5;"/> <line x1="10" y1="30" x2="50" y2="30" style="stroke: #9999ff;stroke-width:5;" /> <line x1="10" y1="40" x2="50" y2="40" style="stroke: rgb(255,128,64);stroke-width:5;"/> <line x1="10" y1="50" x2="50" y2="50" style="stroke: rgb(60%,20%,60%);stroke-width:5;"> </svg>
效果图:
如果不指定画笔颜色的话,将看不到任何线,因为stroke属性的默认值是none。
4.2.3 stroke-opacity
我们可以通过给stroke-opacity属性赋值来控制线条的不透明度(opacity,与透明度相反。),取值范围为0.0~1.0.其中0代表完全透明,1代表完全不透明。小于0的值会被更改为0,大于1的值会被更改为1。
<svg width = "200px" height = "200px" viewBox = "0 0 200 200" xmlns="http://www.w3.org/2000/svg"> <line x1="30" y1="0" x2="30" y2="60" style="stroke: red;stroke-width:5;" /> <line x1="10" y1="10" x2="50" y2="10" style="stroke-opacity:0.2;stroke: black;stroke-width:5;"/> <line x1="10" y1="20" x2="50" y2="20" style="stroke-opacity:0.4;stroke: black;stroke-width:5;"/> <line x1="10" y1="30" x2="50" y2="30" style="stroke-opacity:0.6;stroke: black;stroke-width:5;" /> <line x1="10" y1="40" x2="50" y2="40" style="stroke-opacity:0.8;stroke: black;stroke-width:5;"/> <line x1="10" y1="50" x2="50" y2="50" style="stroke-opacity:1.0;stroke: black;stroke-width:5;"> </svg>
效果图:
4.2.4 stroke-dasharray属性
如果你需要点线或者虚线,则需要使用stroke-dasharray属性,它的值由一列数字构成,代表线的长度和空隙的长度,数字之间用逗号或空格分隔。数字的个数应该为偶数,但如果你指定的数字个数为奇数,则SVG会重复一次,使得总个数为偶数。
<svg width = "200px" height = "200px" viewBox = "0 0 200 200" xmlns="http://www.w3.org/2000/svg"> <!-- 9个像素的虚线,5个像素的空隙 --> <line x1="10" y1="10" x2="100" y2="10" style="stroke-dasharray:9,5;stroke:black;stroke-width:2;" /> <!-- 5个像素的虚线,3个像素的空隙,9个像素的虚线,2个像素的空隙 --> <line x1="10" y1="20" x2="100" y2="20" style="stroke-dasharray: 5,3,9,2;stroke:black;stroke-width:2;" /> <!-- 复制奇数个数,这等价于:9个像素的虚线,3个像素的空隙,5个像素的虚线,9个像素的空隙,3个像素的虚线,5个像素的空隙 --> <line x1="10" y1="30" x2="100" y2="30" style="stroke-dasharray: 9,3,5;stroke: black;stroke-width:2;" /> </svg>
效果图:
4.3矩形
矩形是最简单的基本形状,只需要指定其左上角的x和y坐标以及它的宽度(width)和高度(height)即可。矩形内部会使用fill属性代表的颜色进行填充,如果没有指定fill的颜色,则会使用黑色填充。fill属性的值可以用以上的画笔颜色的值进行定义,也可以指定为none,则不填充矩形内部,保持透明。也可以通过与stroke-opacity一样的方式来指定fill-opacity。fill和fill-opacity都是表现属性,属于style属性的值。
绘制矩形的边框,与上面画线时指定的stroke一样。如果不指定stroke,则它的值为none,将不会绘制矩形边框。
<svg width = "200px" height = "200px" viewBox = "0 0 200 200" xmlns="http://www.w3.org/2000/svg"> <!-- 内部填充为黑色,不绘制边框 --> <rect x="10" y="10" width="30" height="50" /> <!-- 内部不填充颜色,绘制黑色边框 --> <rect x="50" y="10" width="20" height="40" style="fill:none;stroke: black;" /> <!-- 内部填充为蓝色,绘制较粗的、半透明红色边框 --> <rect x="10" y="70" width="25" height="30" style="fill:#0000ff;stroke: red;stroke-width:7;stroke-opacity:0.5;" /> <!-- 内部填充为半透明的黄色,用虚线绘制绿色边框 --> <rect x="50" y="70" width="35" height="20" style="fill:yellow;fill-opacity:0.5;stroke:green;stroke-width:2;stroke-dasharray: 5 2" /> </svg>
效果图:
矩形坐标的x和y值默认都为0。如果指定宽或高(width/height)为0,则矩形不显示,如果指定宽或高为负值则会报错。
圆角矩形
如果希望得到圆角矩形,可以分别指定x方向和y方向的圆角半径,rx(x-radius,x方向的圆角半径)的最大值是矩形宽度的一半。同理,ry(y-radius,y方向的圆角半径)的最大值是矩形高度的一半。如果只指定了rx和ry中的一个值,则认为它们相等。
<svg width = "200px" height = "200px" viewBox = "0 0 200 200" xmlns="http://www.w3.org/2000/svg"> <!-- rx和ry相等,逐渐增大 --> <rect x="10" y="10" width="20" height="40" rx="2" ry="2" style="stroke: black;fill:none;" /> <rect x="40" y="10" width="20" height="40" rx="5" style="stroke: black;fill:none;" /> <rect x="70" y="10" width="20" height="40" rx="10" style="stroke: black;fill:none;" /> <!-- rx和ry相等,逐渐增大 --> <rect x="10" y="60" width="20" height="40" rx="10" ry="5" style="stroke: black;fill:none;" /> <rect x="40" y="60" width="20" height="40" rx="5" ry="10" style="stroke: black;fill:none;" /> </svg>
效果图:
CSS中的border-radius属性,可以通过设置圆角半径为宽高的50%,可使矩形变成一个圆或者椭圆。在SVG中也可以通过百分比来指定圆角半径的值,但会被解析为相对视口的宽度的百分比(和使用百分比来设置矩形的宽和高一样),而不是相对矩形本身宽高的百分比。
但是创建圆形,SVG有更简单的方法。
4.4 圆和椭圆
要画一个圆,需要<circle>元素,并指定圆心的x和y坐标(cx/cy)以及半径(r),和矩形一样,不指定fill和stroke的情况下,圆会使用黑色填充并且没有轮廓线。椭圆除了需要指定圆心的坐标外,还需要同时指定x方向的半径和y方向的半径,属性分别是rx和ry。对圆和椭圆来说。如果省略了cx或者cy,则默认为0。如果半径为0,则不会显示图形。如果半径为负数,则会报错。
<svg width = "200px" height = "200px" viewBox = "0 0 200 200" xmlns="http://www.w3.org/2000/svg"> <circle cx="30" cy="30" r="20" style="stroke: black;fill:none;" /> <circle cx="80" cy="30" r="20" style="stroke-width:5;stroke:black;fill:none;" /> <ellipse cx="30" cy="80" rx="10" ry="20" style="stroke:black;fill:none;" /> <ellipse cx="80" cy="80" rx="20" ry="10" style="stroke:black;fill:none;" /> </svg>
效果图:
4.5多边形
<polygon>元素可以用来画任意封闭图形,这个图形也可以填充和绘制轮廓。使用时需要为points属性指定一系列的x/y坐标对,并用逗号或者空格分隔。表示坐标的数字个数必须是偶数。指定坐标时不需要在最后指定返回起始坐标,因为图形是封闭的,会自动回到起始坐标。
<svg width = "200px" height = "200px" viewBox = "0 0 200 200" xmlns="http://www.w3.org/2000/svg"> <!-- 平行四边形 --> <polygon points="15,10 55,10 45,20 5,20" style="fill:red;stroke: black;" /> <!-- 五角星 --> <polygon points="35,37.5 37.9,46.1 46.9,46.1 39.7,51.5 42.3,60.1 35,55 27.7,60.1 30.3,51.5 23.1,46.1 32.1,46.1" style="fill:#ccffcc;stroke:green;" /> <!-- 不规则图形 --> <polygon points="60 60,65 72,80 60,90 90,72 80,72 85,50 95" style="fill:yellow;fill-opacity:0.5;stroke: black;stroke-width:2;" /> </svg>
效果图:
填充边线交叉的多边形
<svg width = "200px" height = "200px" viewBox = "0 0 200 200" xmlns="http://www.w3.org/2000/svg"> <!-- 未填充的边线交叉的多边形 --> <polygon points="48,16 16,96 96,48 0,48 80,96" style="stroke: black;fill:none;" /> </svg>
效果图:
SVG有两种判断某个点是否在多边形中的规则。分别对应fill-rule(表现的一部分)属性的nonzero(默认值)和evenodd。选择不同的规则会有不同的效果。
<svg width = "200px" height = "200px" viewBox = "0 0 200 200" xmlns="http://www.w3.org/2000/svg"> <!-- 不同填充规则的效果 --> <polygon points="48,16 16,96 96,48 0,48 80,96" style="fill-rule: nonzero;fill:yellow;stroke: black;" /> <polygon points="148,16 116,96 196,48 100,48 180,96" style="fill-rule:evenodd;fill:#00ff00;stroke:black;" /> </svg>
效果图:
填充规则解释:
nonzero规则在判断某个点是否在图形内部时,从这个点画一条线到无穷远,然后数这条线与图形边线有多少次交叉。如果交叉的边线是从右向左画,则总数加1;如果交叉的边线是从左往右画,则总数减1。如果最后总数为0,则认为改点在图形外部,否则认为在图形内部。
evenodd规则也画了同样一条线,但它只算与边线相交的次数。如果总数是奇数,则认为点在图形内部,否则认为点在图形外部。
4.6折线
如果想要一系列的直线段,但不闭合为某个形状。你乐意使用多个<line>元素,但如果有非常多线的话,可能使用<polyline>更容易。它与<polygon>有相同的point属性,不同之处在于图形并不封闭。
<svg width = "100px" height = "50px" viewBox = "0 0 100 50" xmlns="http://www.w3.org/2000/svg"> <!-- 折线 --> <polyline points="5 20,20 20,25 10,35 30,45 10,55 30,65 10,75 30,80 20,95 20" style="stroke-width:3;fill:none;stroke: black;" /> </svg>
效果图:
在使用<polyline>时最好将fill属性设置为none,否则SVG阅读器会尝试填充形状。
4.7 线帽和线连接
当使用<line>或者<polyline>画线的时候,可以为stroke-linecap指定不同的值来确定线的头尾形状,可能的取值为butt、round、square。
<svg width = "200px" height = "200px" viewBox = "0 0 200 200" xmlns="http://www.w3.org/2000/svg"> <line x1="10" y1="15" x2="50" y2="15" style="stroke:black;stroke-linecap:butt;stroke-width:15;" /> <line x1="10" y1="45" x2="50" y2="45" style="stroke:black;stroke-linecap:round;stroke-width:15;" /> <line x1="10" y1="75" x2="50" y2="75" style="stroke:black;stroke-linecap:square;stroke-width:15;" /> <!-- 灰色线 --> <line x1="10" y1="0" x2="10" y2="100" style="stroke:#999;" /> <line x1="50" y1="0" x2="50" y2="100" style="stroke:#999;" /> </svg>
效果图:
可以看出round和square在起止位置都超过了真实位置,默认值butt则精确地与起止位置对齐。
我们还可以通过stroke-linejoin属性来指定线段在图形棱角处交叉时的效果,可能的取值为miter(尖的) 、round(圆的)、bevel(平的)。
效果图:
如果两条线相交的时候是锐角,切stroke-linejoin的值为miter,则相交处有可能比线本身要宽。你可以指定stroke-miterlimit的值来设置相交处的显示宽度和线宽的比率,它的默认值为4
4.8基本形状总结。
4.8.1形状元素
形状 | 描述 |
---|---|
<line x1="start-x" y1="start-y" x2="end-x" y2="end-y" />
|
从起始点(start-x,start-y)画一条线到(end-x,end-y) |
<rect x="left-x" y="top-y" width="width" height="height" rx="2" />
|
画一个矩形,左上角位于(left-x,top-y),宽高分别为width和height |
<circle cx="center-x" cy="center-y" r="radius" />
|
以指定半径radius画一个圆,圆心位于(center-x,center-y) |
<ellipse cx="center-x" cy="center-y" rx="x-radius" ry="y-radius" />
|
画一个椭圆,x方向半径为x-radius,y方向半径为y-radius,圆心位于(center-x,center-y) |
<polygon points="points-list" />
|
画一个封闭图形,轮廓由points-list指定,它由一系列x/y坐标对组成,这些数值只能使用用户坐标,不可能添加长度单位。 |
<polyline points="points-list" />
|
画一系列相连的折线段,折线点由points-list指定,它由一系列x/y坐标对组成。这些数值只能使用用户坐标,不可以添加长度单位 |
当你为属性指定数值时,默认会以用户坐标为准。上表除了最后两个元素之外,其他元素的属性都可以在数字后面加上单位,如mm、pt等。
4.8.2 指定颜色
可以通过以下几种方式指定填充或者轮廓的颜色。
①none:不绘制轮廓或不为形状填充颜色。
其余见上方4.2.2画笔颜色。
4.8.3笔画和填充特性。
为了使线或者轮廓显示出来,必须使用以下属性指定笔画的特性。图形的轮廓会在内部填充完之后进行绘制。
下表中总结的所有特性都是表现特性,都属于style属性。
属性 | 值 |
---|---|
stroke | 笔画颜色,默认值为none。 |
stroke-width | 笔画宽度,可用用户坐标或者指定单位的方式指定。 |
stroke-opacity | 数字,从0.0到1.0。0.0是完全透明,1.0是完全不透明(默认值) |
stroke-dasharray | 用一系列的数字来指定虚线和间隙的长度。这些数字智能使用用户坐标,默认值为none; |
stroke-linecap | 线头尾的形状,值为butt(默认值)、round或者square。 |
stroke-linejoin | 图形的棱角或者一系列连线的形状,取值为miter(尖的,默认值)、round(圆的)或者bevel(平的)。 |
stroke-miterlimit | 相交处显示宽度与线宽的最大比例,默认值为4。 |
下表中的属性可以用来控制图形内部填充的方式。图形会首先填充内部在绘制轮廓。
属性 | 值 |
---|---|
fill | 按照4.8.2描述的方式指定填充颜色,默认值为black。 |
fill-opacity | 从0.0到1.0的数字,0.0表示完全透明,1.0(默认值)表示完全不透明 |
fill-rule | 属性值为nonzero(默认值)或evenodd。该属性决定判断某个点是否在图形内部的方法。只有当边线交叉时或者内部有“洞”时才有效。 |
这些只是SVG元素上可以应用的一部分样式属性。