Android贝塞尔曲线-波纹效果
刚写一个波纹的控件,具体的代码给上,简要介绍下实现的方法。
画图分析
如上图绿色方框为手机的屏幕,我们只需要在屏幕的前方再画一个相同的周期视图,然后将整个的画的曲线向右平移,最多平移到原点,也就是将ac段曲线移动到屏幕中间,然后重复这个步骤就可以得到一个类似于波浪的效果。这个周期用的就是ValueAnimator。
源代码
/**
* Created by zhanghs on 2017/12/4/004.
*/
public class RippleView extends View {
private int mWidth,mHeight;//画布的宽带和高度
private float cycleWidth,cycleHeight=60f;//周期的宽度和高度
private Path pathRipple;//画的路径
private Paint paintRipple;//画笔
private float moveSet=0;//移动的值
private ValueAnimator animator;//动画
private boolean isStart=false;
public RippleView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initPaint();
initAnimator();
}
/**
* 初始化动画
*/
private void initAnimator() {
animator=ValueAnimator.ofFloat(0,mWidth);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setDuration(1500);
animator.setInterpolator(new LinearInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
moveSet= (float) valueAnimator.getAnimatedValue();
invalidate();
}
});
}
/**
* 初始化画的路径
*/
private void initPath() {
pathRipple=new Path();
pathRipple.moveTo(-6*cycleWidth+moveSet,0);
pathRipple.quadTo(-5*cycleWidth+moveSet,cycleHeight,-4*cycleWidth+moveSet,0);
pathRipple.quadTo(-3*cycleWidth+moveSet,-cycleHeight,-2*cycleWidth+moveSet,0);
pathRipple.quadTo(-cycleWidth+moveSet,cycleHeight,moveSet,0);
pathRipple.quadTo(cycleWidth+moveSet,-cycleHeight,2*cycleWidth+moveSet,0);
pathRipple.lineTo(2*cycleWidth+moveSet,mHeight/2);
pathRipple.lineTo(-6*cycleWidth+moveSet,mHeight/2);
pathRipple.close();
pathRipple.setFillType(Path.FillType.WINDING);
}
/**
* 初始化画笔
*/
private void initPaint() {
paintRipple=new Paint();
paintRipple.setStrokeWidth(2);
paintRipple.setStyle(Paint.Style.FILL);
paintRipple.setColor(Color.BLUE);
paintRipple.setAntiAlias(true);
}
/**
* 画波纹
* @param canvas
*/
private void drawRipple(Canvas canvas) {
initPath();
canvas.drawPath(pathRipple,paintRipple);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mHeight=h;
mWidth=w;
cycleWidth=mWidth/4;
initAnimator();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(mWidth/2,mHeight/2);
drawRipple(canvas);
}
/**
* 开始动画
*/
public void start(){
if(isStart) return;
isStart=true;
if(animator==null){
initAnimator();
}
animator.start();
}
/**
* 结束动画
*/
public void stop(){
if(!isStart) return;
isStart=false;
moveSet=0;
animator.cancel();
animator=null;
invalidate();
}
}