android實現貝塞爾曲線之波浪效果
本文實例為大傢分享瞭android實現貝塞爾曲線之波浪效果的具體代碼,供大傢參考,具體內容如下
1 前言
為瞭給我以前的博客填坑,這章講解貝塞爾曲線的幾個常用的應用:
1.波浪效果
2.qq聊天列表上的沾粘體效果
3.翻書頁效果
4.彈性球效果
大傢如果把這些看懂並掌握,以後做和貝塞爾曲線相關的效果應該都能信手拈來!
2 波浪效果
原理分析:
其實這個效果應用瞭2個階的貝塞爾曲線來完成的,先看一下原理分析圖:
有上面的圖可以看出:在屏幕的左面畫出瞭1.5個波長,在屏幕中畫出1個波長,然後讓它循環的向右移動,這個就會出現波浪效果,這裡有幾點需要註意:
1.為什麼是1.5個波長而不是1個波長呢?
理論上1個波長就夠瞭,但是實際運行出來的效果會出現不協調,所以經過調試,我又加瞭0.5個波長
2.那條綠線是幹什麼用的?
在波浪線以下的所有空間都要填充成一個顏色,所以path必須是封閉的區間,隻有這個才能填充。代碼中我會具體的解釋
我們在編碼的時候隻需要計算最左面半個波長的坐標,其他的用for循環搞定。
好瞭我們看一下代碼:
public class WaveView extends View { private int width = 0; private int height = 0; private int baseLine = 0;// 基線,用於控制水位上漲的,這裡是寫死瞭沒動,你可以不斷的設置改變。 private Paint mPaint; private int waveHeight = 100;// 波浪的最高度 private int waveWidth ;//波長 private float offset =0f;//偏移量 public WaveView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } /** * 不斷的更新偏移量,並且循環。 */ private void updateXControl(){ //設置一個波長的偏移 ValueAnimator mAnimator = ValueAnimator.ofFloat(0,waveWidth); mAnimator.setInterpolator(new LinearInterpolator()); mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float animatorValue = (float)animation.getAnimatedValue() ; offset = animatorValue;//不斷的設置偏移量,並重畫 postInvalidate(); } }); mAnimator.setDuration(1000); mAnimator.setRepeatCount(ValueAnimator.INFINITE); mAnimator.start(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawPath(getPath(),mPaint); } //初始化paint,沒什麼可說的。 private void initView(){ mPaint = new Paint(); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.FILL); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); width = getMeasuredWidth();//獲取屏幕寬度 height = getMeasuredHeight();//獲取屏幕高度 waveWidth = width; baseLine = height/2; updateXControl(); } /** * 核心代碼,計算path * @return */ private Path getPath(){ int itemWidth = waveWidth/2;//半個波長 Path mPath = new Path(); mPath.moveTo(-itemWidth * 3, baseLine);//起始坐標 //核心的代碼就是這裡 for (int i = -3; i < 2; i++) { int startX = i * itemWidth; mPath.quadTo( startX + itemWidth/2 + offset,//控制點的X,(起始點X + itemWidth/2 + offset) getWaveHeigh( i ),//控制點的Y startX + itemWidth + offset,//結束點的X baseLine//結束點的Y );//隻需要處理完半個波長,剩下的有for循環自已就添加瞭。 } //下面這三句話很重要,它是形成瞭一封閉區間,讓曲線以下的面積填充一種顏色,大傢可以把這3句話註釋瞭看看效果。 mPath.lineTo(width,height); mPath.lineTo(0,height); mPath.close(); return mPath; } //奇數峰值是正的,偶數峰值是負數 private int getWaveHeigh(int num){ if(num % 2 == 0){ return baseLine + waveHeight; } return baseLine - waveHeight; } }
核心的代碼在 getPath()方法中,其實這個坐標是有規律的:
先找到最左面的半個波長,設置貝塞爾曲線坐標,
然後用for循環,不斷的設置,
這個規律大傢體會,我這裡簡單提一下。
3 qq聊天列表上的沾粘體效果
先看一個效果圖:
這個做起來小有點復雜。具體思路如下:
1.畫兩個圓,一個黏連小球固定在一個點上,一個氣泡小球跟隨手指的滑動改變坐標。隨著兩個圓間距越來越大,黏連小球半徑越來越小。
2.當間距小於一定值,松開手指氣泡小球會恢復原來位置;
3.當間距超過一定值之後,黏連小球消失,氣泡小球繼續跟隨手指移動,此時手指松開,氣泡小球消失~
結尾
本來想把上面的全部弄在一篇博客呢,現在看來不太可能,一篇一篇的來吧。核心就是貝塞爾曲線的應用,大傢如何理解瞭貝塞爾曲線,這些都不難。
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Android自定義View繪制貝塞爾曲線的方法
- Android用Canvas繪制貝塞爾曲線
- android實現倒計時動態圈
- Android開發之自定義加載動畫詳解
- Android自定義view實現圓形進度條效果