SVG 路徑(path)

本文轉自:https://developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorial/Pathshtml

<path>元素是SVG基本形狀中最強大的一個,它不只能建立其餘基本形狀,還能建立更多其餘形狀。編輯器

另外,path只須要設定不多的點,就能夠建立平滑流暢的線條(好比曲線)。雖然polyline元素也能實現相似的效果,可是必須設置大量的點 (點越密集,越接近連續,看起來越平滑流暢),而且這種作法不可以放大(放大後,點的離散更明顯)。爲了更好的理解path,你最好用path實際畫一個 SVG圖形,雖然用XML或文本編輯器來編輯path元素不是很容易,但能夠幫助咱們理解path是如何工做的,因此,你就忍了吧。svg

上一章提到過,path元素的形狀是經過d屬性定義的,d屬性的值是一個「命令+參數」的序列,咱們將學習這些命令,而且看到不少相關的示例。性能

每個命令都用一個關鍵字母來表示,好比,字母「M」表示的是「Move to」命令,當解析器讀到這個命令時,它就知道你是打算移動到某個點。跟在命令字母后面的,是你須要移動到的那個點的x和y軸座標。好比移動到 (10,10)這個點的命令,應該寫成「M 10 10」。這一段字符結束後,解析器就會去讀下一段命令。每個命令都有兩種表示方式,一種是用大寫字母,表示採用絕對定位。另外一種是用小寫字母,表示採用相對定位(例如:從上一個點開始,向上移動10px,向左移動7px)。學習

d屬性採用的是用戶座標系統,不需標明單位。在後面的教程中,咱們會學到如何讓變換path,以知足更多需求。動畫

直線命令 Line commands

<path>元素有5個畫直線的命令,如名字所示,直線命令就是在兩個點之間畫直線。首先是「Move to」命令,M,前面已經提到過,它有兩個參數,分別是須要移動到的點的x軸和y軸的座標。假設,你的畫筆當前位於一個點,在使用M命令移動畫筆後,只會 移動畫筆,但不會在兩點之間畫線。由於M命令僅僅是移動畫筆,但不畫線。因此M命令常常出如今路徑的開始處,用來指明從何處開始畫。spa

M x y

or翻譯

m dx dy

這有一個比較好的例子,不過咱們沒畫任何東西,只是將畫筆移動到路徑的起點,因此咱們不會看到任何圖案。可是,我把咱們移動到的點標註出來了,因此 在下面的例子裏會看到(10,10)座標上有一個點。注意,若是隻畫path,這裏什麼都不會顯示。(這段不太好理解,說明一下:爲了更好地展現路徑,下 面的全部例子裏,在用path繪製路徑的同時,也會用circle標註路徑上的點。)code

<?xml version="1.0" standalone="no"?> <svg width="200px" height="200px" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M10 10"/> <!-- Points --> <circle cx="10" cy="10" r="2" fill="red"/> </svg>

可以真正畫出線的命令有3個(M命令是移動畫筆位置,可是不畫線),最經常使用的是「Line to」命令,LL有兩個參數,分別是一個點的x軸和y軸座標,L命令將會在該點和當前點(L前面畫筆所在的點)之間畫一條線段。xml

L x y (or l dx dy)

另外還有兩個簡寫命令,用來繪製平行線和垂直線。H,繪製平行線。V,繪製垂直線。它們都只帶一個參數,標明在x軸或y軸移動到的位置,由於它們都只在一個座標軸的方向上移動。

H x (or h dx)
 V y (or v dy)

如今咱們已經掌握了一些命令,能夠開始畫一些東西了。先從簡單的地方開始,畫一個簡單的矩形(一樣的效果用<rect/>元素能夠更簡單的實現),矩形是由水平線和垂直線組成的,因此這個例子能夠很好地展示前面講的畫線的方法。

<?xml version="1.0" standalone="no"?> <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,Z命令會從當前點畫一條直線到路徑的起點,儘管咱們不老是須要閉合路徑,可是它仍是常常被放到路徑的最後。另外,Z命令不用區分大小寫。

Z (or z)

因此上面例子裏用到的路徑,能夠簡化成這樣:

<path d="M10 10 H 90 V 90 H 10 Z" fill="transparent" stroke="black"/>

你也可使用這些命令的相對座標形式來繪製相同的圖形,如以前所述,相對命令使用的是小寫字母,它們的參數不是指定一個明確的座標,而是表示相對於它前面的點須要移動多少距離。例如前面的示例,畫的是一個80*80的正方形,用相對命令能夠這樣描述:

