天天看點

svg初探,繪制愛心

svg初探,繪制愛心

1、svg圖檔

   svg和bitmap的差別  不詳細介紹了

   首先強烈推薦阿裡 iconfont 簡單粗暴

   找一張圖檔下載下傳 可以調整圖檔屬性  選擇svg下載下傳

svg初探,繪制愛心

   然後打開android studio module 右鍵drawable

svg初探,繪制愛心
svg初探,繪制愛心

   選中下載下傳的svg圖檔  這裡可以調整圖檔屬性  然後生成對應的.xml檔案

   最後的使用是一樣的  android:src="@drawable/ic_xxxxx" 等等

2、svg屬性
 打開導入svg生成的xml檔案  發現是這個樣子
 
 一臉懵逼,什麼鬼。
 淡定 屬性講解
 <vector xmlns:android="http://schemas.android.com/apk/res/android"  //命名空間
    android:height="200dp"  //這個是圖檔的intrinsic高度
    android:width="200dp"   //這個是圖檔的intrinsic寬度
    android:viewportHeight="100"    //這個是為這個圖檔設定的縱坐标,表示将圖檔分為100等份,主要下面的pathData需要依賴這個坐标的劃分
    android:viewportWidth="100"     //同上,隻不過這個是橫坐标,這兩個值可以随便定
    android:alpha="0.2"     //這個是整個圖像的透明度,取值範圍0到1
    >

    <group      //這個标簽中可以放入若幹個<path/>标簽,并給它們設定一些共同的屬性
        android:name="group_name"   //這個name很有用,在設定objectAnimator的時候用來區分給那個部分施加動畫
        android:pivotY="50"     //這個設定這個group的中心點的X坐标,取值範圍為0到100,在做rotation時有用
        android:pivotX="50"     //這個設定這個group的中心點的Y坐标,取值範圍為0到100,在做rotation時有用
        android:translateX="20" //将整個group在X軸方向平移多少像素
        android:translateY="30" //将整個group在Y軸方向平移多少像素
        android:rotation="90"   //将整個group以中心點左邊旋轉的角度,360為一圈
        android:scaleX="0.5"    //橫坐标的縮放比例 , 取值1表示100%
        android:scaleY="0.3">   //縱坐标的縮放比例,取值0.5表示50%,取值1.5表示150%

        <path   //這個标簽是重頭戲,矢量圖繪制的路徑
            android:name="path_name"    //為這個path标記的名字,在使用objectAnimator的時候用來區分給哪個部分施加動畫

            android:pathData="m 0,0 L50,0 L100,100 L0,100 z"    //這個具體文法,在網上随便搜搜就有了,就是SVG的文法,如果這個都不明白,那麼你肯定不明白什麼是矢量圖,找點資料再看看吧,這篇文章不适合你

            android:fillColor="@color/red"  //圖形内部的夜色
            android:fillAlpha="1"       //圖形的透明度取值範圍0到1
            android:strokeAlpha="0.5"   //線條的透明度,取值範圍0到1
            android:strokeColor="#ff0000ff" //線條的顔色
            android:strokeLineCap="butt|round|square"   //線的末端形狀,butt嚴格到指定的坐标就截至,round圓角的先端邊緣,square方形的邊緣不過有點向外延伸
            android:strokeLineJoin="round|bevel|miter"  //線的連接配接處形狀,round是圓角的,bevel和miter貌似看不出來有什麼差別....
            android:strokeWidth="20"    //線段的寬度

            android:trimPathStart="0.5"    //顧名思義,從path開始的地方(0%)去除path,去除到指定的百分比位置,取值範圍0到1
            android:trimPathEnd="0.5"      //顧名思義,從path結束的地方(100%的地方)去除path,去除到指定的百分比位置,取值範圍0到1
            android:trimPathOffset="0.5"   //這個屬性是和上面兩個屬性共同使用的,單獨使用沒有用,這個屬性的意思是,在去除path的時候設定path原點的位置,按百分比設定,取值範圍0到1
            />
    </group>

</vector>
           
3、svg動畫
動畫 特效 。。。 頭皮發麻有沒有
svg可以打造非常炫酷的動畫   這裡先來繪制簡單的線條動畫

圖檔看起來很卡頓  但是實際運作效果是非常流暢的!
繪制動畫前 先來了解點東西
           
Android對于 SVG 的支援是從 Android L 開始的,它的 SDK 裡面加入了 VectorDrawable , AnimatedVectorDrawable 等類幫助我們建構 SVG 圖形以及動畫,并且你可以在 xml 檔案裡面直接使用 <vector/> 标簽繪制 SVG 圖像以及 <animated-vector/> 标簽為 SVG 圖像配置設定動畫

