android 使用贝塞尔曲线实现“波浪”效果思路解析

来源:互联网 发布:ecmall多用户商城源码 编辑:程序博客网 时间:2024/06/05 09:00

首先对于贝塞尔曲线是什么我就不在叙述了。各位可能对于贝塞尔曲线已经不陌生了。
先看下效果图
这是一张静态图,实际上是动态的!!!
这里写图片描述
要实现“波浪”效果,先介绍一下二阶贝塞尔曲线的几个方法:
1:moveto 方法,就是设置起点,源码如下:

    public void moveTo(float x, float y) {        native_moveTo(mNativePath, x, y);    }

2:quadTo方法 x1,y1就是控制点的坐标; x2,y2就是终点的坐标,源码如下:

    public void quadTo(float x1, float y1, float x2, float y2) {        isSimplePath = false;        native_quadTo(mNativePath, x1, y1, x2, y2);    }

3:lineTo(x1,y1)方法我需要也别解释一下:就是连接起点和终点;不说的话,这个可能会坑到很多人。如下如所示,

这里写图片描述
一般来说 我们是起点到(x1,y1),然后是(x1,y1)到终点,如果是这样的话 就错了!
注意:lineTo绘制这两条线的先后顺序是:终点到(x1,y1),然后才是(x1,y1)到起点!!!!!!
同理两个LineTo的话就是:终点到(x2,y2)然后是(x2,y2)到(x1,y1),最后是(x1,y1)到终点。这个很重要!!!

好了 这是方法,然后看思路: 我们画两个波浪,然后一个占满屏幕,一个在屏幕外,然后每次更新width的值,height的值不变,然后循环。大体思路就是这样。
如下图:
这里写图片描述

到这里,我想应该就可以自己写出代码了。
附上整体代码:

package com.app.test.beisaierproject;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PixelFormat;import android.util.AttributeSet;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceView;/** * Created by ${liumegnqiang} on 2017/5/19. */public class MyBeiSaiErView extends SurfaceView implements SurfaceHolder.Callback{    private SurfaceHolder surfaceHolder;    public MyBeiSaiErView(Context context) {        super(context);    }    public MyBeiSaiErView(Context context, AttributeSet attrs) {        super(context, attrs);        surfaceHolder = getHolder();        surfaceHolder.setFormat(PixelFormat.TRANSLUCENT);        surfaceHolder.addCallback(this);    }    public MyBeiSaiErView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        new Thread(new MyThread()).start();    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {    }    public class MyThread extends Thread{        @Override        public void run() {            super.run();            /**             * 修改波浪的宽度             */            int measuredWidth = getMeasuredWidth();            /**             * 修改波浪的高度             */            int measuredHeight = getMeasuredHeight();            /**             * 总共平移的间隔             */            int totalWidth = 0;            while (true){                try {                    sleep(10);                } catch (InterruptedException e) {                    e.printStackTrace();                }                Canvas canvas = surfaceHolder.lockCanvas();                try {                    canvas.drawColor(Color.GRAY);                    Paint paint = new Paint();                    paint.setColor(Color.BLUE);                    paint.setAntiAlias(true);                    paint.setStyle(Paint.Style.FILL);                    Path path = new Path();                    path.moveTo(-measuredWidth + totalWidth,measuredHeight/2);                    path.quadTo(-measuredWidth * 3/ 4+ totalWidth,measuredHeight * 5/8,                            -measuredWidth/2+ totalWidth,measuredHeight/2);                    path.quadTo(-measuredWidth / 4+ totalWidth,measuredHeight*3/8,                            0+ totalWidth,measuredHeight/2);                    path.quadTo(measuredWidth / 4+ totalWidth,measuredHeight*5/8,                            measuredWidth/2+ totalWidth,measuredHeight/2);                    path.quadTo(measuredWidth * 3/ 4+ totalWidth,measuredHeight*3/8,                            measuredWidth+ totalWidth,measuredHeight/2);                    path.lineTo(measuredWidth+ totalWidth,measuredHeight);                    path.lineTo(-measuredWidth+ totalWidth,measuredHeight);                    path.close();                    canvas.drawPath(path,paint);                    totalWidth += 10;                    if(totalWidth > getMeasuredWidth()){                        totalWidth = 0;                    }                }catch (Exception e){                    e.printStackTrace();                }finally {                    surfaceHolder.unlockCanvasAndPost(canvas);                }            }        }    }}

这里我用的是surfaceview,因为在绘制动态图的方面,surfaceview比view性能是好的。当然你也可以加上双缓冲技术。

最后附上源码地址:http://download.csdn.net/detail/lmq121210/9846701
源码下载之后直接能用的。

原创粉丝点击