svg之path詳解

svgdemo1.png

一、svg <path>介紹

path元素是SVG基本形狀中最強大的一個,它不僅能創建其他基本形狀,還能創建更多其他形狀。你可以用path元素繪制矩形(直角矩形或者圓角矩形)、圓形、橢圓、折線形、多邊形,以及一些其他的形狀,例如貝塞爾曲線、2次曲線等曲線。
path元素的形狀是通過屬性d來定義的,屬性d的值是一個“命令+參數”的序列。

每一個命令都用一個關鍵字母來表示,比如,字母“M”表示的是“Move to”命令,當解析器讀到這個命令時,它就知道你是打算移動到某個點。跟在命令字母后面的,是你需要移動到的那個點的x和y軸坐標。比如移動到(10,10)這個點的命令,應該寫成“M 10 10”。這一段字符結束后,解析器就會去讀下一段命令。每一個命令都有兩種表示方式,一種是用大寫字母,表示采用絕對定位。另一種是用小寫字母,表示采用相對定位

因為屬性d采用的是用戶坐標系統,所以不需標明單位

二、svg的 <path>命令

下面的命令可用于路徑數據:

M = moveto
L = lineto
H = horizontal lineto
V = vertical lineto
C = curveto
S = smooth curveto
Q = quadratic Bézier curve
T = smooth quadratic Bézier curveto
A = elliptical Arc
Z = closepath

注意:以上所有命令均允許小寫字母。大寫表示絕對定位,小寫表示相對定位。

1、直線命令

顧名思義,直線命令就是在兩個點之間畫直線。首先是“Move to”命令,M,需要兩個參數,分別是需要移動到點的x軸和y軸的坐標。在使用M命令移動畫筆后,只會移動畫筆,但不會在兩點之間畫線。所以M命令經常出現在路徑的開始處,用來指明從何處開始畫。

解析:
M
????移動到的點的x軸和y軸的坐標
L
????需要兩個參數,分別是一個點的x軸和y軸坐標,L命令將會在當前位置和新位置(L前面畫筆所在的點)之間畫一條線段。
H
????繪制平行線
V
????繪制垂直線
Z
????從當前點畫一條直線到路徑的起點

示例代碼及效果:


image.png
<svg width="100px" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M10 10 H 90 V 90 H 10 L 10 10"/> 
    <!-- Points -->
    <circle cx="10" cy="10" r="2" fill="red"/>
    <circle cx="90" cy="90" r="2" fill="red"/>
    <circle cx="90" cy="10" r="2" fill="red"/>
    <circle cx="10" cy="90" r="2" fill="red"/>
</svg>

可以通過一個“閉合路徑命令”Z來簡化上面的path,簡寫形式:

<svg width="100px" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <path d="M10 10 H 90 V 90 H 10 Z" fill="transparent" stroke="black"/>
   <!-- Points -->
   <circle cx="10" cy="10" r="2" fill="red"/>
   <circle cx="90" cy="90" r="2" fill="red"/>
   <circle cx="90" cy="10" r="2" fill="red"/>
   <circle cx="10" cy="90" r="2" fill="red"/>
</svg>

相對命令使用的是小寫字母,它們的參數不是指定一個明確的坐標,而是表示相對于它前面的點需要移動多少距離。相對坐標形式:

<svg width="100px" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path d="M10 10 h 80 v 80 h -80 Z" fill="transparent" stroke="black"/>
   <!-- Points -->
   <circle cx="10" cy="10" r="2" fill="red"/>
   <circle cx="90" cy="90" r="2" fill="red"/>
   <circle cx="90" cy="10" r="2" fill="red"/>
   <circle cx="10" cy="90" r="2" fill="red"/>
</svg>

原理分析:畫筆移動到(10,10)點,由此開始,向右移動80像素構成一條水平線,然后向下移動80像素,然后向左移動80像素,最后再回到起點。

2、曲線命令

繪制平滑曲線的命令有三個,其中兩個用來繪制貝塞爾曲線,另外一個用來繪制弧形或者說是圓的一部分。
在path元素里,只存在兩種貝塞爾曲線:三次貝塞爾曲線C,和二次貝塞爾曲線Q。

