在 SVG 的 fill 裡有一個很特別的填色方式叫做 pattern,這邊指的是我們可以定義(defs)好一個圖樣(pattern),之後再用 fill 的方式去指定用那個圖案去填滿。
這些是 pattern 可以定義的屬性:
- patternUnits = "userSpaceOnUse | objectBoundingBox"
- patternContentUnits = "userSpaceOnUse | objectBoundingBox"
- patternTransform
- x
- y
- width
- height
- xlink:href
- preserveAspectRatio = "[defer] []"
其中 patternUnits 是用來定義單位的,分別說明一下兩個值:
- userSpaceOnUse: 代表 pattern 上定義的長寬是實際數值,pattern 會按照 svg 的 "使用的座標系" 做調整。
- objectBoundingBox:預設值,代表 pattern 上定義的長寬是 "比例" ,要乘上套用圖案的長寬,才是真正的 pattern 尺寸。
userSpaceOnUse 比較好理解,我們先定義一個 pattern:
<defs>
<pattern id="title" 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 h20 v20 h-20 z" style="stroke: gray; fill: none"></path>
</pattern>
</defs>
可以在以下範例看到 pattern 會依據我們定義的大小填滿空間,如果 pattern 裡面的圖形小於他的範圍,圖形會被裁掉。
那如果是設定為 objectBoundingBox 則會變成是依據你要放 pattern 的區塊的比例的關係,像這邊我們把 width 跟 height 都設為 20%,之後要使用這個 pattern 的區塊就會先均分成五等分後,再把 pattern 填入:
<defs>
<pattern id="title" 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 h20 v20 h-20 z" style="stroke: gray; fill: none"></path>
</pattern>
</defs>
可以注意到只是 pattern 的位置是均分區塊,但大小不變。
那如果我們希望 pattern 跟著比例調整大小,則可以將 patternContentUnits 的屬性指定為 objectBoundingBox,預設值則為 userSpaceOnUse 就是維持原本的大小。
patternTransform 則是可以讓定義好的 pattern 變形,可以參考這樣的寫法來調整變形的內容:
patternTransform="rotate(20)
skewX(30)
scale(1 0.5)"
要注意跟 CSS 的 transform 看起來有點像但寫法是不一樣的。
最後看一下我們還可以利用 pattern 使用 pattern 的方式,把圖形再拆的更細,這樣就有機會讓我們的 pattern 更有彈性。