android使用贝塞尔曲线,Android贝塞尔曲线初步学习第一课

贝塞尔曲线有一阶、二阶、三阶、N阶

一阶就是一条直线,有起点终点,没有控制点,对应方法就是

canvas.drawLine(float startX, float startY, float stopX, float stopY, @NonNull Paint paint) ;

二阶为曲线,有起点终点,一个控制点,对应方法就是

path.quadTo(float x1, float y1, float x2, float y2);

其中x1、y1为控制点坐标, x2、y2为终点坐标,效果如下:

3a0bb1987f80e8fdb5036f0dfc09f237.png

三阶由俩个控制点控制,对应方法就是

path.cubicTo(float x1, float y1, float x2, float y2, float x3, float y3);

其中x1、y1、x2、y2为两个控制点坐标, x3、y3为终点坐标,效果如下:

3e8951c63778a69dc9a2d1c7ab2a3560.png

做一个demo巩固一下用法:

a766589674dfaf217c6f97d1bb42ff34.gif

新建一个SecondBezierView继承View,重写构造方法、初始化画笔、固定起点和终点的坐标,重写onTouchEvent()方法获取当前点击的点为控制点:

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_MOVE:

mControlX = event.getX();

mControlY = event.getY();

invalidate();

break;

}

return true;

}

在onDraw()方法中画点、画连接线、画文本、画二阶贝塞尔曲线

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.drawCircle(mStartX, mStartY, 8, mLinePaint);

canvas.drawText("起点", mStartX, mStartY, mLinePaint);

canvas.drawCircle(mEndX, mEndY, 8, mLinePaint);

canvas.drawText("终点", mEndX, mEndY, mLinePaint);

canvas.drawCircle(mControlX, mControlY, 8, mLinePaint);

canvas.drawText("控制点", mControlX, mControlY, mLinePaint);

canvas.drawLine(mStartX, mStartY, mControlX, mControlY, mLinePaint);

canvas.drawLine(mEndX, mEndY, mControlX, mControlY, mLinePaint);

mBezierPath.reset();//因为不断重绘,path的路径也要重置,不然页面上会显示很多条线

mBezierPath.moveTo(mStartX, mStartY);//移至起点

mBezierPath.quadTo(mControlX, mControlY, mEndX, mEndY);//二阶贝塞尔曲线,传入控制点和终点坐标

canvas.drawPath(mBezierPath, mBezierPaint);

}

最后添加一个回弹的动画,用的是OvershootInterpolator插值器,在onTouchEvent的MotionEvent.ACTION_UP中:

case MotionEvent.ACTION_UP:

ValueAnimator animX = ValueAnimator.ofFloat(mControlX, getWidth() / 2);

animX.setDuration(500);

animX.setInterpolator(new OvershootInterpolator());

animX.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

mControlX = (float) animation.getAnimatedValue();

invalidate();

}

});

animX.start();

ValueAnimator animY = ValueAnimator.ofFloat(mControlY, getHeight() / 2);

animY.setDuration(500);

animY.setInterpolator(new OvershootInterpolator());

animY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

mControlY = (float) animation.getAnimatedValue();

invalidate();

}

});

animY.start();

break;

再来个三阶的

7a7fee32b7afc9a18eb76beebc2b269d.gif

主要就是用到了多点触控:

private boolean mIsSecondPoint = false;

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction() & MotionEvent.ACTION_MASK) {//多点触控

case MotionEvent.ACTION_POINTER_DOWN:

mIsSecondPoint = true;

break;

case MotionEvent.ACTION_POINTER_UP:

mIsSecondPoint = false;

break;

case MotionEvent.ACTION_MOVE:

mControlX1 = event.getX(0);//获取控制点1的横纵坐标

mControlY1 = event.getY(0);

if (mIsSecondPoint) {

mControlX2 = event.getX(1);//获取控制点2的横纵坐标

mControlY2 = event.getY(1);

}

invalidate();

break;

}

return true;

}

然后再onDraw()中画三阶贝塞尔曲线

mBezierPath.reset();

mBezierPath.moveTo(mStartX, mStartY);

mBezierPath.cubicTo(mControlX1, mControlY1, mControlX2, mControlY2, mEndX, mEndY);

canvas.drawPath(mBezierPath, mBezierPaint);

大功告成,打完收工。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值