Android 图片波浪动画,Android水纹波浪动画

先上效果图

0818b9ca8b590ca3270a3433284dd417.png

实现原理

0818b9ca8b590ca3270a3433284dd417.png

总体思路如下:

1、将波浪效果绘制成一个静态的图片

2、将图片往水平和竖直方向,同时并按一定的速率移动

在实现的过程中,主要利用正弦函数 y=Asin(ωx+φ)+h ,设置四个参数(振幅、高度、波长和偏移)来实现波浪的动画效果。

Wate Level(水位):波浪静止时水面距离底部的高度

Amplitude(振幅):波浪垂直振动时偏离水面的最大距离

Wave Length(波长):一个完整的波浪的水平长度

Wave Shift(偏移):波浪相对于初始位置的水平偏移

代码模块

一、绘制波浪图片

mDefaultWaterLevel = getHeight() * DEFAULT_WATER_LEVEL_RATIO;

float mDefaultWaveLength = getWidth();

float mDefaultAmplitude = getHeight() * DEFAULT_AMPLITUDE_RATIO;

double mDefaultAngularFrequency = 2.0f * Math.PI / DEFAULT_WAVE_LENGTH_RATIO / getWidth();

Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas(bitmap);

Paint wavePaint = new Paint();

wavePaint.setStrokeWidth(2);

wavePaint.setAntiAlias(true);

// y=Asin(ωx+φ)+h 正弦曲线

final int endX = getWidth() + 1;

final int endY = getHeight() + 1;

float[] waveY = new float[endX];

wavePaint.setColor(Color.parseColor("#71CFFF")); //后面的波浪

for (int beginX = 0; beginX < endX; beginX++) {

double wx = beginX * mDefaultAngularFrequency;

float beginY = (float) (mDefaultWaterLevel + mDefaultAmplitude * Math.sin(wx));

canvas.drawLine(beginX, beginY, beginX, endY, wavePaint);

waveY[beginX] = beginY;

}

wavePaint.setColor(Color.parseColor("#37BFFF")); //前面的波浪

final int wave2Shift = (int) (mDefaultWaveLength / 4);

for (int beginX = 0; beginX < endX; beginX++) {

canvas.drawLine(beginX, waveY[(beginX + wave2Shift) % endX], beginX, endY, wavePaint);

}

//将波浪曲线的Bitmap变量赋值给画笔

mWaveShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);

mViewPaint.setShader(mWaveShader);

二、重写onDraw

@Override

protected void onDraw(Canvas canvas) {

if (mWaveShader != null) {

if (mViewPaint.getShader() == null) {

mViewPaint.setShader(mWaveShader);

}

//根据水位的高度定义 mShaderMatrix 的规模

mShaderMatrix.setScale(1, 1, 0, mDefaultWaterLevel);

//根据水位的高度和偏移定义 mShaderMatrix 在起始时的位置

mShaderMatrix.postTranslate(mWaveShiftRatio * getWidth(), (DEFAULT_WATER_LEVEL_RATIO - mWaterLevelRatio) * getHeight());

//将 mShaderMatrix 设置给波浪

mWaveShader.setLocalMatrix(mShaderMatrix);

canvas.drawRect(0, 0, getWidth(), getHeight(), mViewPaint);

} else {

mViewPaint.setShader(null);

}

}

三、定义横纵的动画序列

List mAnimators = new ArrayList();

ObjectAnimator waveShiftAnim = ObjectAnimator.ofFloat(mWaveView, "waveShiftRatio", 0f, 1f); //水平方向循环

waveShiftAnim.setRepeatCount(ValueAnimator.INFINITE);

waveShiftAnim.setDuration(2000);

waveShiftAnim.setInterpolator(new LinearInterpolator());

mAnimators.add(waveShiftAnim);

ObjectAnimator waterLevelAnim = ObjectAnimator.ofFloat(mWaveView, "waterLevelRatio", mCurrentHeight, height); //竖直方向从0%到x%

waterLevelAnim.setDuration(6000);

waterLevelAnim.setInterpolator(new DecelerateInterpolator());

mAnimators.add(waterLevelAnim);

mWaveView.invalidate(); //刷新动画

AnimatorSet mAnimatorSet = new AnimatorSet();

mAnimatorSet.playTogether(mAnimators);

mAnimatorSet.start();

开源分享

转载请注明出处,谢谢!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值