使用path标簽建立SVG,就像用指令的方式來控制一隻畫筆,例如移動畫筆到某一坐标位置,畫一條線,畫一條曲線,結束。path标簽所支援的指令有以下幾種。
           
M = moveto(M X,Y):将畫筆移動到指定的坐标位置,但未發生繪制

L = lineto(L X,Y):畫直線到指定的坐标位置

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 curveto(Q X,Y,ENDX,ENDY):二次貝塞曲線

T = smooth quadratic Belzier curveto(T ENDX,ENDY):映射前面路徑後的終點

A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧線

Z = closepath():關閉路徑
           
OK 簡單了解了點屬性  那看代碼  根據代碼來推敲 效果會好很多
           
4根線條代碼  在drawable中建立 text.xml
           
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportHeight="100"
android:viewportWidth="100">

<path
android:name="heart1"
android:pathData="
M13,20  C 9,40, 5,60, 2,80 L14,80"
android:strokeColor="#E91E63"
android:strokeWidth="1" />

<path
android:name="heart2"
android:pathData="
M30,38 C20,30,10,40,11.5,50  C11.5,58.5,20,65,30,70  C40,65,48.5,58.5,48.5,50  C50,40,40,30,30,38Z"
android:strokeColor="#E91E63"
android:strokeWidth="1" />

<path
android:name="heart3"
android:pathData="
M30,50 L30,55L30,50L35,50L30,50L60,80"
android:strokeColor="#E91E63"
android:strokeWidth="1" />

<path
android:name="heart4"
android:pathData="
M75,55 L75,65 C75,70,80,75,85,75C90,75,95,70,95,65L95,55"
android:strokeColor="#E91E63"
android:strokeWidth="1" />

</vector>

定義的寬高是256dp 然後viewportHeight viewportWidth都是100  即寬高的每個機關是2.56dp
可以用白紙畫出來  一個寬高256dp的正方形  100等分
每根線條的pathData 對應上面的屬性來了解都很簡單   現在講講愛心怎麼繪制
           
參考
https://www.cnblogs.com/wjtaigwh/p/6652510.html
貝塞爾曲線函數難點是在坐标定位   網上應該有很多貝塞爾曲線定點工具

先用4根貝塞爾曲線繪制個圓
           
svg初探,繪制愛心
再根據愛心的變化  調整幾個坐标點即可
參考 https://www.cnblogs.com/wjtaigwh/p/6652510.html
線條畫完  再加入動畫  
在drawable中建立 text_vector_animator.xml

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/text">
<target
android:name="heart1"
android:animation="@animator/heart_animator" />

<target
android:name="heart2"
android:animation="@animator/heart_animator" />

<target
android:name="heart3"
android:animation="@animator/heart_animator" />

<target
android:name="heart4"
android:animation="@animator/heart_animator" />
</animated-vector>
           
在drawable中建立 heart_animator.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="6000"
android:propertyName="trimPathEnd"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" />

<!-- trimPathEnd 開始到結束  trimPathStart結束到開始-->
           
最後在activity中調用  用的是kotlin
svg_animator_text!!.setImageDrawable(AnimatedVectorDrawableCompat.create([email protected], R.drawable.text_vector_animator))
(svg_animator_text!!.drawable as Animatable).start()

完成
但是有些互動需要監聽動畫  該怎麼辦呢
上面svg動畫強轉Animatable類  進去看看
           
public interface Animatable {
void start();

void stop();

boolean isRunning();
}

是個接口  并且沒有監聽的方法  再看看其他強轉的類  發現有個Animatable2  并且有個AnimationCallback回調 裡面有動畫監聽
試試   發現報錯  程式都運作不起來了   怎麼辦
初探svg  還沒去看源碼怎麼辦呢
然後又發現個Animatable2Compat類  運作成功
           
svg_animator_text!!.setImageDrawable(AnimatedVectorDrawableCompat.create([email protected], R.drawable.text_vector_animator))
val animatable2 = svg_animator_text?.drawable as Animatable2Compat
animatable2.registerAnimationCallback(object : Animatable2Compat.AnimationCallback(){
override fun onAnimationEnd(drawable: Drawable?) {
    super.onAnimationEnd(drawable)
    println("onAnimationEnd")
    }

    override fun onAnimationStart(drawable: Drawable?) {
    super.onAnimationStart(drawable)
    println("onAnimationStart")
    }
})
           
最最最後   一定要記得svg相容性  這裡就不多說了  網上很多