wave.gif
波動(dòng)的弧度衣厘,弧度生成由二階貝塞爾曲線生成
path.rQuadTo(...)
path.quadTo(...)
// 兩者區(qū)別是rQuadTo是相對(duì)終點(diǎn)的
思路
1584352627(1).jpg
波浪由一個(gè)個(gè)這樣的波浪組合而成树酪,使用path.rQuadTo(...) 畫(huà)出一個(gè)波浪,之后接著再畫(huà)波浪直至充滿整個(gè)屏幕寬度灭翔。
1584352825(1).jpg
之后再path.lineTo(...)到屏幕的右下角 -> 屏幕的左下角 -> path.close()形成閉合魏烫。這樣一個(gè)靜態(tài)的波浪就完成了辣苏。
之后動(dòng)畫(huà)就通過(guò)ValueAnimator形成動(dòng)畫(huà)。
public class WaveView extends View{
private int mWaveWidth = 400;// 一個(gè)波浪長(zhǎng)
private int halfWaveWidth = 200;// 一半波浪長(zhǎng)
private Paint mPaint;
private int dx;// 移動(dòng)的距離
private int dy = 300;// 初始的y距離
private Path mPath;
public WaveView(Context context) {
super(context);
initPaint();
startAnim();
}
public WaveView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initPaint();
startAnim();
}
public WaveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
startAnim();
}
private void initPaint() {
mPaint = new Paint();
mPaint.setColor(Color.BLUE);
mPaint.setStyle(Paint.Style.FILL);
}
private void startAnim() {
mPath = new Path();
ValueAnimator anim = ValueAnimator.ofInt(0,mWaveWidth);
anim.setDuration(2000);
anim.setRepeatCount(ValueAnimator.INFINITE);
anim.setInterpolator(new LinearInterpolator());
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
dx = (int)valueAnimator.getAnimatedValue();
invalidate();
}
});
anim.start();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 畫(huà)在屏幕的盡可能多的波浪哄褒,并且路徑起始點(diǎn)向左移動(dòng)一個(gè)波浪(為了動(dòng)畫(huà))
mPath.reset();
mPath.moveTo(-mWaveWidth + dx,dy);
for(int i = -mWaveWidth;i <= getWidth() + mWaveWidth; i+=mWaveWidth){
mPath.rQuadTo(halfWaveWidth / 2,-100,halfWaveWidth,0);
mPath.rQuadTo(halfWaveWidth / 2, 100,halfWaveWidth,0);
}
mPath.lineTo(getWidth(),getHeight());
mPath.lineTo(0,getHeight());
mPath.close();
canvas.drawPath(mPath,mPaint);
}
}