(1)三次貝塞爾曲線

三次貝塞爾曲線需要定義一個點和兩個控制點,所以用C命令創建三次貝塞爾曲線,需要設置三組坐標參數:C x1 y1, x2 y2, x y (or c dx1 dy1, dx2 dy2, dx dy),最后一個坐標(x,y)表示的是曲線的終點,另外兩個坐標是控制點,(x1,y1)是起點的控制點,(x2,y2)是終點的控制點。

示例代碼及效果圖:


image.png
<!--三次貝塞爾曲線-->
<svg width="190px" height="160px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M130 110 C 120 140, 180 140, 170 110" stroke="black" fill="transparent"/>
    <circle cx="130" cy="110" r="2" fill="red"/>
    <circle cx="120" cy="140" r="2" fill="red"/>
    <line x1="130" y1="110" x2="120" y2="140" style="stroke:rgb(255,0,0);stroke-width:2"/>
    <circle cx="180" cy="140" r="2" fill="red"/>
    <circle cx="170" cy="110" r="2" fill="red"/>
    <line x1="180" y1="140" x2="170" y2="110" style="stroke:rgb(255,0,0);stroke-width:2"/>
</svg>

原理分析:曲線沿著起點到第一控制點的方向伸出,逐漸彎曲,然后沿著第二控制點到終點的方向結束。

簡寫的貝塞爾曲線命令S

一個點某一側的控制點是它另一側的控制點的對稱(以保持斜率不變)。可以使用一個簡寫的貝塞爾曲線命令S:S x2 y2, x y (or s dx2 dy2, dx dy),S命令可以用來創建與之前那些曲線一樣的貝塞爾曲線,但是,如果S命令跟在一個C命令或者另一個S命令的后面,它的第一個控制點,就會被假設成前一個控制點的對稱點。如果S命令單獨使用,前面沒有C命令或者另一個S命令,那么它的兩個控制點就會被假設為同一個點。

示例代碼及效果圖:


image.png
<!--三次貝塞爾曲線簡寫-->
<svg width="190px" height="160px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" stroke="black" fill="transparent"/>
    <circle cx="10" cy="80" r="2" fill="red"/>
    <circle cx="40" cy="10" r="2" fill="red"/>
    <line x1="10" y1="80" x2="40" y2="10" style="stroke:rgb(255,0,0);stroke-width:1"/>

    <circle cx="65" cy="10" r="2" fill="red"/>
    <circle cx="95" cy="80" r="2" fill="red"/>
    <line x1="65" y1="10" x2="95" y2="80" style="stroke:rgb(255,0,0);stroke-width:1"/>

    <circle cx="125" cy="150" r="2" fill="blue"/>
    <circle cx="180" cy="80" r="2" fill="red"/>
    <circle cx="150" cy="150" r="2" fill="red"/>
    <line x1="95" y1="80" x2="125" y2="150" style="stroke:blue;stroke-width:1"/>
    <line x1="180" y1="80" x2="150" y2="150" style="stroke:rgb(255,0,0);stroke-width:1"/>
</svg>
(2)二次貝塞爾曲線

二次貝塞爾曲線Q比三次貝塞爾曲線簡單,只需要一個控制點,用來確定起點和終點的曲線斜率。需要兩組參數,控制點和終點坐標。Q命令:Q x1 y1, x y (or q dx1 dy1, dx dy)

示例代碼及效果圖:


image.png
<!--二次貝塞爾曲線-->
<svg width="190px" height="160px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M10 80 Q 95 10 180 80" stroke="black" fill="transparent"/>
     <!--Points-->
    <circle cx="10" cy="80" r="2" fill="red"/>
    <circle cx="95" cy="10" r="2" fill="red"/>
    <circle cx="180" cy="80" r="2" fill="red"/>
    <line x1="10" y1="80" x2="95" y2="10" style="stroke:rgb(255,0,0);stroke-width:1"/>
    <line x1="95" y1="10" x2="180" y2="80" style="stroke:rgb(255,0,0);stroke-width:1"/>
</svg>  

簡寫的貝塞爾曲線命令T

