Android貝塞爾曲線實(shí)戰(zhàn)之鯨云特效-創(chuàng)新互聯(lián)

作者:哈哈將 -個(gè)推 Android 高級(jí)開發(fā)工程師

專注于為中小企業(yè)提供成都做網(wǎng)站、成都網(wǎng)站建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)攀枝花免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上1000家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

前言

APP開發(fā)市場已經(jīng)告別“野蠻生長”時(shí)代,人們不再滿足于APP外形創(chuàng)新,而將目光轉(zhuǎn)向全方面的用戶體驗(yàn)上。在這過程中,動(dòng)效化作為移動(dòng)互聯(lián)網(wǎng)產(chǎn)品的新趨勢,如何實(shí)現(xiàn)酷炫絲滑的動(dòng)畫效果已然成為開發(fā)者們的新課題。實(shí)現(xiàn)方式其實(shí)很簡單。本文將為你剖析理論基礎(chǔ)以及具體應(yīng)用??赐赀@篇文章,你的App也可以達(dá)到酷炫吊炸天的動(dòng)畫效果。

先看兩個(gè)例子:

1. 手機(jī) QQ 未讀消息紅點(diǎn)拖拽效果。

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

2. 小說閱讀 APP 的翻頁效果。

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

簡介

在開始實(shí)戰(zhàn)之前,我們還是先了解下理論基礎(chǔ)。動(dòng)畫的終極武器就是貝塞爾曲線了。它是一條光滑的曲線,依據(jù)四個(gè)位置任意的點(diǎn)坐標(biāo)繪制而成。1962年,法國工程師皮埃爾·貝塞爾(Pierre Bézier)率先研究出這種矢量繪制曲線的方法并給出了詳細(xì)的計(jì)算公式,應(yīng)用于汽車的主體設(shè)計(jì)。因此,人們將按照此種公式繪制的曲線命名為貝塞爾曲線。

核心思想

貝塞爾曲線是計(jì)算機(jī)圖形學(xué)中運(yùn)用得最多的參數(shù)曲線之一。它通過控制曲線上的四個(gè)點(diǎn)(起始點(diǎn)、終止點(diǎn)以及兩個(gè)相互分離的中間點(diǎn))來創(chuàng)造、編輯圖形。其中起重要作用的是位于曲線中央的控制線。這條線是虛擬的,中間與貝塞爾曲線交叉,兩端是控制端點(diǎn)。移動(dòng)兩端的端點(diǎn)時(shí)貝塞爾曲線可以改變曲線的曲率(彎曲的程度);移動(dòng)中間點(diǎn)(也就是移動(dòng)虛擬的控制線)時(shí),貝塞爾曲線在起始點(diǎn)和終止點(diǎn)鎖定的情況下做均勻移動(dòng)。注意:貝塞爾曲線上的所有控制點(diǎn)、節(jié)點(diǎn)均可編輯。

原理

這里面有個(gè)通用公式,這個(gè)公式已經(jīng)有前輩幫我們總結(jié)好了。

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

其中 P0 為起點(diǎn),Pn 為中點(diǎn),Pi 為控制點(diǎn)。

一階貝塞爾曲線

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

一階這個(gè)比較簡單,因?yàn)闆]有在網(wǎng)上找到可以直接輸入數(shù)學(xué)公式的工具,就手工推導(dǎo)了下。一階這個(gè)比較簡單,因?yàn)闆]有在網(wǎng)上找到可以直接輸入數(shù)學(xué)公式的工具,就手工推導(dǎo)了下。

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

最后的公式為 B(t)=(1-t)Po+tP1,t->[0,1]

二階貝塞爾曲線

先看動(dòng)畫效果。

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

關(guān)注紅線部分,這條線就是我們單位時(shí)間內(nèi)運(yùn)行的貝塞爾曲線效果圖。這條紅線實(shí)際上是由無數(shù)個(gè)點(diǎn)組成,隨著 t 的不斷變化,紅線的轉(zhuǎn)換過程非常的順滑。

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

最后得到的公式如下:

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

貝塞爾曲線的繪制,無論多少階(一階除外),均需要逐級(jí)降階,最終降至一階。在 “二階貝塞爾曲線解析” 這段文字中,從 第一步 到 第二步 的過程就是在降階。貝塞爾曲線最終的路徑是由 一階基線 上游走的紅色小點(diǎn)形成的。

三階貝塞爾曲線

有了二階的推導(dǎo)過程,三階的推導(dǎo)就容易多啦。由于篇幅限制,推導(dǎo)過程這里不再展開,大家有興趣的話可以自行推導(dǎo)下。

最后的紅色曲線是由藍(lán)色一階曲線獲得的,而藍(lán)色一階曲線又是由綠色一階曲線獲得,最后的綠色一階曲線則是最外的 P0,P1,P2,P3構(gòu)成的。動(dòng)畫效果為:

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

四階貝塞爾曲線

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

五階貝塞爾曲線

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

