先看效果:
![](https://img.haomeiwen.com/i19865651/93d083034198ca38.gif)
实现的原理图如下:
![](https://img.haomeiwen.com/i19865651/21f5c6d49e3c05cd.png)
如上图所示,其实这个图形的实现原理也很简单。就是在屏幕竖直方向上画上N条直线,只要直线足够密集,就可以形成一个填充的视觉效果的图形。
如上原理图所示,代码将分三个步骤计算实现:
(1)通过获取到的屏幕宽度getWidth()用公式计算出三角函数的周期 T= (2 * pi)/getWidth()
计算周期T 的代码如下:
mCycle = (float) (2 * Math.PI / totalWidth); // 根据宽度计算三角函数周期
其中mCycle 是周期T,totalWidth是获取到的屏幕宽度。
(2)根据算出的周期T ,用公式 y = sin(T * x)循环计算出媒体条直线顶点坐标的y值
直线顶点的所有y值计算如下:
for (int x = 0 ; x < totalWidth ; x ++){ // 利用三角函数生成数组
myPoint[x] = (float) (100 * Math.sin(mCycle * x)); // Y = Asin(mCycle * X + phase)
}
所有 y 值循环计算后保存在数组myPoint中,100 振幅是振幅。
(3)获取到所有y值后,即可在屏幕上绘制所有直线,然后将头部的若干直线移到波形尾部,再重绘。
将数组第一个数移到数组尾部的方法如下:
private void turnArray(){ // 数组旋转
float team = myPoint[0];
for (int i = 1 ; i < myPoint.length ; i ++){
myPoint[i - 1] = myPoint[i];
}
myPoint[myPoint.length - 1] = team;
}
图形绘制的代码如下:
for (int i = 0 ; i < totalWidth ; i ++){ // 循环竖直方向的直线
canvas.drawLine(i , myPoint[i] + totalHeight / 2 , i , totalHeight , mPaint);
}
setOffSet(5); //旋转数组
invalidate(); //死循环重绘,可以设一个变量使之停止
如上代码所示,循环绘制完所有直线后,再将数组旋转。然后调用 invalidate();方法重绘,如此反复循环,即可实现无限动态效果。
源码:(EthanLee-88/SinWaterRippleView: 利用三角函数Sin自定义View,实现水波纹效果。 (github.com)
)
网友评论