学习笔记
之前看了很多的波浪Demo觉得挺有意思的,也想写一个感受一下。 查了一些文章和资料,然后结合理解写了一个demo。 其实波浪的绘制就是是贝塞尔曲线一个简单的应用,而让波浪进行波动,其实并不需要对控制点进行改变,而是可以通过位移来实现,贝塞尔曲线+动画。
效果图:
贝塞尔曲线: 在Path中有四个函数与贝赛尔曲线有关:
//二阶贝赛尔
public void quadTo(float x1, float y1, float x2, float y2)
public void rQuadTo(float dx1, float dy1, float dx2, float dy2)
//三阶贝赛尔
public void cubicTo(float x1, float y1, float x2, float y2,float x3, float y3)
public void rCubicTo(float x1, float y1, float x2, float y2,float x3, float y3)
复制代码
波浪用到的是Path类的quadTo(x1, y1, x2, y2)方法,二阶贝塞尔曲线,参数中(x1,y1)是控制点坐标,(x2,y2)是终止点坐标,起始点默认是Path的起始点(0,0)
思路:
1、通过for循环画出两个波纹,需要波纹的-mWL点、-3/4 * mWL点、-1/2 * mWL、-1/4 *mWL四个点,通过path的quadTo画出
2、接着通过ValueAnimator对offset递增,实现平移效果,并无限重复
复制代码
代码实现:
/**
* 波浪wave
*
* .-~~~~~~~~~-._ _.-~~~~~~~~~-.
* __ .' ~. .~ `.__
* .'// 加油 \ . / 加油 \\`.
* .'// | \\`.
* .'// .-~"""""""~~~~-._ | _,-~~~~"""""""~-. \\`.
* .'//.-" `-. | .-' "-.\\`.
* .'//______.============- .. \ | / ..-============._______\\`.
* .'____________________________\|/___________________________`.
*
*
* Created by yy on 18/10/11.
*/
public class WaveBezierView extends View implements View.OnClickListener {
private Paint mPaint;//波浪画笔
private Path mPath;//波浪Path类
private int mWaveLength = 1000;//一个波浪长度
private int mWaveCount;//波纹个数
private int mOffset;//平移偏移量
private int mScreenHeight;//屏幕高度
private int mScreenWidth;//屏幕宽度
private int mCenterY;//波纹的中间轴
public WaveBezierView(Context context) {
super(context);
}
public WaveBezierView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public WaveBezierView(Context context, AttributeSet attrs) {
super(context, attrs);
mPath = new Path();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(getResources().getColor(R.color.waveColor));
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
setOnClickListener(this);
}
//获取宽和高
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mScreenHeight = h;
mScreenWidth = w;
//加1.5:至少保证波纹有2个,至少2个才能实现平移效果
mWaveCount = (int) Math.round(mScreenWidth / mWaveLength + 1.5);
mCenterY = mScreenHeight / 2;
}
//绘制水波纹
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPath.reset();
mPath.moveTo(-mWaveLength + mOffset, mCenterY);//移到屏幕外最左边
for (int i = 0; i < mWaveCount; i++) {
// + (i * mWaveLength)
// + mOffset
//正弦曲线
mPath.quadTo((-mWaveLength * 3 / 4) + (i * mWaveLength) + mOffset, mCenterY + 60, (-mWaveLength / 2) + (i * mWaveLength) + mOffset, mCenterY);
mPath.quadTo((-mWaveLength / 4) + (i * mWaveLength) + mOffset, mCenterY - 60, i * mWaveLength + mOffset, mCenterY);
}
//填充矩形
mPath.lineTo(mScreenWidth, mScreenHeight);
mPath.lineTo(0, mScreenHeight);
mPath.close();
canvas.drawPath(mPath, mPaint);
}
//实现平移效果
@Override
public void onClick(View view) {
ValueAnimator animator = ValueAnimator.ofInt(0, mWaveLength);
animator.setDuration(1000);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setInterpolator(new LinearInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mOffset = (int) animation.getAnimatedValue();
postInvalidate();
}
});
animator.start();
}
}
复制代码
ps:写来只为了觉得好玩想自己感受一下,顺便做一下学习笔记。