結(jié)論?我們發(fā)現(xiàn)原來貝塞爾曲線上的點(diǎn)與高數(shù)中二項(xiàng)式展開一樣,對(duì)于每個(gè)線段上的點(diǎn)經(jīng)過控制點(diǎn)進(jìn)行切面操作,而連續(xù)的兩點(diǎn)之間是無限接近的,所以在繪制的過程中會(huì)出現(xiàn)非常絲滑地過度。

貝塞爾曲線在 Android 上的使用

在Android 中使用貝塞爾曲線比較簡單,Android 已經(jīng)內(nèi)置了貝塞爾曲線的 API,開發(fā)者可以直接予以調(diào)用。主要有兩個(gè) API 。

quadTo

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

其中 (startX,startY) 為起點(diǎn),(endX,endY)為終點(diǎn),而 (eventX,eventY)即為控制點(diǎn)了。

cubicTo

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

調(diào)用此方法即可畫出一條三階貝塞爾曲線。(startX,startY)為起點(diǎn),(endX,endY)為終點(diǎn),而(leftX,leftY)與(rightX,rightY) 為兩個(gè)控制點(diǎn)了。

多階貝塞爾曲線:?Android 系統(tǒng)高只能畫出三階的貝塞爾曲線,那么想畫出更高階的怎么辦呢?其實(shí)也很簡單。如果真的需要使用高階的曲線,可以進(jìn)行人工降階,降階到 3 級(jí)即可。

實(shí)戰(zhàn)

終于到實(shí)戰(zhàn)環(huán)節(jié)了,該環(huán)節(jié)共有兩個(gè)demo。一個(gè)是貝塞爾曲線擬圓效果,另一個(gè)是仿網(wǎng)易云音樂里面的鯨云效果。

效果實(shí)現(xiàn)1:以貝塞爾曲線畫圓為例

前文總結(jié)了貝塞爾曲線的通用公式。在網(wǎng)上瀏覽資料的過程中我們發(fā)現(xiàn)有這么一個(gè)公式:(4/3)tan(π/(2n)),其意義是由n段三階貝塞爾曲線擬合圓形時(shí),曲線端點(diǎn)到該端點(diǎn)最近的控制點(diǎn)的最佳距離是(4/3)tan(π/(2n))。大家感興趣的話可以自行推導(dǎo)。推導(dǎo)過程并不復(fù)雜,因?yàn)樨惾麪柷€有個(gè)重要的性質(zhì),即曲線方程中t=0.5時(shí)的點(diǎn)一定落在圓弧上。只需要把坐標(biāo)系帶入到三階方程式即可。

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

最后得知當(dāng) t=0.5,根據(jù)圓形方程式 X^2+Y^2=R^2 ,得到h=(4/3)(sqrt(2)-1) ≈ 0.552284749831 。有了上述的理論基礎(chǔ),再去畫圓就非常的輕松,我們先在草稿紙中得到這么一個(gè)模型。

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

根據(jù)上圖,這個(gè)圓是由 4 段三階貝塞爾曲線構(gòu)成的,分別是 P0->P3,P3->P6,P6->P9,P9->P11。三階貝塞爾曲線的構(gòu)圖是 Android 內(nèi)置的,我們直接調(diào)用API 即可,核心代碼如下:

