svg折線演算法 SVG之Paths

2021-10-17 06:51:45 字數 3248 閱讀 2615

看d3.js的時候就見識過元素有多牛x,啥都能畫出來,可不知其原理的話,看上去簡直形同天書!沒關係,有的是時間精力和耐性,仔細看看這天書的正確開啟方式。

把看做是一支筆,可以按照我的意願在哪兒落「筆」,畫各種各樣在其功能範圍內的線條,還能自動幫我做很多事情來美化這些線條。所有這些控制這支「筆」的資訊被包含在元素的"d"

落筆(m)

以moveto首字母m開頭,加上座標,以逗號或空格分割,表示移動到指定座標位置。

直線(l)

以lineto首字母l開頭,加上座標,以逗號或空格分割,表示從當前位置畫一條直線到指定座標位置。

可連續畫多條直線

這就近似畫了個矩形,為什麼說近似,我們加上線的寬度看一下

左上角的殘缺說明,即使直線的開始和末尾的座標重合,svg也不會對重合處做自動銜接處理,咋辦?

封閉(z)

用z代表closepath,表示讓svg自動將前乙個m指定的起始位置與z之前最後乙個座標位置用直線連線。

現在就真的是個矩形了。

可以利用多個m在同乙個path中畫出多餘乙個不相連的圖形。

相對位置

簡單來說,用小寫字母(m, l)時,後面的座標x,y可以理解為以當前位置為原點,向x和y軸方向移動相應距離、或畫一條相應長度的線。上面兩個正方形的例子可以用相對位置來畫。

表示封閉的識別符號z不區分大小寫。另外,後面的識別符號大小寫都是表示絕對位置和相對位置。

縮寫基於節約是美德,頻寬盡量省得原則,path屬性也是能縮寫就縮寫。

垂線vertical lineto首字母v(v),表示畫一條垂線到指定y軸座標(或相對位置)

與 等同

水平線horizontal lineto首字母h(h),表示畫一條水平線到指定x軸座標(或相對位置)

與 等同

其他縮寫

字母和數字之間可以不用隔開。

如果path只用到直線,l(l)全都可以去掉。

負數與數字(或字母)之間可以不用隔開。

曲線最bt的圖形駕到~到這裡才會知道幾何知識還是挺重要的,各種切線,後面再說。

橢圓上的曲線

這算是一種最常規的曲線吧,就是以指定的x和y作為半徑做乙個橢圓,落在兩個已知的點的中間的一段曲線。一般有四種可能。

盜張書中的圖看下:

兩個已知的點分別為arc start和arc end,以指定x和y作為半徑可做出兩個經過這兩點的橢圓,落在這兩點中間的曲線就是黑色實線的四種情況,按順逆時針方向分有兩種,按兩點和圓心之間形成的夾角是否超過180度分有兩種,組合就是四種。當然還能旋轉,如圖f

arc首字母a(a),表示畫一條曲線,其後的前兩個引數分別表示橢圓的x軸半徑和y軸半徑;第三個引數表示x-axis-rotation,即以x軸為基準旋轉多少角度;第四個引數表示large-arc-flag,0表示夾角小於180度,1表示大於180度;第五個引數表示sweep-flag,0表示逆時針(counterclockwise),1表示順時針(clockwise);最後兩個引數表示第二個點座標(arc end)。

兩點需要注意的地方:

arc start和arc end兩個點如果重合,svg將畫不出任何曲線。因為經過乙個點的曲線有無數條。

如果arc start和arc end兩個點之間距離太遠導致已給定半徑的任意橢圓都無法將兩個點相連時,svg檢視將會等比放大橢圓半徑,直到有橢圓正好能夠將兩點相連。可以試試,第二個點的x座標變大,曲線也會跟著變長。

貝塞爾曲線

path裡最牛x以及最容易讓人懵逼和卻步的曲線,分為二次貝塞爾曲線(quadratic bézier curve)和三次貝塞爾曲線(cubic bézier curve)。聽名字就嚇退了有木有啊!

