波动的弧度,弧度生成由二阶贝塞尔曲线生成
path.rQuadTo(...)
path.quadTo(...)
// 两者区别是rQuadTo是相对终点的
思路
1584352627(1).jpg波浪由一个个这样的波浪组合而成,使用path.rQuadTo(...) 画出一个波浪,之后接着再画波浪直至充满整个屏幕宽度。
1584352825(1).jpg
之后再path.lineTo(...)到屏幕的右下角 -> 屏幕的左下角 -> path.close()形成闭合。这样一个静态的波浪就完成了。
之后动画就通过ValueAnimator形成动画。
public class WaveView extends View{
private int mWaveWidth = 400;// 一个波浪长
private int halfWaveWidth = 200;// 一半波浪长
private Paint mPaint;
private int dx;// 移动的距离
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);
// 画在屏幕的尽可能多的波浪,并且路径起始点向左移动一个波浪(为了动画)
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);
}
}
网友评论