SVG 擠出與匯入相容性參考
返回第 39 課示範,在編輯器中實際操作。
SVG 支援條件
轉換器接受帶有一層實心填色的封閉輪廓。<path>、<line>、<polyline>、<polygon>、<rect>、<circle> 或 <ellipse> 上的實心 SVG 描邊,會展開成封閉、可編輯的 Path。
因此只有描邊的開放直線與路徑也可以擠出。當圖形同時有填色與描邊時,描邊會變成填色來源上方的另一個 Path;兩者都保留 SVG 群組變換,並且可以匯出成 GLB。
圓形與方形線帽,以及圓角、斜角與斜接接合都會保留。SVG 的 stroke="none" 佔位會被忽略。
轉換器保留 fill-rule,包含 evenodd 孔洞,並從 SVG 群組繼承塗料與描邊寬度。一般的填色矩形仍是可編輯的 Rect 節點;圓角矩形、橢圓與封閉折線會變成可編輯的 Path。
內嵌 style 宣告裡的填色、描邊、不透明度、填色規則與描邊幾何,會覆寫表現屬性。fill="currentColor" 與 stroke="currentColor" 會依圖形、群組、<use> 實例或 SVG 根上最近的 color 解析;沒有顏色時預設為黑色。
透過 style 提供的描邊也可以展開。外部 CSS 樣式表不會被解析。
擠出時,圓角矩形會把 SVG 各自的 rx 與 ry 保留成橢圓圓角弧。缺少的半徑會預設成另一個,而且每個半徑會被限制在對應尺寸的一半以內。
一般的 2D Rect 匯入器仍然只儲存單一圓角半徑。 可解析、長度為正的 SVG 虛線樣式,包含奇數長度的樣式與 stroke-dashoffset,會展開成各自可編輯的實心輪廓。
長度為零的虛線搭配圓形線帽,會產生一個擠出的圓點。non-scaling-stroke 會在 SVG 群組變換與 viewBox 縮放中保持指定的寬度:匯入器先投影中心線,再把它展開成可編輯的 3D 輪廓。
這個寬度在匯入時就固定,因此之後編輯器縮放會照常縮放 3D Mesh。裁剪路徑或 slice 視埠下的非縮放描邊、長度為零的間隙、搭配其他線帽且長度為零的虛線、漸層、塗料伺服器,以及不支援的 SVG 圖形,仍留在 2D。
圖案與漸層
自足的 <pattern> 填色,若使用整數像素磁磚且 patternUnits="userSpaceOnUse",會匯入成重複的 2D 填色。磁磚可以包含基本 SVG 圖形;圖案可使用本地 <use>、繼承與線性或放射漸層,並可嵌入 PNG、JPEG、WebP 或 AVIF 圖片。
數值 x / y 原點受支援;外部參考、外部圖片與循環參考不支援。支援的 patternTransform 函式(matrix、translate、scale、rotate 與 skew)在匯入的填色上仍可編輯。
畫布放大時,SVG 圖案磁磚會從向量來源重繪。磁磚間距在畫布座標中保持固定,柵格尺寸則以紋理上限為頂。
矩形上的圓形 <radialGradient> 填色,若使用 userSpaceOnUse、明確的數值中心與半徑,以及置中的焦點,也會以 2D 保留。矩形、圓、橢圓、路徑與多邊形上其他自足的放射漸層,包含橢圓漸層、偏移的焦點與漸層變換,會使用柵格化的 SVG 影像填色。
圖形仍可編輯,而它的漸層色標烘進該影像,而不是各自可編輯的塗料控制。 你放大時,SVG 影像填色會從向量來源重繪,直到紋理尺寸上限,因此邊緣在較高倍率下仍比較銳利。
如果描邊無法產生有效的封閉 Mesh,就保留它原來的 2D 節點。 展開後的描邊輪廓在座標正規化時保留六位小數,因此很細的細節不會在最終 Mesh 檢查之前塌掉。
本地參考與視埠
本地的 <use href="#id"> 與舊式 xlink:href 對支援圖形或群組的參考,會建立獨立實例,包含向前參考與重複參考。實例的像素偏移、變換與繼承的填色會在擠出之前套用;每個實例得到自己可編輯的 ID。
循環與無法解析的參考會被跳過。<use> 也可以參考帶有 viewBox 的 <symbol>,只要實例或 symbol 提供正的像素 width 與 height。
實例尺寸覆寫 symbol 的尺寸。symbol 的 preserveAspectRatio 支援 meet 對齊、none,以及擠出輪廓的 slice 裁切。
若有效尺寸不存在或無效,就跳過該 symbol 實例。外部參考尚未匯入。
帶有明確正像素尺寸與 viewBox 的巢狀 <svg> 元素,也會建立可編輯的視埠群組。它們的 x/y、變換與 preserveAspectRatio 會影響擠出的子節點。
本地的 <use> 可以參考其中一個 SVG 元素,並獨立覆寫它的視埠尺寸。巢狀 SVG 視埠預設會裁切產生的擠出輪廓,包含 slice;設定 overflow="visible" 可保留超出的幾何。
完全包含在內的圖形保持群組關係,因此移動視埠群組也會移動它們的 3D Mesh。跨過邊緣的圖形成為裁切後的 Path。
裁剪與可見性
本地的 clip-path="url(#id)" 與內嵌 CSS clip-path 現在也會裁切符合條件的 3D 輪廓。<clipPath> 可以包含 Path、多邊形、折線、矩形、圓、橢圓、巢狀群組,以及對那些圖形的本地 <use> 參考。
它的圖形形成聯集;clip-rule="evenodd" 可以挖孔。群組與重複 <use> 實例上的裁剪跟隨它們的變換,多個祖先裁剪彼此相交,也與 SVG 視埠相交。
clipPathUnits="objectBoundingBox" 使用單一圖形的範圍,或群組所支援子圖形的範圍,包含它們的變換。被裁切的輪廓變成可編輯的 Path;完全位於裁剪內的輪廓保留原來的節點與群組關係。
無法解析或不支援的裁剪定義留在 2D。遮罩、濾鏡、裁剪路徑裡的文字,以及外部裁剪參考,不會轉成 3D。
帶有 display="none" 或繼承 visibility="hidden" 的元素不會產生 3D Mesh;後代可以明確設定 visibility="visible"。 把根 <svg> 傳進去,即可套用明確的像素 width/height 與 viewBox,包含 preserveAspectRatio。
填色擠出也會保留巢狀群組中 SVG 的 skewX、skewY,以及剪切過的 matrix(...) 變換。當組合變換包含剪切時,這些輪廓會變成以取樣線段構成、仍可編輯的 Path。
一般的 viewBox 縮放會讓矩形與曲線 Path 以原來的形式保持可編輯。沒有明確像素視埠尺寸的 SVG 保留它們的 viewBox 座標。
不支援的 2D 圖形仍使用一般的 SVG 匯入器,它不會保留來源剪切。
使用 preserveAspectRatio="slice" 時,填色擠出輪廓會裁切到視埠,包含孔洞,以及被分成分開島嶼的圖形。完全位於視埠內的圖形保持 Rect 或曲線 Path 的形式。不支援的 2D 圖形仍跟隨一般匯入器,不會被這個輔助函式裁切。
範例與效能
在第 39 課的示範中選擇 Repeated use sample,檢視同一個定義的兩個實例使用不同填色,旁邊還有一個一般矩形。 選擇 Symbol viewport sample,比較一個有孔 symbol 的兩個視埠實例。第一個使用 symbol 的尺寸;第二個設定自己的尺寸。 選擇 Nested SVG viewport sample,比較一個內嵌 SVG 視埠,以及用 <use> 參考的第二個實例;它們的擠出輪廓會裁切到各自的視埠。 選擇 Paint style + currentColor sample,比較繼承的顏色與實例專用的顏色、一個內嵌填色覆寫,以及一個有樣式的描邊。 選擇 Stroke caps + joins sample,比較圓形與方形線帽、一個帶有分開 3D 輪廓的填色圖形、群組變換下的非縮放描邊、擠出的虛線描邊,以及圓點。 選擇 Clip paths + repeated use sample,檢視兩個各自裁切、帶有孔洞的實例,以及一個由物件範圍聯集裁切的圖形。 選擇 Group bounds + clip use sample,檢視變換群組上的物件範圍裁剪,其中兩個窗口重用一個本地定義。
SVG 預先檢查會判斷每條輪廓能否形成 Mesh。得到的 CPU 幾何保存在最近的快取裡,最多 256 個 Mesh、幾何陣列合計 8 MiB,因此非同步的畫布更新建立 3D 伴生時可以重用它。較舊的項目會被逐出;GPU 幾何有自己的每畫布快取。 執行 pnpm bench:svg-import:browser,檢視儲存庫的 Ghostscript Tiger SVG 與其他代表性圖稿的匯入與編輯計時。你也可以下載該 SVG,並用第 39 課的 Upload SVG 檢視可編輯圖層,以及比較不同縮放層級。 當匯入的 SVG 圖層重疊時,它們擠出後的正面保留 SVG 繪製順序,包含巢狀群組內的圖層。較晚的圖層在連動 3D 視圖中仍蓋在較早的圖層之上。 GLB 匯出以相同的由前到後走訪順序列出擠出節點,我們的 glTF 匯入器會保留這個順序。對於同一平面上不透明、平坦的擠出,匯出也會把重疊圖層在深度上分開,最多為最薄擠出厚度的 5%。這讓 glTF 檢視器得到不同的深度緩衝值,而不移動畫布上可編輯的圖形。每一組互不相交的堆疊各自處理,因此遠處的 3D Mesh 不會關閉這個間距。若某個堆疊的投影範圍與傾斜或透明的擠出、另一個抬升,或一個獨立的 3D Mesh 重疊,則保留它原本寫入的變換。極大或極遠的模型,仍可能因為檢視器的深度緩衝精度而失去微小的深度差異。