SVG 中的漸變
除了簡單的填充和描邊之外,更令人興奮的或許是,您還可以建立和應用漸變作為填充或描邊。
SVG 漸變有兩種型別:線性漸變和徑向漸變。它們與使用它們的位置分開定義,這有助於重用。您必須為每個漸變指定一個 id 屬性,以允許其他元素引用它。漸變定義可以放在 <defs> 元素或 <svg> 元素中。
線性漸變
線性漸變沿直線變化。要插入一個線性漸變,您需要在 SVG 檔案的 <defs> 部分內建立一個 <linearGradient> 節點。
基本示例
<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="Gradient1">
<stop class="stop1" offset="0%" />
<stop class="stop2" offset="50%" />
<stop class="stop3" offset="100%" />
</linearGradient>
<linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
<stop offset="0%" stop-color="red" />
<stop offset="50%" stop-color="black" stop-opacity="0" />
<stop offset="100%" stop-color="blue" />
</linearGradient>
</defs>
<style>
#rect1 {
fill: url("#Gradient1");
}
.stop1 {
stop-color: red;
}
.stop2 {
stop-color: black;
stop-opacity: 0;
}
.stop3 {
stop-color: blue;
}
</style>
<rect id="rect1" x="10" y="10" rx="15" ry="15" width="100" height="100" />
<rect
x="10"
y="120"
rx="15"
ry="15"
width="100"
height="100"
fill="url(#Gradient2)" />
</svg>
上面是一個將線性漸變應用於 <rect> 元素的示例。線性漸變內部有多個 <stop> 節點。這些節點透過指定位置的 offset 屬性和 stop-color 屬性來告訴漸變在特定位置應該是什麼顏色。這可以直接分配,也可以透過 CSS 分配。出於本示例的目的,這兩種方法已混合使用。例如,這個例子告訴漸變從紅色開始,中間變為透明黑色,最後變為藍色。您可以插入任意數量的停止顏色,以建立您需要的漂亮或醜陋的混合,但偏移量應始終從 0%(或如果您想省略百分號,則為 0)增加到 100%(或 1)。重複的值將使用在 XML 樹中分配最遠的停止點。此外,與填充和描邊一樣,您可以指定 stop-opacity 屬性來設定該位置的不透明度(同樣,在 FF3 中,您也可以使用 rgba 值來完成此操作)。
<stop offset="100%" stop-color="yellow" stop-opacity="0.5"/>
要使用漸變,您必須從物件的 fill 或 stroke 屬性中引用它。這與您在 CSS 中引用元素的方式相同,使用 url。在這種情況下,url 只是對我們漸變的引用,該漸變具有創意 ID“Gradient1”。要附加它,將 fill 設定為 url("#Gradient1"),瞧!我們的物件現在是多色的。您可以對 stroke 執行相同的操作。
<style>
#rect1 {
fill: url("#Gradient1");
}
</style>
<linearGradient> 元素還接受其他幾個屬性,這些屬性指定漸變的大小和外觀。漸變的方向由兩個點控制,由屬性 x1、x2、y1 和 y2 指定。這些屬性定義了漸變所沿的線。漸變預設為水平方向,但可以透過更改這些屬性來旋轉它。上面示例中的 Gradient2 旨在建立垂直漸變。
<linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1"></linearGradient>
注意:您也可以在漸變上使用 href 屬性。使用此屬性時,一個漸變的屬性和停止點可以包含在另一個漸變中。在上面的示例中,您不必在 Gradient2 中重新建立所有停止點。
<linearGradient id="Gradient1">
<stop id="stop1" offset="0%" />
<stop id="stop2" offset="50%" />
<stop id="stop3" offset="100%" />
</linearGradient>
<linearGradient
id="Gradient2"
x1="0"
x2="0"
y1="0"
y2="1"
xmlns:xlink="http://www.w3.org/1999/xlink"
href="#Gradient1" />
我們在這裡直接在節點上包含了 xlink 名稱空間,儘管通常您會在文件頂部定義它。當我們談論影像時,會對此有更多介紹。
徑向漸變
徑向漸變與線性漸變相似,但它們繪製的漸變從一個點向外輻射。要建立徑向漸變,您需要在文件的 <defs> 部分新增一個 <radialGradient> 元素。
基本示例
<?xml version="1.0" standalone="no"?>
<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="RadialGradient1">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="blue" />
</radialGradient>
<radialGradient id="RadialGradient2" cx="0.25" cy="0.25" r="0.25">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="blue" />
</radialGradient>
</defs>
<rect
x="10"
y="10"
rx="15"
ry="15"
width="100"
height="100"
fill="url(#RadialGradient1)" />
<rect
x="10"
y="120"
rx="15"
ry="15"
width="100"
height="100"
fill="url(#RadialGradient2)" />
</svg>
這裡使用的停止點與之前相同,但現在物件中心將是紅色,並向各個方向逐漸變為藍色。與線性漸變一樣,<radialGradient> 節點可以接受多個屬性來描述其位置和方向。然而,與線性漸變不同,它要複雜得多。徑向漸變再次由兩個點定義,這兩個點決定了它的邊緣。第一個點定義了一個漸變結束的圓。它需要一箇中心點,由 cx 和 cy 屬性指定,以及一個半徑 r。設定這三個屬性將允許您移動漸變並更改其大小,如上面第二個 rect 所示。
第二個點稱為焦點,由 fx 和 fy 屬性定義。第一個點描述了漸變的邊緣,而焦點描述了它的中間位置。透過示例更容易理解這一點。
中心點和焦點
<?xml version="1.0" standalone="no"?>
<svg width="120" height="120" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="Gradient" cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="blue" />
</radialGradient>
</defs>
<rect
x="10"
y="10"
rx="15"
ry="15"
width="100"
height="100"
fill="url(#Gradient)"
stroke="black"
stroke-width="2" />
<circle
cx="60"
cy="60"
r="50"
fill="transparent"
stroke="white"
stroke-width="2" />
<circle cx="35" cy="35" r="2" fill="white" stroke="white" />
<circle cx="60" cy="60" r="2" fill="white" stroke="white" />
<text x="38" y="40" fill="white" font-family="sans-serif" font-size="10pt">
(fx,fy)
</text>
<text x="63" y="63" fill="white" font-family="sans-serif" font-size="10pt">
(cx,cy)
</text>
</svg>
如果焦點移到前面描述的圓圈之外,漸變將無法正確渲染,因此該點將被假定為在圓圈邊緣之內。如果沒有給出焦點,則假定它與中心點在同一位置。
線性和徑向漸變還接受其他幾個屬性來描述它們可能經歷的變換。我在這裡想提及的唯一其他屬性是 spreadMethod 屬性。此屬性控制當漸變到達其終點但物件尚未填充時會發生什麼。它可以採用三個值之一:"pad"、"reflect" 或 "repeat"。"pad" 是您到目前為止所看到的。當漸變到達其終點時,最終偏移顏色用於填充物件的其餘部分。"reflect" 導致漸變繼續,但反向反射,從 100% 處的顏色偏移開始,然後返回到 0% 處的偏移,然後再返回。"repeat" 也允許漸變繼續,但不是向後,而是直接跳回開頭並再次執行。
擴充套件方法
<?xml version="1.0" standalone="no"?>
<svg width="220" height="220" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient
id="GradientPad"
cx="0.5"
cy="0.5"
r="0.4"
fx="0.75"
fy="0.75"
spreadMethod="pad">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="blue" />
</radialGradient>
<radialGradient
id="GradientRepeat"
cx="0.5"
cy="0.5"
r="0.4"
fx="0.75"
fy="0.75"
spreadMethod="repeat">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="blue" />
</radialGradient>
<radialGradient
id="GradientReflect"
cx="0.5"
cy="0.5"
r="0.4"
fx="0.75"
fy="0.75"
spreadMethod="reflect">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="blue" />
</radialGradient>
</defs>
<rect
x="10"
y="10"
rx="15"
ry="15"
width="100"
height="100"
fill="url(#GradientPad)" />
<rect
x="10"
y="120"
rx="15"
ry="15"
width="100"
height="100"
fill="url(#GradientRepeat)" />
<rect
x="120"
y="120"
rx="15"
ry="15"
width="100"
height="100"
fill="url(#GradientReflect)" />
<text x="15" y="30" fill="white" font-family="sans-serif" font-size="12pt">
Pad
</text>
<text x="15" y="140" fill="white" font-family="sans-serif" font-size="12pt">
Repeat
</text>
<text x="125" y="140" fill="white" font-family="sans-serif" font-size="12pt">
Reflect
</text>
</svg>
兩種漸變還有一個名為 gradientUnits 的屬性,它描述了您在描述漸變大小或方向時將使用的單位系統。這裡有兩種可能的值:"userSpaceOnUse" 或 "objectBoundingBox"。"objectBoundingBox" 是預設值,所以這就是到目前為止所展示的。它實質上將漸變縮放到物件的大小,因此您只需指定從零到一的值的座標,它們就會自動縮放到物件的大小。userSpaceOnUse 本質上接受絕對單位。所以您必須知道物件的位置,並將漸變放置在相同的位置。上面的徑向漸變將被重寫
<radialGradient
id="Gradient"
cx="60"
cy="60"
r="50"
fx="35"
fy="35"
gradientUnits="userSpaceOnUse"></radialGradient>
您還可以透過使用 gradientTransform 屬性將另一個變換應用於漸變,但由於我們尚未介紹變換,我們將把它留到以後再討論。
當物件邊界框不是正方形時,處理 gradientUnits="objectBoundingBox" 還有一些其他注意事項,但它們相當複雜,需要更瞭解情況的人來解釋。