Android贝塞尔曲线-水波篇

在做自定义view时,很多时候会用到贝塞尔曲线这个东西去实现一些效果,像以前写的那个仿直播点赞动画的实现就是用到了贝塞尔曲线,这次说的水波也会用到贝塞尔曲线这个东西。

Android贝塞尔曲线api

首先看下贝塞尔曲线公式:

一阶

这里写图片描述

二阶

这里写图片描述

其中p0是起点,p1是控制点,p2是终点

三阶

这里写图片描述

其中p0是起点,p1,p2是控制点,p3是终点

Android做好了相应的api,分别如下:

二阶:

quadTo(float x1, float y1, float x2, float y2)
rQuadTo(float dx1, float dy1, float dx2, float dy2)

三阶:

cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
rCubicTo(float x1, float y1, float x2, float y2,float x3, float y3)

因为这里主要用到了二阶杯赛曲线,所以主要讲一下这个

api解释及运用

quadTo(float x1, float y1, float x2, float y2)

quadTo是参数解释:
x1:控制点x坐标
y1:在控制点y坐标
x2:终点x坐标
y2:终点y坐标

先看段例子:

 pathRed.moveTo(getWidth()/2-100,getHeight()/2);
 pathRed.quadTo(getWidth()/2-50,getHeight()/2-50,getWidth()/2,getHeight()/2);
 pathRed.quadTo(getWidth()/2+50,getHeight()/2+50,getWidth()/2+100,getHeight()/2);
 canvas.drawPath(pathRed,paintRed);

得到的图形如下

这里写图片描述

这里解释一点:当连续调用quadTo的时候上一个quadTo的终点即为写下一个quadTo的起点

rQuadTo(float dx1, float dy1, float dx2, float dy2)

dx1:控制点相对起点的x位移
dy1:控制点相对起点的y位移
dx2:终点相对起点的x位移
dy2:终点相对起点的y位移

把上面那段代码改改即为如下所示:

 pathRed.moveTo(getWidth()/2-100,getHeight()/2);
 pathRed.rQuadTo(50,-50,100,0);
 pathRed.rQuadTo(50,50,100,0);

图就不上了,也是同样的效果

水波实现

首先先做出来一个静态的水波,如下图所示:

这里写图片描述

再看下代码

 public void drawMyPath(int wavehigh,Path path){
        path.reset();
        path.moveTo(-waveRed,high/2);
        for (int i = -waveRed; i < getWidth()+waveRed; i+=waveRed) {
            path.rQuadTo(waveRed/4,-wavehigh,waveRed/2,0);
            path.rQuadTo(waveRed/4,wavehigh,waveRed/2,0);

        }
        path.lineTo(getWidth(),getHeight());
        path.lineTo(0,getHeight());
        path.close();
    }

wavehigh是定义的水波高度,waveRed是指水波长度,我们要做的就是在屏幕左右各预留一个波长以便后续的移动。

接下来要做的就是怎么能让波形移动了,因为已经预留了两边的波长所以只要让path的起点慢慢移动一个波长就形成了视觉上的水波效果

代码如下:

 public void drawMyPath(int wavehigh,Path path,int y){
        path.reset();
        path.moveTo(-waveRed+y+dx,high/2);
        for (int i = -waveRed; i < getWidth()+waveRed; i+=waveRed) {
            path.rQuadTo(waveRed/4,-wavehigh,waveRed/2,0);
            path.rQuadTo(waveRed/4,wavehigh,waveRed/2,0);

        }
        path.lineTo(getWidth(),getHeight());
        path.lineTo(0,getHeight());
        path.close();
    }
 public void startAnimation(){
        ValueAnimator animator=ValueAnimator.ofInt(0,waveRed);
        animator.setDuration(2000);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                dx= (int) valueAnimator.getAnimatedValue();
                if (dx == waveRed) {
                    dx=0;

                }

                postInvalidate();
            }
        });
        animator.start();



    }

然后在外部调用一下让动画开始执行就行,看下具体效果:

这里写图片描述

那这时我想做多条水波怎么办呢,还记得前面drawMyPath方法里的y参数吗,它就是控制起点位置,然后再改变一下水波高度就行了

这里写图片描述

我是随便设置的,可能不太明显,能看出来就行

好了差不多说完了,下一篇说下怎么做出圆形水波view

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值