Android 開發 VectorDrawable 矢量圖 (二)了解矢量圖屬性與繪制


了解屬性:

<vector>:

根標簽,表示一個矢量動畫

支持的屬性:

  1. android:name:定義矢量圖形的名稱
  2. android:width:定義Drawable的寬度,支持所有dimension單位,一般使用dp。drawable的寬度不一定是最終繪制寬度,比如給ImageView設置backgroud則Drawable繪制寬度等於ImageView的寬度,給ImageView設置src則在ImageView大於Drawable寬度時,Drawable繪制寬度等於自己定義的寬度。
  3. android:height:定義Drawable的寬度,支持所有dimension單位,一般是dp。其它同上。
  4. android:viewportWidth:定義矢量圖形的視圖(viewport)空間的寬度,viewport是一個虛擬的canvas,后面所有的path都在該坐標系上繪制。坐標系左上方為(0,0),橫軸從左向右,縱軸從上到下。橫軸可視區域就是0~viewportWidth。
  5. android:viewportHeight:定義矢量圖形的可視區域的高度。其它見上。[0,0]~[viewportWidth,viewportHeight]定義了虛擬canvas的可視區域。
  6. android:tint:作為染色(tint)的色彩應用到drawable上。默認不應用tint。
  7. android:tintMode:tint顏色的Porter-Duff混合模式,默認是src_in。
  8. android:autoMirrored:如果drawable布局方向是RTL(right-to-left)時,drawable繪制是否需要鏡像化(鏡像化就是繞自身x軸中線旋轉180度)。
  9. android:alpha:drawble的透明度,取值0~1

<group>:

定義一組路徑和子group,另外還定義了轉換信息(transformation information)。轉換信息定義在vector指定的視圖區域內(與viewport坐標系相同)。定義的應用轉換的順序是縮放-->旋轉-->平移,所以同時定義的這些屬性最先應用scaleX/scaleY屬性,最后應用translateX/translateY屬性。

支持的屬性:

  1. android:name:定義group的名稱
  2. android:rotation:group對應矢量圖形的旋轉角度,取值是360度制。
  3. android:pivotX:Group旋轉和縮放時的中心點的X軸坐標。取值基於viewport視圖的坐標系,不能使用百分比。
  4. android:pivotY:Group旋轉和縮放時的中心點的Y軸坐標。取值基於viewport視圖的坐標系,不能使用百分比。
  5. android:scaleX:Group在X軸上的縮放比例,最先應用到圖形上。
  6. android:scaleY:Group在Y軸上的縮放比例,最先應用到圖形上。
  7. android:translateX:Group在X軸的平移距離,取值基於viewport視圖的坐標系。最后應用到圖形上。
  8. android:translateY:Group在Y軸的平移距離,取值基於viewport視圖的坐標系。最后應用到圖形上。

<path>:

定義一個路徑,一個路徑即可以表示一塊填充區域也可以表示一根線條。

支持的屬性:

  1. android:name:定義路徑的名稱
  2. android:pathData:定義路徑的數據,路徑由多條命令組成,格式與SVG標准的path data的d屬性完全相同,路徑命令的參數定義在viewport視圖的坐標系。
  3. android:fillColor:指定填充路徑的顏色,一般是一個顏色值,在SDK24及以上,可以指定一個顏色狀態列表或者一個漸變的顏色。如果在此屬性上做漸變動畫,新的屬性值會覆蓋此值。如果不指定,則path不被填充。
  4. android:strokeColor:指定路徑線條的顏色,一般是一個顏色值,在SDK24及以上,可以指定一個顏色狀態列表或者一個漸變的顏色。如果在此屬性上做漸變動畫,新的屬性值會覆蓋此值。如果不指定,則path的線條不會繪制出來。
  5. android:strokeWidth:指定路徑線條的寬度,基於viewport視圖的坐標系(不要dp/px之類的結尾)。
  6. android:strokeAlpha:指定路徑線條的透明度。
  7. android:fillAlpha:指定填充區域的透明度。
  8. android:trimPathStart:取值從0到1,表示路徑從哪里開始繪制。0~trimPathStart區間的路徑不會被繪制出來。
  9. android:trimPathEnd:取值從0到1,表示路徑繪制到哪里。trimPathEnd~1區間的路徑不會被繪制出來。
  10. android:trimPathOffset:平移可繪制區域,取值從0到1,線條從(trimPathOffset+trimPathStart繪制到trimPathOffset+trimPathEnd),注意:trimPathOffset+trimPathEnd如果超過1,其實也是繪制的的,繪制的是0~trimPathOffset+trimPathEnd-1的位置。
  11. android:strokeLineCap:設置線條首尾的外觀,三個值:butt(默認,向線條的每個末端添加平直的邊緣), round(向線條的每個末端添加圓形線帽), square(向線條的每個末端添加正方形線帽。)。
  12. android:strokeLineJoin:設置當兩條線條交匯時,創建什么樣的邊角(線段連接類型):三個值:miter(默認,創建尖角),round(創建圓角),bevel(創建斜角) 。
  13. android:strokeMiterLimit:設置設置最大斜接長度,斜接長度指的是在兩條線交匯處內角和外角之間的距離。只有當 lineJoin 屬性為 "miter" 時,miterLimit 才有效。

 

