日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

android實現貝塞爾曲線之波浪效果_Android

作者:程序編織夢想 ? 更新時間: 2022-08-21 編程語言

本文實例為大家分享了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.當間距超過一定值之后,黏連小球消失,氣泡小球繼續跟隨手指移動,此時手指松開,氣泡小球消失~

結尾

本來想把上面的全部弄在一篇博客呢,現在看來不太可能,一篇一篇的來吧。核心就是貝塞爾曲線的應用,大家如何理解了貝塞爾曲線,這些都不難。

原文鏈接:https://blog.csdn.net/mffandxx/article/details/70891481

欄目分類
最近更新