提示

填充图形或笔画除了使用 fill,stroke纯色之外,还可以使用图案和渐变填充。

# 1. 图案

使用图案填充图形,首先要定义一个水平或垂直方向的重复的图案对象,然后用它填充另一个对象或者作为笔画使用。这个图形对象被称为"tile"(瓦片)。

图案对象使用pattern元素定义,pattern元素内部包裹了图案的path元素。定义好之后下一个需要解决的问题是如何排列图案,那就需要使用patternUnits属性.

  • patternUnits = objectBoundingBox

如果希望图案的大小基于要填充对象的大小计算,则需要设置patternUnits属性为objectBoundingBox(01之间的小数或百分比),并需要指定图案左上角的x和y坐标。

<defs>
	<pattern id="tile" x="0" y="0" width="20%" height="20%" patternUnits="objectBoundingBox">
    	    <path d="M 0 0 Q 5 20 10 10 T 20 20" style="stroke:black;fill:none"></path>
	    <path d="M 0 0 h 20 v 20 h -20 z" style="stroke:black;fill:none"></path>
	</pattern>
</defs>
<path d="M 0 0 Q 5 20 10 10 T 20 20" style="stroke:black;fill:none"></path>
<path d="M 0 0 h 20 v 20 h -20 z" style="stroke:black;fill:none"></path>
<rect x="40" y="0" width="100" height="100" style="fill:url(#tile);stroke:black"></rect>	
<rect x="155" y="0" width="70" height="80" style="fill:url(#tile);stroke:black"></rect>
<rect x="250" y="0" width="150" height="130" style="fill:url(#tile);stroke:black"></rect>

在上图中,第一个正方形宽高都为100,百分之20刚好为图案的尺寸,因此恰好平铺。在第二个图中,正方形的宽高分别为7080,因此图案会被截断。在第三个正方形中,宽高的百分之 20 大于图案的尺寸,因此图案平铺时会出现间隙。

  • patternUnits = userSpaceOnUse

除了基于被填充对象尺寸方式之外,还可以按用户单位制定图案的widthheight。此时要设置patternUnits值为userSpaceOnUse

<defs>
	<pattern id="tile" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
    	    <path d="M 0 0 Q 5 20 10 10 T 20 20" style="stroke:black;fill:none"></path>
	    <path d="M 0 0 h 20 v 20 h -20 z" style="stroke:black;fill:none"></path>
	</pattern>
</defs>
<path d="M 0 0 Q 5 20 10 10 T 20 20" style="stroke:black;fill:none"></path>
<path d="M 0 0 h 20 v 20 h -20 z" style="stroke:black;fill:none"></path>
<rect x="40" y="0" width="100" height="100" style="fill:url(#tile);stroke:black"></rect>	
<rect x="155" y="0" width="70" height="80" style="fill:url(#tile);stroke:black"></rect>
<rect x="250" y="0" width="150" height="130" style="fill:url(#tile);stroke:black"></rect>

此时明确制定了图案的宽高,并且xy表示图案与所在的坐标系对齐(0,0)。在第一个正方形中,由于正方形的xy20的整数倍,所以不会出现裁剪情况,第二,三个正方形的x坐标不是20的整数倍,所会出现裁剪。

  • patternContentUnits 属性

在上面两个例子中,pattern元素内的path元素的坐标都是用户坐标,如果想基于被填充图形设置,则需要设置patternContentUnits属性。patternContentUnits属性默认为userSpaceOnUse,当设置patternContentUnits属性为objectBoundingBox时就可以使用百分比来设置图案的大小。

<defs>
	<pattern id="tile" x="0" y="0" width=".2" height=".2" patternUnits="objectBoundingBox" patternContentUnits="objectBoundingBox">
		<path d="M 0 0 Q .05 .2 .1 .1 T .2 .2" style="stroke:black;fill:none;stroke-width:0.01;"></path>
		<path d="M 0 0 h 0.2 v 0.2 h -0.2z" style="stroke:black;stroke-width:0.01;fill:none"></path>
	</pattern>
</defs>
<g transform="translate(20,20)">
	<rect x="0" y="0" width="100" height="100" style="fill:url(#tile);stroke:black"></rect>	
</g>
<g transform="translate(135,20)">
	<rect x="0" y="0" width="150" height="100" style="fill:url(#tile);stroke:black"></rect>	
</g>
<g transform="translate(300,20)">
    <rect x="0" y="0" width="80" height="150" style="fill:url(#tile);stroke:black"></rect>	
</g>

当设置patternContentUnits属性为bojectBoundingBox时,图案的大小会根据百分比调整,主要就可以调整图案的宽高比,填满被填充图形。

此外图案也可以由另一个图案填充,这就是图案的嵌套。

# 2. 线性渐变

线性渐变是一系列颜色沿着一条直线过渡,在特定的位置指定想要的颜色,被称为渐变点。渐变点是渐变结构的一部分,颜色是表现的一部分。

线性渐变使用linearGradient元素表示:

<defs>
	<linearGradient id="linear">
		<stop offset="0%" style="stop-color:#ffcc00;"></stop>
		<stop offset="100%" style="stop-color:#0099cc;"></stop>
	</linearGradient>
</defs>
	<rect x="20" y="20" width="200" height="100" style="fill:url(#linear);stroke:black;"></rect>

stop元素有两个必要属性:offsetstop-coloroffset属性用来指定在哪个点的颜色应该等于stop-coloroffset的取值范围0%-100%。

stop元素的属性:

属性 说明
offset 必需,取值范围 0%-100%
stop-color 必需,对应 offset 位置点的颜色
stop-opacity 对应 offset 位置点的不透明度

linearGradient元素属性:

属性 说明
x1,y1 渐变的起点位置,使用百分比表示,默认的渐变方向是从左到右
x2,y2 渐变的终点位置,使用百分比表示
spreadMethod 如果设置的offset不能覆盖整个对象,该怎么填充。pad: 起点或终点颜色会扩展到对象边缘。repeat: 渐变重复起点到终点的过程。reflect: 渐变按终点-起点-终点的排列重复。

# 3. 径向渐变

径向渐变的每个渐变点是一个圆形路径,从中心点向外扩散。设置方式与线性渐变大致相同。如果填充对象边界框不是正方形的,则过渡路径会变成椭圆来匹配边界框的长宽比。

<defs>
	<radialGradient id="radial" cx="50%" cy="50%" >
		<stop offset="0%" style="stop-color:#f00;"></stop>
		<stop offset="50%" style="stop-color:#0f0;"></stop>
		<stop offset="100%" style="stop-color:#00f;"></stop>
	</radialGradient>
</defs>
<rect x="20" y="20" width="200" height="200" style="fill:url(#radial);stroke:black;"></rect>	

radialGradient元素属性:

属性 说明
cx,cy,r 定义渐变的范围,测量半径的单位是对象的宽高均值,而不是对角线,默认都为50%
fx,fy 0%点所处的圆路径的圆心,默认和cx,cy一样
spreadMethod pad,repeat,reflect 三个值,用来解决绘制范围没有到达图形边缘的情况。
最后更新: 2021/7/5 下午5:48:01