了解語法:

  • M = moveto(M X,Y) :將畫筆移動到指定的坐標位置,相當於 android Path 里的moveTo()
  • L = lineto(L X,Y) :畫直線到指定的坐標位置,相當於 android Path 里的lineTo()
  • H = horizontal lineto(H X):畫水平線到指定的X坐標位置
  • V = vertical lineto(V Y):畫垂直線到指定的Y坐標位置
  • C = curveto(C X1,Y1,X2,Y2,ENDX,ENDY):三次貝賽曲線
  • S = smooth curveto(S X2,Y2,ENDX,ENDY) 同樣三次貝塞爾曲線,更平滑
  • Q = quadratic Belzier curve(Q X,Y,ENDX,ENDY):二次貝賽曲線
  • T = smooth quadratic Belzier curveto(T ENDX,ENDY):映射 同樣二次貝塞爾曲線,更平滑
  • A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧線 ,相當於arcTo()
  • Z = closepath():關閉路徑(會自動繪制鏈接起點和終點)

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

 

直線命令

例子1 畫一個方向圖標:

注意!下面的代碼是Android的VectorDrawable格式

<?xml version="1.0" encoding="utf-8"?>
<!--android:width="50dp"  android:height="50dp" 畫布的寬度與高度-->
<!--android:viewportWidth="50.0" android:viewportHeight="50.0" 視圖的寬度和高度-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="50dp"
    android:height="50dp"
    android:viewportWidth="50.0"
    android:viewportHeight="50.0">

    <!--strokeColor=  筆畫顏色 線條的顏色-->
    <!--fillColor=  填充顏色  注意2個顏色 有明顯區分,填充顏色只是在圖形閉合后顏色-->
    <!--strokeWidth=  線寬-->
    <path
        android:strokeColor="@color/colorPrimaryDark"
        android:strokeWidth="5"
        android:pathData="M10,10
        L26.7,26.9
        M25,25
        L10,40"/>
    <!--這里使用的都是大寫字母,所以坐標值都是絕對坐標-->
    <!--M10,10 = 首先將畫筆移動到X10,Y10的地方-->
    <!--L26.7,26.9 = 然后畫一條直線到X26.7,Y26.9 -->
    <!--M25,25 = 在將畫筆移動到 X25.7,Y25 -->
    <!--L10,40 = 畫一條直線到 X10.7,Y40 -->
    
</vector>
 

效果圖:

例子2  畫一個矩形:

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="100dp"
    android:height="100dp"
    android:viewportHeight="100.0"
    android:viewportWidth="100.0">

    <path
        android:name="stars"
        android:strokeColor="@color/colorPrimaryDark"
        android:strokeWidth="2"
        android:pathData="M10,10 L90,10 L90,90 L10,90 Z"/>
    
</vector>
  • 我們的畫布是100*100的,首先在X10,Y10的坐標上向右畫直線,然后在下線畫直線,在向左畫直線,最后使用Z閉合圖形。注意!需要閉合圖形需要在一個圖形里一直保持線段的連貫,如果在中間使用M移動畫筆,那么Z閉合只與最后一次M移動的點閉合圖形。這點與自定義View里的path畫法類似。
  • 另外,如果你需要一個填充全部顏色的矩形,只需要修改android:strokeColor="@color/colorPrimaryDark"  為android:fillColor="@color/colorPrimaryDark" 這樣,圖形中間就會被全部填充。但是建議初學者在畫的時候設置strokeColor和strokeWidth 在來繪制圖形,否則圖形如果不設置線條顏色和線寬,圖形在閉合之前是不會顯示圖形的。當然,熟悉svg的大佬可以略過。。

