之前經常看到一些酷酷的圖標效果, 深入進去發現不是直接用的圖片, 而是一些以Vector標簽開頭的xml文件, 於是就看到了如下代碼:
-
<vector xmlns:android="http://schemas.android.com/apk/res/android"
-
android:width= "24dp"
-
android:height= "24dp"
-
android:viewportHeight= "40"
-
android:viewportWidth= "40">
-
<path
-
android:fillColor= "#f24e4e"
-
android:pathData= "
-
M8,4
-
h24,0
-
q4,0 4,4
-
v24
-
q0,4 -4,4
-
h-24,0
-
q-4,0 -4,-4
-
v-24
-
q0,-4 4,-4
-
M20,15
-
a5,6 -15 0,0 -9 2
-
C11,22 15,23 20,29
-
C25,23 29,22 29,17
-
a5,6 15 0,0 -9,-2" />
-
</vector>
心里十萬只草泥馬在奔騰, 這都是啥 啥 and啥......最近項目迭代完成間隙, 用了些時間研究了下這塊, 發現也不是那么難, 只是懂了語法的話, 就容易看懂了.廢話不多說, 先看下要實現的效果, 從效果開始深入:
效果還是挺贊的, 圓角矩形中部有個鏤空的心形. 代碼就是上面的那些代碼.
首先看下屬性(這里只挑一些個人認為比較重要的) :
-
android:viewportHeight="40" //將width等分為40份
-
android:viewportWidth= "40" //將height等分為40份
-
-
以下是pathData中用到的:
-
M:move to 移動繪制點,作用相當於把畫筆落在哪一點。
-
L:line to 直線,就是一條直線,注意,只是直線,直線是沒有寬度的,所以你什么也看不到。
-
Z:close 閉合,嗯,就是把圖封閉起來。
-
C:cubic bezier 三階貝塞爾曲線
-
Q:quatratic bezier 二階貝塞爾曲線
-
A:ellipse 圓弧
基本規則
pathData 的指令基本都是由字母跟若干數字組成,數字之間可以用空格或者逗號隔開 (其實逗號會被忽略掉,加上逗號只是一些習慣的問題)。一般來說指令字母分為大小寫兩種,大寫的字母是基於原點的坐標系(偏移量),即絕對位置;小寫字母是基於當前點坐標系(偏移量),即相對位置。
移動:
M(X,Y) 移動到指定點(X,Y), m(dx,dy)表示移動到相對當前點的相對dx,dy坐標位置
划線:
L(X,Y) 從當前點划線到(X,Y), l(dx,dy)表示划線到相對當前點dx距離,dy距離坐標位置
H(X)水平方向划線: y坐標保持不變,划線到x坐標位置, h(dx)表示划線到距離當前坐標dx距離位置(y坐標保持不變)
V(Y)豎直方向划線: x坐標保持不變,划線到y坐標位置, v(dy)表示划線到距離當前坐標dy距離位置(x坐標保持不變)
弧線:
A rx,ry x-axis-rotation large-arc-flag,sweepflag x,y
a rx,ry x-axis-rotation large-arc-flag,sweepflag dx,dy
rx ry表示畫弧的半徑, x-axis-rotation 表示沿x軸旋轉角度, large-arc-flag為0時表示取小弧線,為1時表示取大弧線
sweepflag為0時表示逆時針方向畫弧,為1時表示順時針方向畫弧. x,y表示終點目標的坐標,dx,dy表示起到到終點相對坐標距離.
好了, 看到這里我們就可以繪制以下圖形了:
分析: 此圖可由4段線段加上4個圓弧構成,將畫布分成40份, 則對應關鍵點的坐標如下圖所示:
對應代碼:
-
<vector xmlns:android= "http://schemas.android.com/apk/res/android"
-
android:width= "24dp"
-
android:height= "24dp"
-
android:viewportHeight= "40"
-
android:viewportWidth= "40">
-
<path
-
android:fillColor= "#f24e4e"
-
android:pathData= "
-
M8,4
-
h24,0
-
q4,0 4,4
-
v24
-
q0,4 -4,4
-
h-24,0
-
q-4,0 -4,-4
-
v-24
-
q0,-4 4,-4" />
-
</vector>
先移動到(8,4)點,然后畫水平直線,然后根據起始點 控制點 終點可以畫出右上角的圓弧,然后畫豎直線段,以此類推,這個圖形就輕而易舉的畫出來了,是不是挺簡單,好,繼續深入.為了畫出心形圖案,還需要學習貝塞爾曲線才能畫出.
二階貝塞爾曲線:
Q x1,y1 x,y ( q dx1,dy1 dx,dy)
對應的貝塞爾二階公式為
三階階貝塞爾曲線:
Q x1,y1 x2,y2 x,y ( q dx1,dy1 dx2,dy2 dx,dy)
對應的貝塞爾三階公式為
也就是說為了完成一個二階貝塞爾曲線,需要確定一個起始點,一個控制點和一個終點,依次傳入參數,所以這里的重點是控制點的確定,三階的也是這樣,需要起始點,兩個控制點和一個終點.
先畫個心形圖案練練手吧.
圖形解析:
根據圖片可以看出需要4段弧線組成這個心形, 上邊的兩段圓弧和下邊的兩段曲線,各個弧線的起始點和控制點,終點都確定了,接下來就簡單了,上代碼:
-
<vector xmlns:android= "http://schemas.android.com/apk/res/android"
-
android:width= "24dp"
-
android:height= "24dp"
-
android:viewportHeight= "40"
-
android:viewportWidth= "40">
-
<path
-
android:fillColor= "#f24e4e"
-
android:pathData= "
-
M20,15
-
a5,6 -15 0,0 -9 2
-
C11,22 15,23 20,29
-
C25,23 29,22 29,17
-
a5,6 15 0,0 -9,-2" />
-
</vector>
接下來就可以考慮畫出文章開始給出的那個鏤空心形圖,由於中間是鏤空的,所以采取兩個pathData標簽疊加不可取,可以先順時針畫出矩形,然后逆時針畫出心形就可以了.
-
<vector xmlns:android= "http://schemas.android.com/apk/res/android"
-
android:width= "24dp"
-
android:height= "24dp"
-
android:viewportHeight= "40"
-
android:viewportWidth= "40">
-
<path
-
android:fillColor= "#f24e4e"
-
android:pathData= "
-
M8,4
-
h24,0
-
q4,0 4,4
-
v24
-
q0,4 -4,4
-
h-24,0
-
q-4,0 -4,-4
-
v-24
-
q0,-4 4,-4
-
M20,15
-
a5,6 -15 0,0 -9 2
-
C11,22 15,23 20,29
-
C25,23 29,22 29,17
-
a5,6 15 0,0 -9,-2" />
-
</vector>
代碼就是這樣了,是不是挺簡單,最起碼又一個知識點get了
多個pathData標簽疊加需要使用<group></group>, 另外還有一些屬性,
path
android:name 定義該 path 的名字,這樣在其他地方可以通過名字來引用這個路徑
android:pathData 和 SVG 中 d 元素一樣的路徑信息。
android:fillColor 定義填充路徑的顏色,如果沒有定義則不填充路徑
android:strokeColor 定義如何繪制路徑邊框,如果沒有定義則不顯示邊框
android:strokeWidth 定義路徑邊框的粗細尺寸
android:strokeAlpha 定義路徑邊框的透明度
android:fillAlpha 定義填充路徑顏色的透明度
android:trimPathStart 從路徑起始位置截斷路徑的比率,取值范圍從 0 到1
android:trimPathEnd 從路徑結束位置截斷路徑的比率,取值范圍從 0 到1
android:trimPathOffset 設置路徑截取的范圍,取值范圍從 0 到1
android:strokeLineCap 設置路徑線帽的形狀,取值為 butt, round, square.
android:strokeLineJoin 設置路徑交界處的連接方式,取值為 miter,round,bevel.
android:strokeMiterLimit 設置斜角的上限
group :主要是用來設置路徑做動畫的關鍵屬性的
android:name 定義 group 的名字
android:rotation 定義該 group 的路徑旋轉多少度
android:pivotX 定義縮放和旋轉該 group 時候的 X 參考點。該值相對於 vector 的 viewport 值來指定的。
android:pivotY 定義縮放和旋轉該 group 時候的 Y 參考點。該值相對於 vector 的 viewport 值來指定的。
android:scaleX 定義 X 軸的縮放倍數
android:scaleY 定義 Y 軸的縮放倍數
android:translateX 定義移動 X 軸的位移。相對於 vector 的 viewport 值來指定的。
android:translateY 定義移動 Y 軸的位移。相對於 vector 的 viewport 值來指定的。
clip-path:定義當前繪制的剪切路徑。注意,clip-path 只對當前的 group 和子 group 有效
android:name 定義 clip path 的名字
android:pathData 和 android:pathData 的取值一樣。
vector:定義這個矢量圖
android:name 定義該drawable的名字
android:width 定義該 drawable 的內部(intrinsic)寬度,支持所有 Android 系統支持的尺寸,通常使用 dp
android:height 定義該 drawable 的內部(intrinsic)高度,支持所有 Android 系統支持的尺寸,通常使用 dp
android:viewportWidth 定義矢量圖視圖的寬度,視圖就是矢量圖 path 路徑數據所繪制的虛擬畫布
android:viewportHeight 定義矢量圖視圖的高度,視圖就是矢量圖 path 路徑數據所繪制的虛擬畫布
android:tint 定義該 drawable 的 tint 顏色。默認是沒有 tint 顏色的
android:tintMode 定義 tint 顏色的 Porter-Duff blending 模式,默認值為 src_in
android:autoMirrored 設置當系統為 RTL (right-to-left) 布局的時候,是否自動鏡像該圖片。比如 阿拉伯語。
android:alpha 該圖片的透明度屬性
感謝: http://www.jianshu.com/p/a3cb1e23c2c4#rd