好在svg已經做掉了核心演算法的事情,暴露給使用者的僅僅就是幾個座標。也就是說,使用者只需要知道這幾個座標是幹什麼的,怎麼用就行了,所以可以稍微不用太恐懼的看下去。具體這幾個座標是通過什麼公式來精確控制曲線變化的,實在不知道也沒問題。書裡也根本沒做詳細解釋,這是數學範疇(不懂的就恨當前數學沒認真學吧)。

二次貝塞爾曲線

通過三個點控制曲線變化,開始和結束點,加上乙個外部控制點(control point)。

曲線彎曲的情況如圖

想象一下,假設有兩個點,分別從a和c點出發,沿著ac和cb兩條線向c點和b點移動,並且以相同的時間t到達c點和b點,也就是說從a出發的點移動速度為ac/t,從c出發的點移動速度為cb/t。而兩點之間的連線始終與曲線相切,這一條曲線便是三個點形成的二次貝塞爾曲線。

用quadratic bézier curve首字母q(q),表示二次貝塞爾曲線。前兩個引數為控制點(control point)的座標,後兩個引數為曲線終點座標。

就用上圖的**為例

//ac、cb之間連線

//切線

//二次貝塞爾曲線

//點a

//點b

//點cab

c另外,可以連續使用q來畫連續的二次貝塞爾曲線

這樣的曲線連線處會很生硬

在第乙個q結束以後直接用t(t)加上終點座標,可以讓svg畫出一條平滑優美的曲線。

實際上,svg會自動給後半段二次貝塞爾曲線加上乙個控制點,使得這條連續曲線變得平滑。這個控制點座標計算公式為:

x2 = x + (x - x1) = 2 * x - x1

y2 = y + (y - y1) = 2 * y - y1

(x2,y2)為自動生成的控制點座標,(x,y)為前一段貝塞爾曲線的終點座標,(x1,y1)為前一段曲線的控制點座標。所以通過計算可以得出和前面用t生成的曲線是一致的。不過顯然用t方便得多。

三次貝塞爾曲線

通過四個點控制曲線變化,開始和結束點,加上兩個外部控制點。

用cubic bézier curve首字母c(c),表示三次貝塞爾曲線。前四個引數分別為兩個控制點的座標,後兩個引數為曲線終點座標。

感覺曲線的原理要說清楚有點力不從心了,直接上圖吧。感覺其實和二次貝塞爾很相似,就是多了個控制點。

三次貝塞爾可以生成許多有趣的曲線

多個三次貝塞爾曲線的平滑鏈結,和二次一樣,也有個特定字母s(s),後面接兩組座標,第一組表示第二個控制點座標,第二組表示終點座標,而由svg自動計算其第一組控制點的座標。控制點計算公式與二次貝塞爾一樣,只是(x1,y1)表示前一段曲線的第二個控制點座標。

svg中的path指令分析

使用path標籤時,就像用指令的方式來控制乙隻畫筆,比如 移動畫筆到某一座標位置,畫一條線,畫一條曲線,完事了抬起畫筆,over!path支援的指令有 m moveto m x,y 將畫筆移動到指定的座標位置 l lineto l x,y 畫直線到指定的座標位置 h horizontal linet...

svg中path標籤的用法

除了上次的六個普通標籤之外,svg還支援複雜的路徑標籤 path 使用path標籤時,就像用指令的方式來控制乙隻畫筆,比如 移動畫筆到某一座標位置,畫一條線,畫一條曲線,完事了抬起畫筆,over!path支援的指令有 m moveto m x,y 將畫筆移動到指定的座標位置 l lineto l x...

SVG格式化 PATH 說明

用於定義乙個向量形狀。字串中包含的關鍵命令不外乎 下面的命令中,大寫說明後面的數值是絕對位置 position 小寫表示後面的數值是相對於當前的位置 shift offset moveto 想象 哆啦a夢 開啟 任意門 瞬移到某個位置,因此軌跡是不連續的 格式 m x y 或者 m dx dy li...