Andorid绘制学习——贝塞尔曲线(二阶实战水波效果)

这个是横向滚动的,自己学着做了一个,但是还有很多细节没有达到,采用的值动画来实现;就是动画结束之后会有停顿一小会,希望各位高手帮忙看看,该怎么解决比较好,在这里谢谢了!





下面是我写的Demo:

public class BezierView extends View {
    private static final float POINTWIDTH = 2;

    private Paint mPaint;           // 画笔
    private Path mPath;             // 路径
    private int len = 800;          // 一个正余弦的宽度
    private int startX = 0;      // 绘制的起点
    private int maxHeight = 500;    // 最高点的坐标值
    private int minHeight = 300;    // 最低点的坐标值
    private int levHeight = 400;    // 水平线坐标值
    private int goBottomLength = 500;  //水平线到底部的距离

    private Point startPoint1,startPoint2,startPoint3,startPoint4,startPoint5,startPoint6;       // 开始点
    private Point endPoint1,endPoint2,endPoint3,endPoint4,endPoint5,endPoint6;                   // 结束点
    private Point assistPoint1,assistPoint2,assistPoint3,assistPoint4,assistPoint5,assistPoint6; // 动点

    private List<Point> startPointList = new ArrayList<>();
    private List<Point> endPointList = new ArrayList<>();
    private List<Point> assistPointList = new ArrayList<>();

    public BezierView(Context context) {
        this(context,null);
    }

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

    public BezierView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {

        mPaint = new Paint();
        mPath = new Path();

        // 抗锯齿
        mPaint.setAntiAlias(true);
        // 防抖动
        mPaint.setDither(true);
        mPaint.setColor(Color.BLACK);
        // 笔宽
        mPaint.setStrokeWidth(POINTWIDTH);
        // 空心
        mPaint.setStyle(Paint.Style.FILL);

    }


    private Point currentPoint;
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        startPointList.clear();
        endPointList.clear();
        assistPointList.clear();

        // 左边1贝塞尔的位置
        startPoint1 = new Point(startX, levHeight);
        endPoint1 = new Point(startX+ len/2, levHeight);
        assistPoint1 = new Point((startPoint1.x + endPoint1.x)/2, minHeight);

        startPointList.add(startPoint1);
        endPointList.add(endPoint1);
        assistPointList.add(assistPoint1);

        // 左边2贝塞尔的位置
        startPoint2 = new Point(endPointList.get(0).x, levHeight);
        endPoint2 = new Point(endPointList.get(0).x + len/2, levHeight);
        assistPoint2 = new Point((startPoint2.x + endPoint2.x)/2, maxHeight);

        startPointList.add(startPoint2);
        endPointList.add(endPoint2);
        assistPointList.add(assistPoint2);

        // 1
        startPoint3 = new Point(startX + len, levHeight);
        endPoint3 = new Point(startX+ len/2 + len, levHeight);
        assistPoint3 = new Point((startPoint3.x + endPoint3.x)/2, minHeight);

        startPointList.add(startPoint3);
        endPointList.add(endPoint3);
        assistPointList.add(assistPoint3);

        // 2
        startPoint4 = new Point(endPointList.get(0).x + len, levHeight);
        endPoint4 = new Point(endPointList.get(0).x + len/2 + len, levHeight);
        assistPoint4 = new Point((startPoint4.x + endPoint4.x)/2, maxHeight);

        startPointList.add(startPoint4);
        endPointList.add(endPoint4);
        assistPointList.add(assistPoint4);


        // 备份一个(达到连续的效果)
        startPoint5 = new Point(startX - len, levHeight);
        endPoint5 = new Point(startX+ len/2 - len, levHeight);
        assistPoint5 = new Point((startPoint5.x + endPoint5.x)/2, minHeight);

        startPointList.add(startPoint5);
        endPointList.add(endPoint5);
        assistPointList.add(assistPoint5);

        // 左边2贝塞尔的位置
        startPoint6 = new Point(startX-len/2, levHeight);
        endPoint6 = new Point(startX, levHeight);
        assistPoint6 = new Point((startPoint6.x + endPoint6.x)/2, maxHeight);

        startPointList.add(startPoint6);
        endPointList.add(endPoint6);
        assistPointList.add(assistPoint6);


        if (currentPoint == null) {
            currentPoint = new Point(startPoint1.x,levHeight);

            mPath.reset();
            // 起点
            mPath.moveTo(startPoint5.x, startPoint5.y);
            // 动点 和 终点
            mPath.quadTo(assistPoint5.x, assistPoint5.y, endPoint5.x, endPoint5.y);
            mPath.quadTo(assistPoint6.x, assistPoint6.y, endPoint6.x, endPoint6.y);
            mPath.quadTo(assistPoint1.x, assistPoint1.y, endPoint1.x, endPoint1.y);
            mPath.quadTo(assistPoint2.x, assistPoint2.y, endPoint2.x, endPoint2.y);
            mPath.quadTo(assistPoint3.x, assistPoint3.y, endPoint3.x, endPoint3.y);
            mPath.quadTo(assistPoint4.x, assistPoint4.y, endPoint4.x, endPoint4.y);
            mPath.lineTo(endPoint4.x,endPoint4.y+goBottomLength);
            mPath.lineTo(startPoint5.x,endPoint4.y+goBottomLength);
            mPath.lineTo(startPoint5.x,endPoint4.y);
            // 画路径
            canvas.drawPath(mPath, mPaint);
            startAnimation();
        } else {
            mPath.reset();
            // 起点
            mPath.moveTo(startPoint5.x, startPoint5.y);
            // 动点 和 终点
            mPath.quadTo(assistPoint5.x, assistPoint5.y, endPoint5.x, endPoint5.y);
            mPath.quadTo(assistPoint6.x, assistPoint6.y, endPoint6.x, endPoint6.y);
            mPath.quadTo(assistPoint1.x, assistPoint1.y, endPoint1.x, endPoint1.y);
            mPath.quadTo(assistPoint2.x, assistPoint2.y, endPoint2.x, endPoint2.y);
            mPath.quadTo(assistPoint3.x, assistPoint3.y, endPoint3.x, endPoint3.y);
            mPath.quadTo(assistPoint4.x, assistPoint4.y, endPoint4.x, endPoint4.y);
            mPath.lineTo(endPoint4.x,endPoint4.y+goBottomLength);
            mPath.lineTo(startPoint5.x,endPoint4.y+goBottomLength);
            mPath.lineTo(startPoint5.x,endPoint4.y);
            // 画路径
            canvas.drawPath(mPath, mPaint);
        }
    }


    private void startAnimation(){

        ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint1, startPoint3);

        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                    currentPoint = (Point) animation.getAnimatedValue();
                    startX = currentPoint.x;
                    invalidate();
            }
        });



        anim.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {

            }

            @Override
            public void onAnimationEnd(Animator animator) {
                currentPoint = null;
                startX = 0;
            }

            @Override
            public void onAnimationCancel(Animator animator) {

            }

            @Override
            public void onAnimationRepeat(Animator animator) {

            }
        });
        anim.setDuration(5000);
        anim.start();
    }


    public class PointEvaluator implements TypeEvaluator { // 值动画对象(重新赋值)

        @Override
        public Object evaluate(float fraction, Object startValue, Object endValue) {
            Point startPoint = (Point) startValue;
            Point endPoint = (Point) endValue;

            float x = startPoint.x + fraction * (endPoint.x - startPoint.x);
            float y = startPoint.y + fraction * (endPoint.y - startPoint.y);
            Point point = new Point((int)x, (int)y);
            return point;
        }

    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值