零、前言
第一次接觸SVG時,被它的強大折服,下面兩個小例子可以看看
SVG 文字sin型曲線動畫、SVG繪製星空效果
Android5.0+也支援向量圖VectorDrawable,是變異削弱版的SVG,但已經非常強大了
本來不想寫SVG的path的,但是發現需要用到,還是總結一下吧
留圖鎮樓
手撕路徑動畫:
path變形 | 變形+旋轉 |
---|---|
常規動畫
一、SVG的Path
1.SVG中的Path(有點反人類,可忽略)
命令 含義
M/m (x,y)+ 移動當前位置
L/l (x,y)+ 從當前位置繪製線段到指定位置
H/h (x)+ 從當前位置繪製,水平線到達指定的 x 座標
V/v (x)+ 從當前位置繪製豎直線到達指定的 y 座標
Z/z 閉合當前路徑
C/c (x1,y1,x2,y2,x,y)+ 從當前位置繪製三次貝塞爾曲線到指定位置
S/s (x2,y2,x,y)+ 從當前位置光滑繪製三次貝塞爾曲線到指定位置
Q/q (x1,y1,x,y)+ 從當前位置繪製,二次貝塞爾曲線到指定位置
T/t (x,y)+ 從當前位置光滑繪製,二次貝塞爾曲線到指定位置
A/a (rx,ry,xr,laf,sf,x,y) 從當前位置繪製弧線到指定位置
複製程式碼
2.一開始覺得挺好玩,但是看到...
<path d="M886.786268 386.409745l-17.009967-2.551495a267.623477 267.623477 0 0 1-229.634551-229.351052l-2.267996-17.009967h-17.293466a290.586932 290.586932 0 0 0-226.799557 85.049834l-5.38649 5.669989-12.473975 149.687708 41.107419-41.10742a193.913621 193.913621 0 0 1 135.229236-56.699889 243.242525 243.242525 0 0 0 12.473976 40.82392 22.112957 22.112957 0 0 0-9.071982 5.10299L18.710963 859.853821C-13.324474 891.889258 3.968992 954.542636 11.339978 981.475083a23.813953 23.813953 0 0 1 0 3.401993 21.545958 21.545958 0 0 0 6.236988 15.308971l5.10299 5.10299 6.520487 6.236987h2.551495a22.112957 22.112957 0 0 0 5.953488 0h3.685493a264.221484 264.221484 0 0 0 66.905869 11.339978 75.127353 75.127353 0 0 0 54.715394-18.710963l537.51495-534.963455a22.112957 22.112957 0 0 0 5.10299-9.071983 219.712071 219.712071 0 0 0 40.82392 12.473976 194.48062 194.48062 0 0 1-56.699889 135.512735l-40.82392 41.10742 149.404208-12.757475 5.669989-5.38649a290.019934 290.019934 0 0 0 85.049834-226.799557zM134.378738 975.238095c-6.803987 6.803987-26.081949 11.623477-80.230344-3.685493-15.025471-54.148394-10.20598-73.426357-3.685493-79.946843l532.128461-535.530454a293.138427 293.138427 0 0 0 23.813954 32.885935 9.922481 9.922481 0 0 0-3.685493 2.267996l-60.101883 60.101882a21.262458 21.262458 0 0 0 0 30.334441 21.829457 21.829457 0 0 0 15.025471 6.236988 22.396456 22.396456 0 0 0 15.025471-5.953488l60.101882-60.385382a8.221484 8.221484 0 0 0 2.267996-3.685493 235.58804 235.58804 0 0 0 32.885935 23.813953zM779.339978 595.348837l-28.349945 1.984496A234.170543 234.170543 0 0 0 788.128461 453.599114v-17.009967l-17.009967-2.267995A208.939092 208.939092 0 0 1 590.529347 255.149502l-2.551495-17.009967H552.82392A235.871539 235.871539 0 0 0 425.249169 271.875969l2.267996-26.932447a247.211517 247.211517 0 0 1 173.501661-67.189369 310.431894 310.431894 0 0 0 245.227021 245.51052A247.495017 247.495017 0 0 1 779.339978 595.348837z
立馬覺得不好玩了,SVG的路徑基本上都是用設計軟體製作的
我們就乖乖做個伸手黨吧,這事交給設計師:svg的資源網站:Iconfont-阿里巴巴向量圖示庫
3.SVG轉為Android可用Xml
下載的svg在Android可不能直接用哦,你有3種選擇:
3.1--AS自帶的轉換
3.2--網上線上轉換:網址
3.3--批量轉化:
前兩者都是單檔案的轉化,如果很多檔案就有一個一個來
so,我自己寫了工具類,批量轉化一下
:詳情可見:第三個工具
工具現在已經使用正則匹配了,更加精確,轉換1000+,暫無失誤情況
二、VectorDrawable的使用
vector一覽:
path標籤一覽:
1.修改顏色:兩種方法
方法1:直接改:fillColor
方法2:使用時:android:tint="@color/red"
複製程式碼
2.分組與變換(吾王之劍豈可不正)
用group將path包起來就可以對path進行變換了
<group
android:rotation="-45"
android:scaleX="0.7"
android:scaleY="0.7"
android:translateY="450">
<path
...
<path
...
</group>
複製程式碼
3.線條與填充
關於path的知識和填充模式在Android關於Path你所知道的和不知道的一切,講的很詳細,這裡就不費神了
三、向量動畫
動畫基本套路如下--簡單畫一個示意圖:
1:路徑動畫:trimPathEnd
1.1--向量圖主體:icon_close.xml
記得為path取個名字(隨意):
android:name="trim_path"
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:strokeColor="@color/black"
android:strokeWidth="10"
android:name="trim_path"
android:pathData="M548.992 503.744L885.44 167.328a31.968 31.968 0 1 0-45.248-45.248L503.744 458.496 167.328 122.08a31.968 31.968 0 1 0-45.248 45.248l336.416 336.416L122.08 840.16a31.968 31.968 0 1 0 45.248 45.248l336.416-336.416L840.16 885.44a31.968 31.968 0 1 0 45.248-45.248L548.992 503.744z" /></vector>
複製程式碼
1.2--objectAnimator動畫:trim_path_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:interpolator="@android:interpolator/linear"
android:propertyName="trimPathEnd"
android:valueFrom="0.0"
android:valueTo="1.0"
android:valueType="floatType"/>
複製程式碼
1.3--動畫承載體:anima_close.xml
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/icon_close">
<target
android:animation="@animator/trim_path_animator"
android:name="trim_path"/>
</animated-vector>
複製程式碼
1.4--使用
<ImageView
android:id="@+id/id_iv"
android:layout_width="200dp"
android:layout_height="200dp"
android:src="@drawable/anima_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
複製程式碼
//點選時:
Drawable drawable = mIdIv.getDrawable();
if (drawable instanceof Animatable){
((Animatable) drawable).start();
}
複製程式碼
2.常規動畫
非要平移或縮放還是針對View吧,向量圖是有邊界的,超出邊界不顯示
2.1:--顏色動畫:color_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<objectAnimator
android:duration="2000"
android:propertyName="strokeColor"
android:valueFrom="@color/black"
android:valueTo="@color/red"/>
<objectAnimator
android:duration="2000"
android:propertyName="strokeColor"
android:valueFrom="@color/red"
android:valueTo="@color/black"/>
</set>
複製程式碼
2.2:--透明度動畫:alpha_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<objectAnimator
android:duration="1500"
android:propertyName="strokeAlpha"
android:valueFrom="1f"
android:valueTo="0.5f"/>
<objectAnimator
android:duration="1500"
android:propertyName="strokeAlpha"
android:valueFrom="0.5f"
android:valueTo="1f"/>
</set>
複製程式碼
2.3:--旋轉動畫:rotation_animator_360.xml
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<objectAnimator
android:duration="1500"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"/>
<objectAnimator
android:duration="1500"
android:propertyName="rotation"
android:valueFrom="360"
android:valueTo="0"/>
</set>
複製程式碼
2.3:向量圖:icon_setting.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<group android:name="container"
android:pivotX="512"
android:pivotY="512">
<path
android:name="setting_path"
android:pathData="M514.216481 977.624786c-55.577806 0.002047-89.432869-13.881149-91.457991-14.734586-6.476505-2.729158-10.8143-8.92937-11.160177-15.94925-0.354064-7.203052-0.674359-14.411221-0.994654-21.620413-0.618077-13.917988-1.257643-28.307719-2.143826-42.354644-0.528026-8.348132-1.026376-8.606005-2.88163-9.564843-6.768147-3.497661-14.646582-6.115278-22.98755-8.885368-7.208169-2.39556-14.662955-4.871961-22.014386-8.124028-4.52199-2.001587-8.719592-4.269233-12.780071-6.462179-4.65809-2.51631-9.058306-4.89345-13.099343-6.385431-4.536316-1.684362-10.599406 3.223415-21.657252 14.137998-2.720971 2.686179-5.535063 5.464455-8.398274 7.985882l-28.677133 25.26236c-5.973038 5.26184-14.663978 6.053879-21.490453 1.958608-94.435813-56.662511-123.892705-127.005602-125.100206-129.972167-2.650363-6.509251-1.333368-13.96199 3.38612-19.168572l27.558659-30.40345c2.249227-2.480494 4.53734-4.933359 6.749728-7.306406 4.301979-4.612041 8.368598-8.971325 12.106736-13.455453 0.12996-0.706081 0.50142-4.331655-3.148713-12.644995-1.414209-3.219321-2.916423-6.41306-4.50664-9.792017-2.321882-4.931313-4.721535-10.032494-6.912433-15.399735-2.28095-5.586229-3.906983-11.44875-5.480828-17.116843-3.557012-12.81691-6.27389-21.336958-11.419074-22.917966-15.532765-4.774747-32.260751-5.204535-49.971112-5.658883-6.92369-0.178055-14.081717-0.36225-21.279652-0.818645-7.943926-0.503467-14.648628-6.088672-16.579607-13.81054-26.709315-106.838284 2.204202-177.410596 3.447519-180.362834 2.729158-6.477528 8.930393-10.816347 15.951297-11.160177l74.987878-3.679809c8.106632-25.620517 18.959817-50.2955 32.389688-73.637114l-51.368948-58.31822c-5.260817-5.973038-6.052856-14.663978-1.957585-21.48943 56.662511-94.430696 127.004579-123.891681 129.971144-125.099183 6.512321-2.650363 13.964036-1.333368 19.171642 3.387144l59.183937 53.647851c20.770046-10.567683 42.865273-19.247366 65.957201-25.908066l3.986801-81.220836c0.343831-7.019881 4.682649-13.220093 11.159154-15.94925 2.952238-1.24434 73.520457-30.162974 180.363857-3.448542 7.721869 1.930979 13.307074 8.635681 13.81054 16.578584l5.41636 85.444021c23.345708 7.106862 45.86663 16.432251 67.231217 27.840068l62.865793-56.979736c5.208629-4.720511 12.663414-6.03546 19.169595-3.387144 2.966565 1.207501 73.314773 30.664394 129.97319 125.100206 4.095271 6.825452 3.303232 15.516392-1.957585 21.48943l-57.280588 65.029062c11.642155 21.230534 21.185508 43.48642 28.489868 66.439178l84.800361 4.163833c7.019881 0.343831 13.221116 4.683672 15.950274 11.160177 1.24434 2.952238 30.156834 73.525574 3.443425 180.362834-1.929955 7.721869-8.634658 13.307074-16.578584 13.81054l-83.734076 5.308913c-6.765077 24.480554-15.841803 47.948035-27.093055 70.049403l54.525847 60.155055c4.719488 5.207605 6.036483 12.659321 3.388167 19.168572-0.437975 1.075495-4.553713 10.937097-14.205537 25.910113-5.470595 8.486278-16.782222 10.930957-25.270547 5.460362-8.486278-5.470595-10.930957-16.784268-5.460362-25.270547 2.444679-3.791349 4.445242-7.161097 6.039553-10.001795l-54.736649-60.387345c-5.262864-5.805216-6.240121-14.3181-2.431376-21.165042 14.670118-26.371624 25.797549-55.164391 33.073256-85.579097 1.867534-7.807826 8.611122-13.484106 16.623609-13.991666l83.375919-5.285377c13.876032-65.705468 4.495384-113.633037-1.193175-133.800355l-85.226057-4.184299c-7.863085-0.385786-14.594393-5.761214-16.711614-13.34289-7.990998-28.617781-19.810185-56.174394-35.133172-81.904405-4.061502-6.820336-3.258207-15.480576 1.988284-21.437242l56.915267-64.615647c-36.648688-56.272631-77.172637-83.529415-95.455025-93.767594l-63.320141 57.391105c-5.900384 5.349845-14.585183 6.262634-21.469987 2.25639-25.765827-14.990413-53.601802-26.530236-82.734306-34.297131-7.588839-2.0241-13.037944-8.66945-13.535271-16.507976l-5.371334-84.723613c-65.210187-13.727653-113.473401-4.379751-133.804449 1.26276l-4.022617 81.945337c-0.393973 8.037047-5.997598 14.870686-13.801331 16.833387-29.217439 7.345292-56.766888 18.160615-81.884962 32.145118-6.848988 3.812839-15.363919 2.835581-21.170159-2.428306l-59.389622-53.833069c-18.325367 10.365068-59.080583 37.884842-95.503121 93.724615l51.191916 58.118676c5.342682 6.064113 6.068206 14.916734 1.785669 21.770839-17.210987 27.544333-30.330796 57.32766-38.993083 88.524173-2.109034 7.593955-8.847505 12.981662-16.718777 13.368472l-75.366502 3.698229c-5.621021 20.255323-14.963807 68.428485-1.318018 133.528156 2.092661 0.061398 4.210905 0.115634 6.367011 0.170892 19.395746 0.49835 39.450501 1.014096 59.774385 7.262404 24.664749 7.579629 31.162744 30.992875 35.906791 48.087205 1.351787 4.870938 2.62785 9.470699 4.100388 13.075807 1.830695 4.483104 3.925403 8.93551 6.14393 13.650905 1.620917 3.443425 3.297093 7.005554 4.90266 10.661827 11.409864 25.983791 5.193279 41.804105-2.031263 50.500161-4.455475 5.365194-9.139148 10.385535-13.667278 15.241123-2.222621 2.382257-4.322445 4.63353-6.39771 6.922666l-19.11229 21.084201c10.365068 18.325367 37.882795 59.080583 93.724615 95.502098l18.455327-16.257266c2.084475-1.835811 4.412496-4.134157 6.877641-6.567579 12.292977-12.135388 32.868595-32.44597 60.013839-22.416546 6.469342 2.390443 12.233626 5.503341 17.807574 8.514931 3.594875 1.942235 6.991228 3.777023 10.197246 5.195326 5.746888 2.542916 12.060687 4.640694 18.744923 6.861268 9.309016 3.091408 18.934235 6.28924 28.244274 11.100826 20.75265 10.722202 21.946848 29.600155 22.588461 39.742143 0.907673 14.389732 1.555425 28.952402 2.180666 43.037189 0.132006 2.966565 0.264013 5.933129 0.398066 8.898671 20.298302 5.630231 68.558445 14.980179 133.775796 1.25355l4.866844-76.765361c0.497327-7.848759 5.957689-14.499226 13.558807-16.515139 32.683377-8.66638 63.733557-22.102391 92.28687-39.934524 6.854105-4.281513 15.703657-3.553942 21.767769 1.786693l59.114352 52.068889c1.155313-0.751107 2.299369-1.50733 3.432169-2.263553 5.502317-4.045129 38.557154-24.867364 98.619088-25.960255 0.112564-0.002047 0.227174-0.00307 0.339738-0.00307 9.942443 0 18.090007 7.966439 18.271132 17.948791 0.184195 10.094916-7.850805 18.427698-17.945721 18.611893-51.03842 0.928139-77.314877 18.622126-77.69043 18.908652-0.285502 0.216941-0.577145 0.424672-0.874927 0.624217-5.347798 3.583618-10.934027 7.126304-16.603143 10.528797-6.825452 4.100388-15.517415 3.307326-21.493523-1.954515l-59.31492-52.244898c-24.545022 14.104229-50.618864 25.367761-77.794807 33.606399l-4.910846 77.467349c-0.503467 7.944949-6.088672 14.648628-13.81054 16.579607C569.595766 974.71962 539.630291 977.623763 514.216481 977.624786zM517.457292 736.938052c-60.94914 0-118.250194-23.734564-161.347758-66.833151-43.097564-43.096541-66.832128-100.397594-66.832128-161.347758 0-60.948117 23.734564-118.247124 66.833151-161.343665 43.097564-43.096541 100.398618-66.831105 161.346735-66.831105s118.250194 23.734564 161.347758 66.831105 66.833151 100.396571 66.833151 161.343665c0 60.94914-23.734564 118.251218-66.833151 161.347758C635.707486 713.202465 578.406432 736.938052 517.457292 736.938052zM517.457292 317.145104c-105.657388 0-191.617156 85.956697-191.617156 191.613062 0 105.658412 85.958744 191.617156 191.617156 191.617156 105.658412 0 191.617156-85.958744 191.617156-191.617156C709.074448 403.101801 623.115704 317.145104 517.457292 317.145104z"
android:strokeWidth="8"
android:strokeColor="#000"/>
</group>
</vector>
複製程式碼
3.4:動畫整合:anima_setting.xml
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/icon_setting">
<target
android:name="setting_path"
android:animation="@animator/alpha_animator"/>
<target
android:name="container"
android:animation="@animator/rotation_animator_360"/>
<target
android:animation="@animator/color_animator"
android:name="setting_path"/>
<target
android:animation="@animator/trim_path_animator"
android:name="setting_path"/>
</animated-vector>
複製程式碼
使用同上,不贅述了
3.5:路徑轉換動畫
左上角的箭頭是不是很驚豔:,第一次看到還以為是程式碼的效果呢,原來向量圖也可以輕鬆實現
注意:對路徑進行
objectAnimator
,前提,path操作符都要一一對應
好吧,看來想躲都躲不掉了,那就來看看svg的path吧
四、SVG的path全指南:
1.操作符:M/m,L/l,H/h,V/v
大寫字母都是絕對座標,小寫字母是相對座標(相對尾點)
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="100"
android:viewportHeight="100">
<!--將指標軸平移-->
<group
android:translateX="4"
android:translateY="4">
<path
android:strokeColor="@color/black"
android:strokeWidth="4"
android:pathData="M0,0 L20 20 0,30,60,60 H 0 V100"/>
</group>
</vector>
複製程式碼
2.操作符:CSQT/csqt
注:小寫字母也是相對座標,只演示大寫字母,小寫字母自己對應一下就行了
C/c是三次貝塞爾:曾經寫過一篇詳細分析:詳見
S/s是簡化版的三次貝塞爾,根據一點,自動順滑,具體怎麼順滑,看個大概吧...
Q/q是二次貝塞爾,三次的都會了,二次的還遠嗎? T/t簡易版二次貝塞爾,需要至少兩個才能發揮曲線作用
3.操作符:A/a
A(rx, ry, xr, laf, sf, x,y)----繪製弧線--最複雜的命令
rx - (radius-x)弧線所在橢圓的 x 半軸長
ry - (radius-y)弧線所在橢圓的 y 半軸長
xr - (xAxis-rotation)弧線所在橢圓的長軸角度
laf - (large-arc-flag)是否選擇弧長較長的那一段弧
sf - (sweep-flag)是否選擇逆時針方向的那一段弧
x, y- 弧的終點位置
複製程式碼
五、路徑屬性動畫
好了,知識儲備有了,開始畫圖了,畫個箭頭和三橫還不小case
箭頭:M8,50, l100,0 M0,47, l40,40 M0,52 l40 -40
選單:M0,50, l80,0 M0,80, l80,0 M0,20 l80 0
複製程式碼
path變形 | 變形+旋轉 |
---|---|
1.將兩個path字串放入string.xml
直接寫也可以,但複用不方便
<resources>
<string name="app_name">test</string>
<string name="path_from">M8,50, l100,0 M0,47, l40,40 M0,52 l40 -40 </string>
<string name="path_to">M0,50, l80,0 M0,80, l80,0 M0,20 l80 0</string>
</resources>
複製程式碼
2.向量圖:path_test.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="100"
android:viewportHeight="100">
<group
android:translateX="4"
android:translateY="4">
<path
android:pathData="M0,0 A30,50,90,0,1,50,50"
android:strokeWidth="4"
android:strokeColor="@color/black"/>
</group>
</vector>
複製程式碼
3.旋轉動畫:rotation_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="180"/>
複製程式碼
4.路徑動畫:path_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:interpolator="@android:interpolator/linear"
android:propertyName="pathData"
android:valueFrom="@string/path_from"
android:valueTo="@string/path_to"
android:valueType="pathType"/>
複製程式碼
5.向量圖檔案:icon_path.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="100"
android:viewportHeight="100">
<group android:name="container"
android:translateX="8"
android:pivotX="50"
android:scaleY="0.8"
android:scaleX="0.8"
android:pivotY="50">
<path
android:name="alpha_anim"
android:pathData="@string/path_from"
android:strokeWidth="8"
android:strokeColor="#000"/>
</group>
</vector>
複製程式碼
6.整合動畫:anima_path.xml
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/icon_path">
<target
android:name="alpha_anim"
android:animation="@animator/path_animator"/>
<target
android:name="container"
android:animation="@animator/rotation_animator">
</target>
</animated-vector>
複製程式碼
ok,這樣就行了,你可以隨意定製兩個路徑,但必須保證兩個路徑的指令相同,不然會崩
後記:捷文規範
1.本文成長記錄及勘誤表
專案原始碼 | 日期 | 備註 |
---|---|---|
V0.1--github | 2018-12-8 | Android資源res之向量圖完全指南(附贈SVG-path命令分析) |
2.更多關於我
筆名 | 微信 | 愛好 | |
---|---|---|---|
張風捷特烈 | 1981462002 | zdl1994328 | 語言 |
我的github | 我的簡書 | 我的掘金 | 個人網站 |
3.宣告
1----本文由張風捷特烈原創,轉載請註明
2----歡迎廣大程式設計愛好者共同交流
3----個人能力有限,如有不正之處歡迎大家批評指證,必定虛心改正
4----看到這裡,我在此感謝你的喜歡與支援