Patterns - SVG 编辑

« 上一页下一页 »

图案

在我看来patterns(图案)是SVG中用到的最让人混淆的填充类型之一。它的功能非常强大,所以我认为他们值得讨论一下并且我们应至少对他们有最基本的了解。跟渐变一样,<pattern>需要放在SVG文档的<defs>内部。

<?xml version="1.0" standalone="no"?>
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <linearGradient id="Gradient1">
      <stop offset="5%" stop-color="white"/>
      <stop offset="95%" stop-color="blue"/>
    </linearGradient>
    <linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
      <stop offset="5%" stop-color="red"/>
      <stop offset="95%" stop-color="orange"/>
    </linearGradient>

    <pattern id="Pattern" x="0" y="0" width=".25" height=".25">
      <rect x="0" y="0" width="50" height="50" fill="skyblue"/>
      <rect x="0" y="0" width="25" height="25" fill="url(#Gradient2)"/>
      <circle cx="25" cy="25" r="20" fill="url(#Gradient1)" fill-opacity="0.5"/>
    </pattern>

  </defs>

  <rect fill="url(#Pattern)" stroke="black" x="0" y="0" width="200" height="200"/>
</svg>
ScreenshotLive sample

在pattern元素内部你可以包含任何之前包含过的其它基本形状,并且每个形状都可以使用之前学习过的任何样式样式化,包括渐变和半透明。这里我们在pattern中绘制两个矩形(两个矩形互相重叠,一个矩形是另一个矩形大小的二倍,且用于填充整个pattern)和一个圆。

关于pattern容易混淆的事是,pattern定义了一个单元系统以及他们的大小。上例中,我们在pattern元素上定义了widthheight属性,用于描述在重复下一个图案之前应该跨过多远。如果你想要在绘制时偏移矩形的开始点,也可以使用x和y属性,原因如下。

就像前面使用了gradientUnits属性,同样的pattern也有一个属性patternUnits用于描述我们使用的属性单元。这同之前使用的objectBoundingBox默认值一样,所以当一个值为 1 时,它被缩放到应用 pattern 对象的宽高值。因此,我们希望 pattern 垂直和水平的重复4次,所以宽高被设置位0.25,这一位置 pattern 的宽高仅为总外框大小的 0.25。

与渐变不同,pattern有第二个属性patternContentUnits,它描述了pattern元素基于基本形状使用的单元系统,这个属性默认值为userSpaceOnUse,与patternUnits属性相反,这意味着除非你至少指定其中一个属性值(patternContentUnitspatternUnits),否则在pattern中绘制的形状将与pattern元素使用的坐标系不同,当你手写这部分时会容易混淆。为了使上例生效,我们必须考虑我们的边框(200像素)大小和我们实际希望pattern垂直和水平重复 4 次的需求。这意味着每个 pattern 单元应该是 50x50 的方形,pattern 中的两个矩形和圆形的大小会被缩放适应到一个 50x50 的边框里,任何我们绘制在边框外的内容都不会显示。因为我们希望 pattern 从边框的左上角里开始,所以 pattern 也必须偏移 10 像素,也就是 pattern 的 xy 属性需要调整为 10/200=0.05

如果对象改变了大小,pattern会自适应其大小,但是对象里面的内容不会自适应。所以当我们在 pattern 中还是放置 4 个重复的 pattern 时,组成 pattern 的对象将不会保持相同的大小,同时在他们之间会有大片空白区域。通过改变patternContentUnits属性,我们可以把所有的元素放到相同的单元系统中:

 <pattern id="Pattern" width=".25" height=".25" patternContentUnits="objectBoundingBox">
   <rect x="0" y="0" width=".25" height=".25" fill="skyblue"/>
   <rect x="0" y="0" width=".125" height=".125" fill="url(#Gradient2)"/>
   <circle cx=".125" cy=".125" r=".1" fill="url(#Gradient1)" fill-opacity="0.5"/>
 </pattern>

现在,因为pattern内容与pattern本身处于相同的单元系统中,所以我们不用偏移边框以使pattern在正确的位置上开始,并且即使对象变大,pattern也会自动的缩放以保证pattern内部的对象数目和重复不变。这与 userSpaceOnUse系统不同,userSpaceOnUse 系统中如果对象改变大小,pattern本身会保持不变,只是重复更多次去填满边框。

它有一点点的副作用,在Gecko中的圆如果半径设置得小于0.075(尽管半径应该设置的比这个值大得多。这个可能是pattern元素中的一个bug,或者也不算bug,我也不太清楚)的话绘制的时候可能会出现问题,为了规避这个问题,可能最好的办法是尽量避免在objectBoundingBox单元中绘制图形。

在你想要使用pattern的时候,可能你并不中意这些方法中的任何一个,Pattern通常都是有确认的大小并且重复他们自己,与对象形状独立开来。要想创建这种pattern,pattern和它的内容必须在当前用户空间中绘制,这样当对象在做如下操作时他们才不会改变形状:

 <pattern id="Pattern" x="10" y="10" width="50" height="50" patternUnits="userSpaceOnUse">
   <rect x="0" y="0" width="50" height="50" fill="skyblue"/>
   <rect x="0" y="0" width="25" height="25" fill="url(#Gradient2)"/>
   <circle cx="25" cy="25" r="20" fill="url(#Gradient1)" fill-opacity="0.5"/>
 </pattern>

当然,这意味着如果你后续改变了对象大小,pattern也不会缩放。上述三个举例在下图中放在一个矩形中展示,高度被轻微拉伸到300px,但是我注意到这不是完整的图片,并且有些其他选项可能你的应用不支持。

Image:SVG_Pattern_Comparison_of_Units.png

« 上一页下一页 »

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

词条统计

浏览:84 次

字数:8883

最后编辑:7 年前

编辑次数:0 次

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文