publicHeartView(Context context, @Nullable AttributeSet attrs,intdefStyleAttr){? ? ? ? super(context, attrs, defStyleAttr);? ? ? ? init(context)? ? }@Overrideprotectedvoidinit(Context context){mPaint =newPaint();mPaint.setAntiAlias(true);? ? ? ? mPaint.setColor(Color.RED);? ? ? ? mPaint.setStyle(Paint.Style.FILL);mPath =newPath();//繪制 12 個(gè)點(diǎn)。mCurPointList =newArrayList<>();mCurPointList.add(newPointF(0, dpToPx(-89)));mCurPointList.add(newPointF(dpToPx(50), dpToPx(-89)));mCurPointList.add(newPointF(dpToPx(90), dpToPx(-49)));mCurPointList.add(newPointF(dpToPx(90),0));mCurPointList.add(newPointF(dpToPx(90), dpToPx(50)));mCurPointList.add(newPointF(dpToPx(50), dpToPx(90)));mCurPointList.add(newPointF(0, dpToPx(90)));mCurPointList.add(newPointF(dpToPx(-49), dpToPx(90)));mCurPointList.add(newPointF(dpToPx(-89), dpToPx(50)));mCurPointList.add(newPointF(dpToPx(-89),0));mCurPointList.add(newPointF(dpToPx(-89), dpToPx(-49)));mCurPointList.add(newPointF(dpToPx(-49), dpToPx(-89)));? ? }@OverrideprotectedvoidonDraw(Canvas canvas){? ? ? ? drawCoordinate(canvas);canvas.translate(mWidth /2, mHeight /2);? ? ? ? mPath.reset();for(inti =0; i <4; i++) {if(i ==0) {mPath.moveTo(mCurPointList.get(i *3).x, mCurPointList.get(i *3).y);}else{mPath.lineTo(mCurPointList.get(i *3).x, mCurPointList.get(i *3).y);? ? ? ? ? ? }intendPointIndex;if(i ==3) {endPointIndex =0;}else{endPointIndex = i *3+3;? ? ? ? ? ? }mPath.cubicTo(mCurPointList.get(i *3+1).x, mCurPointList.get(i *3+1).y,mCurPointList.get(i *3+2).x, mCurPointList.get(i *3+2).y,mCurPointList.get(endPointIndex).x, mCurPointList.get(endPointIndex).y);? ? ? ? }? ? ? ? canvas.drawPath(mPath, mPaint);? ? }}

成果展示

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

效果實(shí)現(xiàn)2:以網(wǎng)易云音樂鯨云效果為例

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

轉(zhuǎn)換成 GIF,圖片可能會(huì)有點(diǎn)失真,但并不妨礙具體實(shí)現(xiàn)思路。根據(jù)這個(gè) GIF,我們發(fā)現(xiàn)有三點(diǎn)功能需要去完成:

1.背景色與歌曲圖片相搭配,隨圖片的變化而變化;

2.歌曲中間圖片是一張圓形圖片并且可以自動(dòng)旋轉(zhuǎn);

3.圖形外圈有動(dòng)感 3D環(huán)繞效果。

第一點(diǎn)實(shí)現(xiàn)比較簡單。

第二點(diǎn)也不難。我們可以把一張圖片裁剪成圓形,也可以使用 GitHub 上現(xiàn)有的開源庫,再加上一個(gè)屬性動(dòng)畫代碼。

publicvoidhandleRotate(){ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(ivShowPic,"rotation",0f,360f);objectAnimator.setDuration(20*1000);? ? ? ? objectAnimator.setRepeatMode(ValueAnimator.RESTART);objectAnimator.setInterpolator(newLinearInterpolator());objectAnimator.setRepeatCount(-1);? ? ? ? objectAnimator.start();? ? }

看下動(dòng)感3D環(huán)繞效果即轉(zhuǎn)圈圈。

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

第三點(diǎn)?如何做跳動(dòng)旋律特效???!先不考慮前面兩點(diǎn)需求,我們逐步分析下跳動(dòng)旋律特效。動(dòng)態(tài)圖在文章開始部分已經(jīng)看到了,我們建議先從靜態(tài)圖著手。

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

我們猜測可能的實(shí)現(xiàn)思路(不代表官方實(shí)現(xiàn)思路):該動(dòng)效外層一圈有 4 條線段在不規(guī)則地跳動(dòng),每條線的背后是一個(gè)圓,每個(gè)圓由 4 條貝塞爾曲線組成。

第一步?先畫個(gè)圓。我們只需要把畫筆的屬性設(shè)置成如下屬性,即可畫出一個(gè)空心圓。

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

為達(dá)到更順滑的環(huán)繞效果,我們需要不斷調(diào)試各條貝塞爾曲線的對(duì)應(yīng)的兩個(gè)控制點(diǎn)。具體參數(shù)可根據(jù)業(yè)務(wù)場景來定。文中demo僅作參考。

第二步?上文我們分析過這個(gè)圓其實(shí)是由貝塞爾曲線組成的擬圓。在Android系統(tǒng)中是以每秒60幀為滿幀的,那么只要將1秒÷60幀,就能得出16毫秒(ms)/幀是滿幀的界限,即每幀快于16ms則為流暢。所以我們這邊的刷新頻率設(shè)定為每 80 毫秒刷新一次:

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

得到的效果如下:

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

第三步?雛形已經(jīng)完成,后續(xù)我們的做法是再往上添加 2 個(gè)圓,看下 3 個(gè)圓是怎么樣的效果。

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

第四步?最后一步當(dāng)然是把前面兩點(diǎn)合在一起啦,合一起后就可以看下最終效果了:

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

實(shí)際效果與預(yù)期效果會(huì)存在一定的差異,主要原因在于函數(shù)坐標(biāo)以及畫筆的一些屬性問題。以上就是具體的實(shí)現(xiàn)思路,供大家參考。

總結(jié)

酷炫動(dòng)畫的實(shí)現(xiàn)過程并沒有我們想象的那么復(fù)雜。其實(shí),很多復(fù)雜特效都是由不同的動(dòng)畫組合而成的,而絲滑般的動(dòng)態(tài)效果則離不開貝塞爾曲線的應(yīng)用。希望這篇文章可以幫助到想要做出酷炫絲滑的動(dòng)態(tài)效果的你。

如何獲取實(shí)戰(zhàn) Demo

關(guān)注【個(gè)推技術(shù)學(xué)院】微信公眾號(hào)

(微信號(hào):getuitech)

回復(fù)關(guān)鍵詞“曲線”

即可獲取仿鯨云特效動(dòng)畫demo!

Android 貝塞爾曲線實(shí)戰(zhàn)之鯨云特效

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

新聞標(biāo)題:Android貝塞爾曲線實(shí)戰(zhàn)之鯨云特效-創(chuàng)新互聯(lián)
當(dāng)前鏈接:http://bm7419.com/article32/dgossc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、面包屑導(dǎo)航虛擬主機(jī)、服務(wù)器托管、網(wǎng)站設(shè)計(jì)網(wǎng)站改版

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

營銷型網(wǎng)站建設(shè)