就像三次貝塞爾曲線有一個S命令,二次貝塞爾曲線有一個差不多的T命令,可以通過更簡短的參數,延長二次貝塞爾曲線。T x y (or t dx dy),快捷命令T會通過前一個控制點,推斷出一個新的控制點。這意味著,在你的第一個控制點后面,可以只定義終點,就創建出一個相當復雜的曲線。需要注意的是,T命令前面必須是一個Q命令,或者是另一個T命令,才能達到這種效果。如果T單獨使用,那么控制點就會被認為和終點是同一個點,所以畫出來的將是一條直線。

示例代碼及效果圖:


image.png
<!--二次貝塞爾曲線簡寫-->
<svg width="190px" height="160px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M10 80 Q 52.5 10, 95 80 T  180 80" stroke="black" fill="transparent"/>

    <circle cx="10" cy="80" r="2" fill="red"/>
    <circle cx="52.5" cy="10" r="2" fill="red"/>
    <line x1="10" y1="80" x2="52.5" y2="10" style="stroke:rgb(255,0,0);stroke-width:1"/>

    <circle cx="95" cy="80" r="2" fill="red"/>
    <line x1="95" y1="80" x2="52.5" y2="10" style="stroke:rgb(255,0,0);stroke-width:1"/>

    <circle cx="180" cy="80" r="2" fill="blue"/>
    <circle cx="137.5" cy="150" r="2" fill="blue"/>
    <line x1="95" y1="80" x2="137.5" y2="150" style="stroke:rgb(0,0,255);stroke-width:1"/>
    <line x1="137.5" y1="150" x2="180" y2="80" style="stroke:rgb(0,0,255);stroke-width:1"/>
</svg>
(3)弧形

A命令的參數:
A rx ry x-axis-rotation large-arc-flag sweep-flag x y
或者 a rx ry x-axis-rotation large-arc-flag sweep-flag dx dy

弧形命令A的前兩個參數分別是x軸半徑和y軸半徑,弧形命令A的第三個參數表示弧形的旋轉情況,large-arc-flag(角度大小) 和sweep-flag(弧線方向),large-arc-flag決定弧線是大于還是小于180度,0表示小角度弧,1表示大角度弧。sweep-flag表示弧線的方向,0表示從起點到終點沿逆時針畫弧,1表示從起點到終點沿順時針畫弧。

示例代碼及效果圖:


image.png
<svg width="320px" height="320px" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <path d="M10 315
           L 110 215
           A 30 50 0 0 1 162.55 162.45
           L 172.55 152.45
           A 30 50 -45 0 1 215.1 109.9
           L 315 10" stroke="black" fill="green" stroke-width="2" fill-opacity="0.5"/>
</svg>
原理分析:

如圖例所示,畫布上有一條對角線,中間有兩個橢圓弧被對角線切開(x radius = 30, y radius = 50)。第一個橢圓弧的x-axis-rotation(x軸旋轉角度)是0,所以弧形所在的橢圓是正置的(沒有傾斜)。在第二個橢圓弧中,x-axis-rotation設置為-45,所以這是一個旋轉了45度的橢圓,并以短軸為分割線,形成了兩個對稱的弧形。

參考:路徑-SVG|MDN
參考:svg教程

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • ****此篇為svg的進階介紹篇,了解更多關于svg的介紹請看 HTML5學習--SVG全攻略(基礎篇)*** *...
    nightZing閱讀 5,489評論 3 27
  • 【Android 自定義View之繪圖】 基礎圖形的繪制 一、Paint與Canvas 繪圖需要兩個工具,筆和紙。...
    Rtia閱讀 11,741評論 5 34
  • SVG是什么 可縮放矢量圖形(Scalable Vector Graphics),一種用來描述二位矢量圖形的XML...
    greenteaObject閱讀 2,645評論 0 1
  • 使用XML描述的矢量文件W3C標準(1.1):http://www.w3.org/TR/SVG11/瀏覽器支持情況...
    沒汁帥閱讀 6,049評論 0 16
  • 一是自己的方面。 2017年,我的定位是尋找可能性的一年。在尋找可能性的時候,我會大幅減少天氣預報的量,更多會涉及...
    魔法密林港閱讀 250評論 0 0