android vector pathData探究,幾分鍾繪制自己的vectordrawable


之前經常看到一些酷酷的圖標效果, 深入進去發現不是直接用的圖片, 而是一些以Vector標簽開頭的xml文件, 於是就看到了如下代碼:

 

  1. <vector xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:width= "24dp"
  3. android:height= "24dp"
  4. android:viewportHeight= "40"
  5. android:viewportWidth= "40">
  6. <path
  7. android:fillColor= "#f24e4e"
  8. android:pathData= "
  9. M8,4
  10. h24,0
  11. q4,0 4,4
  12. v24
  13. q0,4 -4,4
  14. h-24,0
  15. q-4,0 -4,-4
  16. v-24
  17. q0,-4 4,-4
  18. M20,15
  19. a5,6 -15 0,0 -9 2
  20. C11,22 15,23 20,29
  21. C25,23 29,22 29,17
  22. a5,6 15 0,0 -9,-2" />
  23. </vector>


心里十萬只草泥馬在奔騰, 這都是啥 啥 and啥......最近項目迭代完成間隙, 用了些時間研究了下這塊, 發現也不是那么難, 只是懂了語法的話, 就容易看懂了.廢話不多說, 先看下要實現的效果, 從效果開始深入:


效果還是挺贊的, 圓角矩形中部有個鏤空的心形. 代碼就是上面的那些代碼.

首先看下屬性(這里只挑一些個人認為比較重要的) :

  1. android:viewportHeight="40" //將width等分為40份
  2. android:viewportWidth= "40" //將height等分為40份
  1.  
  2. 以下是pathData中用到的:
  3. M:move to 移動繪制點,作用相當於把畫筆落在哪一點。
  4. L:line to 直線,就是一條直線,注意,只是直線,直線是沒有寬度的,所以你什么也看不到。
  5. Z:close 閉合,嗯,就是把圖封閉起來。
  6. C:cubic bezier 三階貝塞爾曲線
  7. Q:quatratic bezier 二階貝塞爾曲線
  8. 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份, 則對應關鍵點的坐標如下圖所示:



對應代碼:

 

  1. <vector xmlns:android= "http://schemas.android.com/apk/res/android"
  2. android:width= "24dp"
  3. android:height= "24dp"
  4. android:viewportHeight= "40"
  5. android:viewportWidth= "40">
  6. <path
  7. android:fillColor= "#f24e4e"
  8. android:pathData= "
  9. M8,4
  10. h24,0
  11. q4,0 4,4
  12. v24
  13. q0,4 -4,4
  14. h-24,0
  15. q-4,0 -4,-4
  16. v-24
  17. q0,-4 4,-4" />
  18. </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段弧線組成這個心形, 上邊的兩段圓弧和下邊的兩段曲線,各個弧線的起始點和控制點,終點都確定了,接下來就簡單了,上代碼:

 

  1. <vector xmlns:android= "http://schemas.android.com/apk/res/android"
  2. android:width= "24dp"
  3. android:height= "24dp"
  4. android:viewportHeight= "40"
  5. android:viewportWidth= "40">
  6. <path
  7. android:fillColor= "#f24e4e"
  8. android:pathData= "
  9. M20,15
  10. a5,6 -15 0,0 -9 2
  11. C11,22 15,23 20,29
  12. C25,23 29,22 29,17
  13. a5,6 15 0,0 -9,-2" />
  14. </vector>


接下來就可以考慮畫出文章開始給出的那個鏤空心形圖,由於中間是鏤空的,所以采取兩個pathData標簽疊加不可取,可以先順時針畫出矩形,然后逆時針畫出心形就可以了.

 

  1. <vector xmlns:android= "http://schemas.android.com/apk/res/android"
  2. android:width= "24dp"
  3. android:height= "24dp"
  4. android:viewportHeight= "40"
  5. android:viewportWidth= "40">
  6. <path
  7. android:fillColor= "#f24e4e"
  8. android:pathData= "
  9. M8,4
  10. h24,0
  11. q4,0 4,4
  12. v24
  13. q0,4 -4,4
  14. h-24,0
  15. q-4,0 -4,-4
  16. v-24
  17. q0,-4 4,-4
  18. M20,15
  19. a5,6 -15 0,0 -9 2
  20. C11,22 15,23 20,29
  21. C25,23 29,22 29,17
  22. a5,6 15 0,0 -9,-2" />
  23. </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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM