1. 程式人生 > >Path使用--二階貝塞爾曲線實現水波效果

Path使用--二階貝塞爾曲線實現水波效果

這裡寫圖片描述
上面這個效果是使用Path繪製二階貝塞爾曲線實現的;二階貝塞爾曲線涉及到三個點,起始點、拐點、終點,而拐點有決定著曲線的形狀;下面這張圖大致展示了二階貝塞爾曲線:
這裡寫圖片描述

A點是起始點,C點是終點,B點是拐點,當然根據繪製的需求,B是變動的,繪製出來的曲線也就不一樣,這裡只是一個大致的示意圖;那麼只需呼叫path裡面的相應方法,進行這幾個點的設定一個簡單的二階貝塞爾曲線就可以實現了;
設定二階貝塞爾曲線的方法:

//其中x,y的座標代表圖中曲線左邊起點的位置座標  也就是A點的位置
moveTo(float x,float y) 
//其中x1,y1的座標就是控制點(拐點)的位置, 也就是B點的位置
//x2,y2的座標就是曲線右邊終點的位置座標,也就是C點的位置 quadTo(float x1, float y1, float x2, float y2 )

還可呼叫下面這個方法進行設定,不過傳入的引數和quadTo會有區別;

//這裡的dx1、dy1、dx2、dy2都是相對座標
rQuadTo(float dx1, float dy1, float dx2, float dy2);

水波效果程式碼:

public class WaterView extends View{
    private Paint mPaint;
    private Path mPath;
    //波長的長度
private int waterLenght=100; private int dx; public WaterView(Context context) { this(context,null); } public WaterView(Context context, AttributeSet attrs) { this(context, attrs,0); } public WaterView(Context context, AttributeSet attrs, int defStyleAttr) { super
(context, attrs, defStyleAttr); mPaint=new Paint(); mPaint.setColor(Color.BLUE); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPath=new Path(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int originY=800; //重置path mPath.reset(); int halfWaterLenght=waterLenght/2; //起點 mPath.moveTo(-waterLenght+dx,originY); //螢幕的寬度李放多少個波長 for (int i=-waterLenght;i<getWidth()+waterLenght;i+=waterLenght){ //相對繪製二階貝塞爾曲線(相對於自己的起點--也就是上一個曲線的終點 的距離dx1) mPath.rQuadTo(halfWaterLenght/2,-30,halfWaterLenght,0); mPath.rQuadTo(halfWaterLenght/2,30,halfWaterLenght,0); } //顏色填充 //畫一個封閉的空間 mPath.lineTo(getWidth(),getHeight()); mPath.lineTo(0,getHeight()); //閉合path mPath.close(); //繪製到畫布上 canvas.drawPath(mPath,mPaint); } /** * 開啟動畫 */ public void startAnimation(){ ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, waterLenght); valueAnimator.setDuration(700); //設定插值器 valueAnimator.setInterpolator(new LinearInterpolator()); //設定無線迴圈 valueAnimator.setRepeatCount(ValueAnimator.INFINITE); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float value = (float) animation.getAnimatedValue(); dx= (int) value; postInvalidate(); } }); valueAnimator.start(); } }
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        WaterView waterView = (WaterView) findViewById(R.id.water_view);
        waterView.startAnimation();
    }
}

這樣效果就實現了,也是剛接觸二階貝塞爾曲線,寫的比較簡單,有寫的不對的地方歡迎交流。