Path使用--二階貝塞爾曲線實現水波效果
阿新 • • 發佈:2019-01-03
上面這個效果是使用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();
}
}
這樣效果就實現了,也是剛接觸二階貝塞爾曲線,寫的比較簡單,有寫的不對的地方歡迎交流。