<path d="M10 10 h 80 v 80 h -80 Z" fill="transparent" stroke="black"/>

上述路徑是:畫筆移動到(10,10)點,由此開始,向右移動80像素構成一條水平線,而後向下移動80像素,而後向左移動80像素,而後再回到起點。

你可能會問這些命令有什麼用,由於 <polygon><polyline> 能夠作到畫出同樣的圖形。答案是,這些命令能夠作得更多。若是你只是畫直線,那麼其餘元素可能會更好用,可是,path倒是衆多開發者在SVG繪製中慣用 的。據我所知,它們之間不存在性能上的優劣。可是經過腳本生成path可能有所不一樣,由於另外兩種方法只須要指明點,而path在這方面的語法會更復雜一 些。

曲線命令 Curve commands

繪製平滑曲線的命令有3個,其中兩個用來繪製貝塞爾曲線,另一個用來繪製弧形或者說是圓的一部分。若是你用過Inkscape, Illustrator 或者 Photoshop,你可能對貝塞爾曲線有必定程度的瞭解。關於貝塞爾曲線的數學解釋,你能夠在Wikipedia的文檔中獲取到。其中的不少知識均可以用在這裏。貝塞爾曲線的類型有不少,可是在path元素裏,只存在兩種:三次貝塞爾曲線C,和二次貝塞爾曲線Q。

貝塞爾曲線

咱們從稍微複雜一點的三次貝塞爾曲線入手,三次貝塞爾曲線須要定義一個點和兩個控制點,因此用C命令建立三次貝塞爾曲線,須要設置三組座標參數:

C x1 y1, x2 y2, x y (or c dx1 dy1, dx2 dy2, dx dy)

這裏的最後一個座標(x,y)表示的是曲線的終點,另外兩個座標是控制點,(x1,y1)是起點的控制點,(x2,y2)是終點的控制點。若是你熟 悉代數或者微積分的話,會更容易理解控制點,控制點描述的是曲線起始點的斜率,曲線上各個點的斜率,是從起點斜率到終點斜率的漸變過程。(文字描述很差, 維基百科上有圖示,更直觀。)

<?xml version="1.0" standalone="no"?> <svg width="190px" height="160px" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M10 10 C 20 20, 40 20, 50 10" stroke="black" fill="transparent"/> <path d="M70 10 C 70 20, 120 20, 120 10" stroke="black" fill="transparent"/> <path d="M130 10 C 120 20, 180 20, 170 10" stroke="black" fill="transparent"/> <path d="M10 60 C 20 80, 40 80, 50 60" stroke="black" fill="transparent"/> <path d="M70 60 C 70 80, 110 80, 110 60" stroke="black" fill="transparent"/> <path d="M130 60 C 120 80, 180 80, 170 60" stroke="black" fill="transparent"/> <path d="M10 110 C 20 140, 40 140, 50 110" stroke="black" fill="transparent"/> <path d="M70 110 C 70 140, 110 140, 110 110" stroke="black" fill="transparent"/> <path d="M130 110 C 120 140, 180 140, 170 110" stroke="black" fill="transparent"/> </svg>

上面的例子裏,建立了9個三次貝塞爾曲線。有一點比較遺憾,標記控制點的代碼會比較龐大,因此在這裏捨棄了。(以前全部點都用circle標記,此 處同樣,只不過沒把代碼列出來)。若是你想更準確地控制它們,能夠本身動手把他們畫出來。圖例上的曲線從左開始,控制點在水平方向上逐漸分開,最右側的曲 線,控制點之間離得更遠。這裏要注意觀察,曲線沿着起點到第一控制點的方向伸出,逐漸彎曲,而後沿着第二控制點到終點的方向結束。(這個翻譯的不太好,沒 弄清原文想要表達的意思。曲線的原理,仍是看維基百科比較好。)

你能夠將若干個貝塞爾曲線連起來,從而建立出一條很長的平滑曲線。若是將一個點的控制點在它的另外一側創建一個對稱點(斜率不變),能夠經過一個簡寫 的命令來實現,這個命令是S(或s)。(這段話能夠這樣理解:S命令前面能夠是一條C命令建立的三次貝賽爾曲線,這時候,S命令跟在C命令的後面,就能夠 用比較簡單的參數,生成一個與前面那個相對稱的三次貝塞爾曲線。仔細看一下後面的圖例,能夠幫助理解。另外,S命令也能夠跟在S命令後面。)

S x2 y2, x y (or s dx2 dy2, dx dy)

