Android VectorDrawable SVG 命令詳細分析

趙子龍發表於2017-11-12

Android 5.0系統中引入了 VectorDrawable 來支援向量圖(SVG),同時還引入了 AnimatedVectorDrawable 來支援向量圖動畫

1 直線命令

<path>元素裡有5個畫直線的命令,顧名思義,直線命令就是在兩個點之間畫直線。首先是“Move to”命令,M,前面已經提到過,它需要兩個引數,分別是需要移動到的點的x軸和y軸的座標。假設,你的畫筆當前位於一個點,在使用M命令移動畫筆後,只會移動畫筆,但不會在兩點之間畫線。因為M命令僅僅是移動畫筆,但不畫線。所以M命令經常出現在路徑的開始處,用來指明從何處開始畫

M x y 或 m dx dy複製程式碼

能夠真正畫出線的命令有三個(M命令是移動畫筆位置,但是不畫線),最常用的是“Line to”命令,L,L需要兩個引數,分別是一個點的x軸和y軸座標,L命令將會在當前位置和新位置(L前面畫筆所在的點)之間畫一條線段

L x y (or l dx dy)複製程式碼

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

H x (or h dx)
V y (or v 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="400"
    android:viewportWidth="400">

    <path
        android:name="rect_vector"
        android:fillColor="#04f91d"
        android:pathData="M 100 100 L 300 100 L 300 300 L 100 300 z"
        android:strokeColor="#f76f07"
        android:strokeWidth="5" />

</vector>複製程式碼
<?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 H 300  V 300 H 100 z"
        android:strokeColor="#f76f07"
        android:strokeWidth="5" />

</vector>複製程式碼

Z命令會從當前點畫一條直線到路徑的起點,儘管我們不總是需要閉合路徑,但是它還是經常被放到路徑的最後。另外,Z命令不用區分大小寫

2 曲線命令

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

2.1 貝塞爾曲線

2.1.1 三次貝塞爾曲線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)

2.1.2 連線貝塞爾曲線 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>複製程式碼

2.1.3 二次貝塞爾曲線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>複製程式碼

2.1.4 連線貝塞爾曲線 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>複製程式碼

2.2 弧形

弧形命令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 閉合曲線

相關文章