参数
- Wate Level(水位)
波浪静止时水面距离底部的高度
- Amplitude(振幅)
波浪垂直振动时偏离水面的最大距离
- Wave Length(波长)
一个完整的波浪的水平长度
- Wave Shift(偏移)
波浪相对于初始位置的水平偏移
实现方法
- 绘制一个波形图,填充到View里,移动波形图
/**
* Create the shader with default waves which repeat horizontally, and clamp vertically
*/
private void createShader() {
mDefaultAngularFrequency = 2.0f * Math.PI / DEFAULT_WAVE_LENGTH_RATIO / getWidth();
mDefaultAmplitude = getHeight() * DEFAULT_AMPLITUDE_RATIO;
mDefaultWaterLevel = getHeight() * DEFAULT_WATER_LEVEL_RATIO;
mDefaultWaveLength = getWidth();
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint wavePaint = new Paint();
wavePaint.setStrokeWidth(1);
wavePaint.setAntiAlias(true);
// Draw default waves into the bitmap
// y=Asin(ωx+φ)+h
final int endX = getWidth() + 1;
final int endY = getHeight() + 1;
float[] waveY = new float[endX];
wavePaint.setColor(mBehindWaveColor);
wavePaint.setAlpha(150);
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(mFrontWaveColor);
wavePaint.setAlpha(255);
final int wave2Shift = (int) (mDefaultWaveLength / 4);
for (int beginX = 0; beginX < endX; beginX++) {
canvas.drawLine(beginX, waveY[(beginX + wave2Shift) % endX], beginX, endY, wavePaint);
}
// use the bitamp to create the shader
mWaveShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);
mViewPaint.setShader(mWaveShader);
}
- 调整Bitmap的大小并填充到WaveView
有了初始波形,当WaveView的属性改变时,只需要对初始波形进行相应的拉伸/压缩和位移就可以得到用户想要的波形。
动画
private void initAnimation() {
List<Animator> animators = new ArrayList<>();
// horizontal animation.
// wave waves infinitely.
ObjectAnimator waveShiftAnim = ObjectAnimator.ofFloat(
mWaveView, "waveShiftRatio", 0f, 1f);
waveShiftAnim.setRepeatCount(ValueAnimator.INFINITE);
waveShiftAnim.setDuration(1000);
waveShiftAnim.setInterpolator(new LinearInterpolator());
animators.add(waveShiftAnim);
// vertical animation.
// water level increases from 0 to center of WaveView
ObjectAnimator waterLevelAnim = ObjectAnimator.ofFloat(
mWaveView, "waterLevelRatio", 0f, 0.3f);
waterLevelAnim.setDuration(500);
waterLevelAnim.setInterpolator(new DecelerateInterpolator());
animators.add(waterLevelAnim);
// amplitude animation.
// wave grows big then grows small, repeatedly
ObjectAnimator amplitudeAnim = ObjectAnimator.ofFloat(
mWaveView, "amplitudeRatio", 0.0001f, 0.1f);
amplitudeAnim.setRepeatCount(ValueAnimator.INFINITE);
amplitudeAnim.setRepeatMode(ValueAnimator.REVERSE);
amplitudeAnim.setDuration(15000);
amplitudeAnim.setInterpolator(new LinearInterpolator());
animators.add(amplitudeAnim);
mAnimatorSet = new AnimatorSet();
mAnimatorSet.playTogether(animators);
}