Path使用--二阶贝塞尔曲线实现水波效果

这里写图片描述
上面这个效果是使用Path绘制二阶贝塞尔曲线实现的;二阶贝塞尔曲线涉及到三个点,起始点、拐点、终点,而拐点有决定着曲线的形状;下面这张图大致展示了二阶贝塞尔曲线:
这里写图片描述

A点是起始点,C点是终点,B点是拐点,当然根据绘制的需求,B是变动的,绘制出来的曲线也就不一样,这里只是一个大致的示意图;那么只需调用path里面的相应方法,进行这几个点的设置一个简单的二阶贝塞尔曲线就可以实现了;
设置二阶贝塞尔曲线的方法:

//其中x,y的坐标代表图中曲线左边起点的位置坐标  也就是A点的位置
moveTo(float x,float y) 
//其中x1,y1的坐标就是控制点(拐点)的位置, 也就是B点的位置
//x2,y2的坐标就是曲线右边终点的位置坐标,也就是C点的位置
quadTo(float x1, float y1, float x2, float y2 ) 

还可调用下面这个方法进行设置,不过传入的参数和quadTo会有区别;

//这里的dx1、dy1、dx2、dy2都是相对坐标
rQuadTo(float dx1, float dy1, float dx2, float dy2);

水波效果代码:

public class WaterView extends View{
    private Paint mPaint;
    private Path mPath;
    //波长的长度
    private int waterLenght=100;
    private int dx;
    public WaterView(Context context) {
        this(context,null);
    }

    public WaterView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public WaterView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint=new Paint();
        mPaint.setColor(Color.BLUE);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);

        mPath=new Path();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int originY=800;
        //重置path
        mPath.reset();
        int halfWaterLenght=waterLenght/2;
        //起点
        mPath.moveTo(-waterLenght+dx,originY);
        //屏幕的宽度李放多少个波长
        for (int i=-waterLenght;i<getWidth()+waterLenght;i+=waterLenght){
            //相对绘制二阶贝塞尔曲线(相对于自己的起点--也就是上一个曲线的终点  的距离dx1)
            mPath.rQuadTo(halfWaterLenght/2,-30,halfWaterLenght,0);
            mPath.rQuadTo(halfWaterLenght/2,30,halfWaterLenght,0);
        }
        //颜色填充
        //画一个封闭的空间
        mPath.lineTo(getWidth(),getHeight());
        mPath.lineTo(0,getHeight());
        //闭合path
        mPath.close();
        //绘制到画布上
        canvas.drawPath(mPath,mPaint);
    }

    /**
     * 开启动画
     */
    public void startAnimation(){
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, waterLenght);
        valueAnimator.setDuration(700);
        //设置插值器
        valueAnimator.setInterpolator(new LinearInterpolator());
        //设置无线循环
        valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                dx= (int) value;
                postInvalidate();
            }
        });
        valueAnimator.start();
    }
}
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        WaterView waterView = (WaterView) findViewById(R.id.water_view);
        waterView.startAnimation();
    }
}

这样效果就实现了,也是刚接触二阶贝塞尔曲线,写的比较简单,有写的不对的地方欢迎交流。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值