图案是非常常用的设计元素。它可以提供对比,创建一个深度感,并给组合添加趣味。SVG可以很方便地创建和使用图案,随心所欲~
我上次提到了这周要讨论一个可以定义并重用的元素,就是pattern
啦。
这篇文章我们要讨论<pattern>
元素,以及如何在SVG中使用这个元素。大概会讲SVG图案的基础,然后下一篇讲解如何创建复杂一些的图案。
SVG图案
SVG图案一般用于SVG图形对象的填充fill
或描边stroke
。这个图形可以是一个SVG元素,也可以是位图图像,通过<pattern>
元素在x
轴或y
轴方向以固定的间隔平铺。
你可以在<pattern>
元素内定义图案,然后通过id
引用。下面我们结合实例来讲解。
一个简单的图案示例
我们从一个简单的实例开始,这里我创建了一个重复的圆的图案。同样,如果你阅读了前面几篇关于SVG的文章,这些代码看起来都是很相似的。
<svg width="660" height="220">
<defs>
<pattern id="pattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<circle cx="10" cy="10" r="10" stroke="none" fill="#393" />
</pattern>
</defs>
<rect x="10" y="10" width="600" height="200" stroke="#630" stroke-width="5px" fill="url(#pattern)" />
</svg>
在<defs>
标签内定义图案。<pattern>
元素中的内容直到引用的时候才会显示。<pattern>
中定义一个id
,方便在后面被矩形引用。<rect>
元素使用图案作为填充,然后再使用纯色来作为描边。
在<pattern>
元素内,我们定义了一个半径为10(px)
的绿色圆。cx
和cy
的值(分别为10px
)设置了circle
元素的初始圆的原点,或它的左上角。
这听起来可能有点奇怪。圆怎么可能有一个左上角或者任何的角呢?不过记住我们是通过一个矩形的视窗来看SVG图形的,所以矩形区域内展示的圆确实是有一个左上角的。
在讨论剩下的代码之前,我们先来看看当前的图形长啥样。基本是一个重复绿色圆的图案。
现在来看看<pattern>
元素的属性。
<pattern id="pattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
x
和y
属性定义了图案的起点。这里我把它们都设置为0
,这样在图案开始前就不会有偏移了。前面circle
已经设置了中心在原点。设置x
和y
为0
,使得圆形的中心和图案的起点对齐了。
width
和height
属性定义了重复图案的宽度和高度。这里我给它们设置了相同的尺寸,为圆的直径,所以图案是一个一个圆挨着重复的。
理解<pattern>
元素的属性
我们来依次改变这些属性的值,看看每个属性都对应什么效果。这是当x
和y
的值都变成10
之后,输出的SVG。
<pattern id=“pattern" x=“10" y=“10" width=“20" height=“20" patternUnits="userSpaceOnUse">
第一眼看起来好像是没什么区别,但是仔细看看左上角的第一个圆。我们注意到它从绿色小圆的边缘开始重复的,而不是中心。也就是说,改变<pattern>
元素的x
和y
的值,会改变整个图案的位置。
我们把x
和y
的值设置回0
,这次我们来调整pattern
的width
和height
值。这是当width
和height
都被设置为25
时的效果,初始示例中设置的是20
。
<pattern id=“pattern" x=“0" y=“0" width=“25" height=“25" patternUnits="userSpaceOnUse">
得到的图案和第一个实例的起点位置一样,是左上角的圆的中心。注意到在各个圆之间有一些空间。这是因为本来每个圆的宽度是20px
,但是图案设置了是25px
重复一次图案,所以各个圆之间就留下了5px
的空白。
也就是说pattern的width
和height
决定的是下一个pattern出现的位置,它们允许你在pattern之间加入额外的空白。
最后一个属性是patternUnits
,定义pattern的坐标系统。它的可能值有两个,userSpaceOnUse
和objectBoundingBox
。
- userSpaceOnUse:
x
、y
、width
和height
表示的值都是当前用户坐标系统的值。也就是说,这些值没有缩放,都是绝对值。 - objectBoundingBox(默认值):
x
、y
、width
和height
表示的值都是外框的坐标系统(包裹pattern的元素)。也就是说,图案的单位进行了一个缩放,比如:pattern中为1
的值,会变成和包裹元素的外框的width
和height
一样的大小。
如果上面的定义还是理解不了,不要担心。只需要记住userSpaceOnUse
不会对pattern的单位进行缩放,但是objectBoundingBox
会。
在这系列文章的前面我们已经讨论过了重用SVG元素,所以这里重点是看看要缩放的元素。大多数情况应该是使用userSpaceOnUse
。不过,这还是取决于你的项目的具体情况。
在这篇文章中目前为止的例子中,我用的都是userSpaceOnUse
。这里有一个patternUnits
设置为objectBoundingBox
的实例。
<pattern id="pattern" x=“0" y="0" width=“20" height="20" patternUnits="objectBoundingBox">
图案发生了什么?因为我们把patternUnits
的值改成了objectBoundingBox
,而width
和height
都是20
,会被放大,至于它们具体是按照600px
(矩形的宽度)还是200px
(矩形的高度)放大,需要根据方向是x
还是y
来确定(水平方向是x600
,垂直方向是x200
)。圆形图案下一次出现的位置是在矩形之外。
使用objectBoundingBox
这个值时,width
和height
必须小于1.0
,不然图案就只会出现一次。
<svg width="660" height="220">
<defs>
<pattern id="pattern" x="0" y="0" width="0.0333" height="0.1" patternUnits="objectBoundingBox">
<circle cx="10" cy="10" r="10" stroke="none" fill="#393" />
</pattern>
</defs>
<rect x="10" y="10" width="600" height="200" stroke="#630" stroke-width="5px" fill="url(#pattern)" />
</svg>
结果如下。
你可能会很好奇我怎么得出x
和y
为0.0333
和0.1
的。因为:
20 (circle height) ÷ 200 (rectangle height) = 0.1
20 (circle width) ÷ 600 (rectangle width) = 0.0333
不过还是userSpaceOnUse
更易于使用,而且大多数时候我们都是希望图案保留绝对值尺寸,但有时你可能想要pattern缩放,这个时候可能objectBoundingBox
更好用。
使用pattern描边
我前面提到你可以使用图案作为填充和描边,尽管我这里只写了图案作为填充的示例。你可以尝试把它作为描边,看看其工作效果。
<svg width="660" height="220">
<defs>
<pattern id="pattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<circle cx="10" cy="10" r="10" stroke="none" fill="#393" />
</pattern>
</defs>
<rect x="10" y="10" width="600" height="200" stroke="url(#pattern)" stroke-width="20px" fill="#630" />
</svg>
还是那个我们已经用了很多次的图案实例。这是我最初使用的那个示例的副本,只对矩形做了一点改变。
早前我给矩形的填充引用了pattern。这里我把它作为描边,然后使用纯色来作填充。我把stroke-width
设置为20px
,这样圆圈才能完整显示出来。
结果如下。
pattern现在填充的是描边,而不是元素的背景。有一点需要注意的是,我们移动图案的位置只是在border
之内移动。而不会移动整个border
。
例如,这是SVG标签的内容,当我把x
和y
设置为10
。图案就向右边和下边各移动了10px
。
<pattern id="pattern" x=“10" y=“10" width=“20" height=“20" patternUnits="userSpaceOnUse">
多尝试,还是可以创建出很有趣的图案的。
我们今天先讲到这里,图案这部分内容还没有讲完。我们下次再见。
总结
图案可以给组合元素添加很多有趣的东西,SVG创建图案也非常容易。使用简单的图形和线条就可以定义很有趣的图案,然后通过fill
和stroke
属性就可以把它们赋给SVG对象。
今天讲得主要是图案的基础内容,还有很多。下次我们再继续讲讲一些可以给<pattern>
元素添加的属性。然后我会给你展示如何在图案中嵌套图案,来创建更复杂的图案。
本文根据@Steven Bradley的《How To Work With SVG Patterns》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://vanseodesign.com/web-design/svg-pattern-element/。
如需转载,烦请注明出处:http://www.w3cplus.com/svg/svg-pattern-element.html