android 水波纹+小船漂浮实现
2020-01-16 本文已影响0人
Levipeng
如图
wave.gif
实现思路贝塞尔曲线+属性动画
1:先画曲线
曲线类似正弦函数曲线,所以也就是画贝塞尔曲线。如何做到流动的效果,让贝塞尔曲线移动起来。不断的改变起始点的位置,重新绘制,也就能实现流动水波纹效果了。然后旋转平移和旋转矩阵实现浮动的小船。
如图
QQ图片20200116153239.jpg
不断的改变A的位置。
代码如下
//一个波长的长度
private final int INT_WAVE_LENGTH = 1000;
private Paint mPaint;
private Path mPath;
private Integer move = 0;
private Bitmap mBitMap;
private Matrix mMatrix;
private PathMeasure mPathMeasure;
private void init() {
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setColor(Color.RED);
mPath = new Path();
mMatrix = new Matrix();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
mBitMap = BitmapFactory.decodeResource(getResources(), R.drawable.timg,options);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPath.reset();
int orginy = getHeight() / 2;
mPath.moveTo(-INT_WAVE_LENGTH + move, orginy);
int half = INT_WAVE_LENGTH / 2;
for (int i = -INT_WAVE_LENGTH; i < getWidth() + INT_WAVE_LENGTH; i += INT_WAVE_LENGTH) {
mPath.rQuadTo(half / 2, 80, half, 0);
mPath.rQuadTo(half / 2, -80, half, 0);
}
mPath.lineTo(getWidth(), getHeight());
mPath.lineTo(0, getHeight());
mPath.close();
canvas.drawPath(mPath, mPaint);
mPathMeasure = new PathMeasure(mPath, false);
float length = mPathMeasure.getLength();
mMatrix.reset();
mPathMeasure.getMatrix(getWidth()+500-move, mMatrix, PathMeasure.TANGENT_MATRIX_FLAG | PathMeasure.POSITION_MATRIX_FLAG);
mMatrix.preTranslate(- mBitMap.getWidth() / 2, - mBitMap.getHeight());
canvas.drawBitmap(mBitMap, mMatrix, mPaint);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
startAnimation();
}
public void startAnimation() {
ValueAnimator valueAnimator = ValueAnimator.ofInt(0, INT_WAVE_LENGTH);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.setDuration(2000);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
move = (Integer) animation.getAnimatedValue();
postInvalidate();
}
});
valueAnimator.start();
}