S命令能夠用來建立與以前那些曲線同樣的貝塞爾曲線,可是,若是S命令跟在一個C命令或者另外一個S命令的後面,它的第一個控制點,就會被假設成前一 個控制點的對稱點。若是S命令單獨使用,前面沒有C命令或者另外一個S命令,那麼它的兩個控制點就會被假設爲同一個點。下面是S命令的語法示例,如圖所示, 左側的控制點用紅色標示,與它對稱的控制點用藍色標示。

<?xml version="1.0" standalone="no"?> <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"/> </svg>

另外一個貝塞爾曲線是二次貝塞爾曲線Q,它比三次貝塞爾曲線簡單,只須要一個控制點,用來肯定起點和終點的曲線斜率。所以它須要兩組參數,控制點和終點座標。

Q x1 y1, x y (or q dx1 dy1, dx dy)

<?xml version="1.0" standalone="no"?> <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"/> </svg>

就像三次貝塞爾曲線有一個S命令,二次貝塞爾曲線有一個差很少的T命令,能夠經過更簡短的參數,延長二次貝塞爾曲線。

T x y (or t dx dy)

和以前同樣,快捷命令T會經過前一個控制點,推斷出一個新的控制點。這意味着,在你的第一個控制點後面,能夠只定義終點,就建立出一個至關複雜的曲 線。須要注意的是,T命令前面必須是一個Q命令,或者是另外一個T命令,才能達到這種效果。若是T單獨使用,那麼控制點就會被認爲和終點是同一個點,因此畫 出來的將是一條直線。

<?xml version="1.0" standalone="no"?> <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"/> </svg>

雖然三次貝塞爾曲線擁有更大的自由度,可是兩種曲線能達到的效果老是差很少的。具體使用哪一種曲線,一般取決於需求,以及對曲線對稱性的依賴程度。

弧形Arcs

弧形命令A是另外一個建立SVG曲線的命令。基本上,弧形能夠視爲圓形或橢圓形的一部分。假設,已知橢圓形的長軸半徑和短軸半徑,另外已知兩個點(它 們的距離在圓的半徑範圍內),這時咱們會發現,有兩個路徑能夠鏈接這兩個點。每種狀況均可以生成出四種弧形。因此,爲了保證建立的弧形惟一,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軸半徑,它們的做用很明顯,不用多作解釋,若是你不是很清楚它們的做用,能夠參考一下橢圓ellipse命令中的相同參數。弧形命令A的第三個參數表示弧形的旋轉狀況,下面的例子能夠很好地解釋它:

<?xml version="1.0" standalone="no"?> <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,因此這是一個旋轉的橢圓,並以短軸爲分割線,造成了兩個對稱的弧形。參看圖示中的第二個橢圓形。

上面提到的四種不一樣路徑將由接下來的兩個參數決定。如前所講,還有兩種可能的橢圓用來造成路徑,它們給出的四種可能的路徑中,有兩種不一樣的路徑。這 裏要講的參數是large-arc-flag(角度大小) 和sweep-flag(弧線方向),large-arc-flag決定弧線是大於仍是小於180度,0表示小角度弧,1表示大角度弧。sweep- flag表示弧線的方向,0表示從起點到終點沿逆時針畫弧,1表示從起點到終點沿順時針畫弧。下面的例子展現了這四種狀況。

<?xml version="1.0" standalone="no"?> <svg width="325px" height="325px" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M80 80 A 45 45, 0, 0, 0, 125 125 L 125 80 Z" fill="green"/> <path d="M230 80 A 45 45, 0, 1, 0, 275 125 L 275 80 Z" fill="red"/> <path d="M80 230 A 45 45, 0, 0, 1, 125 275 L 125 230 Z" fill="purple"/> <path d="M230 230 A 45 45, 0, 1, 1, 275 275 L 275 230 Z" fill="blue"/> </svg>

你應該已經猜到了,最後兩個參數是指定弧形的終點,弧形能夠簡單地建立圓形或橢圓形圖標,好比你能夠建立若干片弧形,組成一個餅圖

若是你是從Canvas過 渡到SVG,那麼弧形會比較難以掌握,但它也是很是強大的。用路徑來繪製完整的圓或者橢圓是比較困難的,由於圓上的任意點均可以是起點同時也是終點,無數 種方案能夠選擇,真正的路徑沒法定義。經過繪製連續的路徑段落,也能夠達到近似的效果,但使用真正的circle或者ellipse元素會更容易一些。

相關文章
相關標籤/搜索