三个点 pre ber block span 初始化 move 理解
最近突然手痒就想搞个贝塞尔曲线做个水波纹效果玩玩,终于功夫不负有心人最后实现了想要的效果,一起来看下吧:
绘制贝塞尔曲线我们必须要知道三个点:起点、控制点、终点;有了这三个点我们就可以绘制一段简单二阶贝塞尔曲线。从图中我们可以看出 起点 控制点p1 x1 这三个点绘制了一段曲线,也就是通过path.quadTo()函数添加一个曲线路径。
???假设我们需要绘制一个周期的sin曲线,那么我们就只需要知道起点、一个周期的宽度、振幅;就可以绘制一个sin曲线了。
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- //获取view的宽度
- width = getViewSize(800, widthMeasureSpec);
- //获取view的高度
- height = getViewSize(400, heightMeasureSpec);
- //获取起点坐标
- startPoint = new Point(0, height / 2);
- }
首先肯定是要获取到画布的大小才能确定好起点的坐标,有了起点坐标就可以开始绘制我们的曲线了
- /*sin曲线 1/4个周期的宽度*/
- private int cycle = 200;
- /*sin曲线振幅的高度*/
- private int waveHeight = 200;
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- path.moveTo(startPoint.x, startPoint.y);
- int j = 1;
- //循环绘制正弦曲线 循环一次半个周期
- for (int i = 1; i <= 8; i++) {
- if (i % 2 == 0) {
- //波峰
- path.quadTo(startPoint.x + (cycle * j), startPoint.y + waveHeight,
- startPoint.x + (cycle * 2) * i, startPoint.y);
- } else {
- //波谷
- path.quadTo(startPoint.x + (cycle * j), startPoint.y - waveHeight,
- startPoint.x + (cycle * 2) * i, startPoint.y);
- }
- j += 2;
- }
- //绘制封闭的曲线
- path.lineTo(width, height);//右下角
- path.lineTo(startPoint.x, height);//左下角
- path.lineTo(startPoint.x, startPoint.y);//起点
- path.close();
- canvas.drawPath(path, paint);
- }
- //初始化的时候将起点移至屏幕外一个周期
- startPoint = new Point( - cycle * 4, height / 2);
- //继续在ondraw()函数最后追加平移代码
- //判断是不是平移完了一个周期
- if (startPoint.x + 40 >= 0) {
- //满了一个周期则恢复默认起点继续平移
- startPoint.x = -cycle * 4;
- }
- //每次波形的平移量 40
- startPoint.x += 40;
- postInvalidateDelayed(150);
- path.reset();
- @Override protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- //裁剪画布为圆形
- Path circlePath = new Path();
- circlePath.addCircle(width / 2, height / 2, width / 2, Path.Direction.CW);
- canvas.clipPath(circlePath);
- canvas.drawPaint(circlePaint);
- canvas.drawCircle(width / 2, height / 2, width / 2, circlePaint);
- //以下操作都是在这个圆形画布中操作
- //根据进度改变起点坐标的y值
- startPoint.y = (int)(height - (progress / 100.0 * height));
- //起点
- path.moveTo(startPoint.x, startPoint.y);
- int j = 1;
- //循环绘制正弦曲线 循环一次半个周期
- for (int i = 1; i <= 8; i++) {
- if (i % 2 == 0) {
- path.quadTo(startPoint.x + (cycle * j), startPoint.y + waveHeight, startPoint.x + (cycle * 2) * i, startPoint.y);
- } else {
- path.quadTo(startPoint.x + (cycle * j), startPoint.y - waveHeight, startPoint.x + (cycle * 2) * i, startPoint.y);
- }
- j += 2;
- }
- //绘制封闭的曲线
- path.lineTo(width, height); //右下角
- path.lineTo(startPoint.x, height); //左下角
- path.lineTo(startPoint.x, startPoint.y); //起点
- path.close();
- canvas.drawPath(path, paint);
- drawText(canvas, textPaint, progress + "%");
- //判断是不是平移完了一个周期
- if (startPoint.x + 40 >= 0) {
- //满了一个周期则恢复默认起点继续平移
- startPoint.x = -cycle * 4;
- }
- //每次波形的平移量 40
- startPoint.x += 40;
- if (autoIncrement) {
- if (progress >= 100) {
- progress = 0;
- } else {
- progress++;
- }
- }
- postInvalidateDelayed(150);
- path.reset();
- }
Android自定义View——实现水波纹效果类似剩余流量球
来源: http://www.bubuko.com/infodetail-2294788.html