情人節過去有那麼幾天了,有些人在考慮,情人節那天應該贈送什麼禮物才會讓女神關注我了,才有機會約飯了,今天教大家一個小技能,能幫助大家在情人節或者其他的節日成功表白,約會;
同時,在給大家分享之前,這裡推薦下我自己建的Android技術分享群 :653961128,不管你是小白還是大牛,小編我都挺歡迎,不定期分享幹貨,包括2017最新的Android企業案例學習資料和零基礎入門教程,歡迎初學和進階中的小夥伴,大家一起交流學習,共同進步。
我們先看一下效果圖:
那麼這個效果是怎麼樣制作的,先給大家介紹一下原理
樹枝是通過貝塞爾曲線來構造的,二階貝塞爾曲線。
數據的準備
-
getBranches()函數中,定義各個樹枝的位置和形狀,最終返回樹幹。
-
繪制的時候,先繪制樹幹,然後繪制其分支,最後繪制分支的分支(隻有三層)。
封裝Branch類
-
主要包含分支的構建(構造函數,addChild函數),以及繪制。
-
繪制分支時,不斷地調用grow函數,繪制點(currLen)逐漸靠近末端(maxLen), 分支的半徑逐漸變小;
-
最終控制點到達分支末端(currLen==maxLen), 繪制結束。
-
如果是繪制靜态畫面,while循環直到grow返回false;
-
如果是繪制動畫, 可通過調用postInvalidate(),不斷地對回調繪制函數, 每一幀樹枝成長一截。
樹幹效果圖如下:
二、花瓣
-
花瓣的繪制,是通過一條曲線實現的:本文的主角,自帶愛情故事的心形線。
-
心形線有很多種,有的用普通方程表示,有的用參數方程表示。
-
對于繪制曲線來說,參數方程更方便一些。
-
在網站wolframalpha上,可以輸入方程直接預覽曲線。
計算心形線
-
因為要繪制很多花瓣,所以可以将其形狀預先計算好,緩存起來。
-
或許是因為精度的原因, 如果直接采樣上圖的點,繪制時如果有scale(縮放)操作,可能會顯示不平滑;
-
所以在采樣心形線的點時我們放大一定比率(SCALE_FACTOR )。
-
就像一張圖片,如果分辨率是200x200, 縮小到100x100顯示,圖片還是清晰的,如果放大到400x400,可能會模糊。
封裝Bloom類
-
一片花瓣,除了形狀之外,還有方位,顔色,方向,大小等參數。
-
故此,和Branch一樣,封裝了一個類。
-
花瓣的顔色和方向參數是随機初始化的。
-
顔色方面,ARGB中Red通道固定為最大值0xff, 效果就是花瓣的顔色為紅,紫,黃,白等。
-
因為要适應移動設備的多分辨率,所以一些參數要根據分辨率來動态設置。
三、樹冠
-
樹冠是由數百片花瓣構成,關鍵點在于确定這些花瓣的位置。
-
這裡用到另一條心形線(x^2 y^2 -1)^3 - x^2 * y^3 = 0。
-
我們需要做的,是在心形内部選取位置,而非繪制曲線,故此,普通方程相對于參數方程更合适。
-
坐标系中的點(x,y), 計算ax by, 大于0和小于0分别在直線的兩側, x^2 y^2 - r 則分别在圓外和圓内;
-
這個現象還蠻奇妙的,雖然我不知道這在數學中叫什麼-_-。
-
類似的,在x=[-c, c], y=[-c,c]的範圍内随機選取(x^2 y^2 -1)^3 - x^2 * y^3<0的點,即可使得花瓣的位置錯落與心形線中。
繪制動畫
-
簡單地說,不斷地觸發onDraw(Canvas canvas)回調,在每一幀裡面,變換繪制參數,就形動畫了。
-
在這個例子中,劃分了幾個動畫階段,每個階段各自變化自己的參數。
-
總之,就是分而治之,然後串聯起來。
連接起來最後的效果圖:
,