效果圖:

 

曲線命令

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

三次貝塞爾曲線C

三次貝塞爾曲線C,三次貝塞爾曲線需要定義一個點和兩個控制點,所以用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" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="400dp"
    android:height="400dp"
    android:viewportHeight="400"
    android:viewportWidth="400">

    <path
        android:name="rect_vector"
        android:fillColor="#04f91d"
        android:pathData="M 100 100 C 200 0 300 0 400 100 "
        android:strokeColor="#f76f07"
        android:strokeWidth="5" />
        
</vector>

M 定義起點為(100,100)
C 定義終點為(400,100)
其中兩個控制點 (200,0)(300,0)

連接貝塞爾曲線 S

以將若干個貝塞爾曲線連起來,從而創建出一條很長的平滑曲線。通常情況下,一個點某一側的控制點是它另一側的控制點的對稱(以保持斜率不變)。這樣,可以使用一個簡寫的貝塞爾曲線命令S

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="800dp"
    android:height="800dp"
    android:viewportHeight="800"
    android:viewportWidth="800">
    
    <path
            android:name="rect_vector"
        android:fillColor="#04f91d"
        android:pathData="M 100 100 C 200 0 300 0 400 100 S 600 200 700 100"
        android:strokeColor="#f76f07"
        android:strokeWidth="5" />

</vector>

二次貝塞爾曲線Q

它比三次貝塞爾曲線簡單,只需要一個控制點,用來確定起點和終點的曲線斜率。因此它需要兩組參數,控制點和終點坐標

Q x1 y1, x y (or q dx1 dy1, dx dy)
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="400dp"
    android:height="400dp"
    android:viewportHeight="800"
    android:viewportWidth="800">

    <path
        android:name="rect_vector"
        android:fillColor="#04f91d"
        android:pathData="M 100 100 Q 200 0 400 100"
        android:strokeColor="#f76f07"
        android:strokeWidth="5" />

</vector>

 

連接貝塞爾曲線 T

就像三次貝塞爾曲線有一個S命令,二次貝塞爾曲線有一個差不多的T命令,可以通過更簡短的參數,延長二次貝塞爾曲線。

T x y (or t dx dy)
    <?xml version="1.0" encoding="utf-8"?>
    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="800dp"
        android:height="800dp"
        android:viewportHeight="800"
        android:viewportWidth="800">

        <path
            android:name="rect_vector"
            android:fillColor="#04f91d"
            android:pathData="M 100 100 Q 200 0 300 100 T 500 100"
            android:strokeColor="#f76f07"
            android:strokeWidth="5" />

    </vector>

弧形

弧形命令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軸半徑
參數 x-axis-rotation (第三個)表示弧形的旋轉情況
參數 large-arc-flag (第四個)決定弧線是大於還是小於180度,0表示小角度弧,1表示大角度弧。
參數 sweep-flag(第五個)表示弧線的方向,0表示從起點到終點沿逆時針畫弧,1表示從起點到終點沿順時針畫弧。
最后的參數x y 是弧線的終點

實例

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="800dp"
    android:height="800dp"
    android:viewportHeight="800"
    android:viewportWidth="800">
    
    <path
        android:name="rect_vector"
        android:fillColor="#04f91d"
        android:pathData="
        M 100 400
        A 100 120 0 0 1 400 400 Z"
        android:strokeColor="#f76f07"
        android:strokeWidth="5" />

</vector>

這里 起點坐標是 (100,400) 弧線的半徑 rx =100 ry=120 旋轉角度為 0度,第四個參數 0 代表取的是小角方向的弧度,這里正好兩而相等
終點坐標是 (400,400) 最后 Z 閉合曲線 

 貝塞爾在線模擬工具:http://wx.karlew.com/canvas/bezier/

github:https://github.com/karlew/bezier-tool-for-canvas


免責聲明!

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



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