Android 贝塞尔曲线菜鸟起步
来源:互联网 发布:粑粑是什么网络意思 编辑:程序博客网 时间:2024/05/02 05:42
一、基本认识
贝塞尔曲线(Bezier curve)是应用于二维图形程序的数学曲线。
一阶贝塞尔曲线:
是一条直线,只有起点和终点,实现方法:
canvas.drawLine(float startX, float startY, float stopX, float stopY, @NonNull Paint paint) ;
二阶贝塞尔曲线:
有起点和终点、一个控制点的曲线,实现方法:
path.moveTo(startX, startY); //移至起点 path.quadTo(controlX, controlY, endX, endY); //二阶曲线,参数是控制点和终点坐标
三阶贝塞尔曲线:
有起点和终点、两个控制点的曲线,实现方法:
path.moveTo(startX, startY);path.cubicTo(controlX1, controlY1, controlX2, controlY2, endX, endY); //三阶曲线,参数是控制点1、控制点2和终点坐标
展示一张效果图:
以下我将会实现图中的效果。
二、二阶贝塞尔曲线View
自定义一个SecondBezierView继承自View。
首先,在构造方法中,初始化我们的画笔和其他变量:
public SecondBezierView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mLinePaint = new Paint(); mLinePaint.setAntiAlias(true); mLinePaint.setDither(true); mLinePaint.setColor(Color.parseColor("#454545")); mBezierPaint = new Paint(); mBezierPaint.setAntiAlias(true); mBezierPaint.setDither(true); mBezierPaint.setColor(Color.RED); mBezierPaint.setStyle(Paint.Style.STROKE); mBezierPaint.setStrokeWidth(3); mBezierPath = new Path(); }
然后,在onMeasure方法中明确我们贝塞尔曲线的起始点坐标、终点坐标和控制点坐标,这里让它处在居中的位置:
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mStartX = 50; mStartY = getMeasuredHeight() / 2; mEndX = getMeasuredWidth() - 50; mEndY = getMeasuredHeight() / 2; mControlX = (mStartX + mEndX) / 2; mControlY = (mStartY + mEndY) / 2;}
接下来,就该在onDraw方法中绘制我们的曲线了:
@Overrideprotected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawCircle(mStartX, mStartY, 5, mLinePaint); canvas.drawText("起点", mStartX - 10, mStartY - 10, mLinePaint); canvas.drawCircle(mEndX, mEndY, 5, mLinePaint); canvas.drawText("终点", mEndX - 10, mEndY - 10, mLinePaint); canvas.drawCircle(mControlX, mControlY, 5, mLinePaint); canvas.drawText("控制点", mControlX - 10, mControlY -10 , 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);}
最后,重写onTouchEvent,让控制点随着我们手指的移动而移动,并在松开手指时(ACTION_UP),让曲线以动画的形式重置:
@Overridepublic boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_DOWN: mControlX = event.getX(); mControlY = event.getY(); invalidate(); break; case MotionEvent.ACTION_UP: ValueAnimator animX = ValueAnimator.ofFloat(mControlX, (mStartX + mEndX) / 2); animX.setDuration(400); 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, (mStartY + mEndY) / 2); animY.setDuration(400); animY.setInterpolator(new OvershootInterpolator()); animY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mControlY = (float) animation.getAnimatedValue(); invalidate(); } }); animY.start(); break; } return true;}
三、三阶贝塞尔曲线View
具体实现和二阶贝塞尔曲线相似,只不过这里有两个控制点。
在绘制的时候,需要调用三阶的方法:
mBezierPath.reset();mBezierPath.moveTo(mStartX, mStartY);mBezierPath.cubicTo(mControlX1, mControlY1, mControlX2, mControlY2, mEndX, mEndY); //三阶贝塞尔曲线,参数是控制点1、控制点2和终点坐标canvas.drawPath(mBezierPath, mBezierPaint);
而对于控制点的操纵,这里用到了多点触控:
@Overridepublic 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: case MotionEvent.ACTION_DOWN: mControlX1 = event.getX(0); mControlY1 = event.getY(0); if (mIsSecondPoint) { mControlX2 = event.getX(1); mControlY2 = event.getY(1); } invalidate(); break; ......}
具体请参见我的代码:https://github.com/Yiiip/Bezier
在实际的运用中,贝塞尔曲线可以让你的应用或者控件拥有非常漂亮的特效,和动画结合效果会非常理想。
1 0
- Android 贝塞尔曲线菜鸟起步
- 菜鸟起步
- 菜鸟的起步
- 菜鸟起步的艰难
- webpack的菜鸟起步
- 前端 html 菜鸟起步
- Android贝塞尔曲线——曲线进阶
- Android-贝塞尔曲线应用
- Android-贝塞尔曲线
- Android 实现贝塞尔曲线
- Android-贝塞尔曲线
- Android 贝塞尔曲线
- Android-贝塞尔曲线
- Android 动画-贝塞尔曲线
- Android 贝塞尔曲线解析
- Android 贝塞尔曲线解析
- Android 贝塞尔曲线解析
- Android-贝塞尔曲线
- 当起大量爬虫,爬同一个网页,运行到后面会大量出现错误
- 正则表示IP
- 使用轻量级Spring @Scheduled注解执行定时任务
- springMVC 使用 swagger
- 小程序怎么突然不火了?
- Android 贝塞尔曲线菜鸟起步
- Ubuntu 16.04.1 LTS配置Python3.6.0
- PlantUml
- Vulkan编程指南翻译 第五章 展现 第3节 全屏画幕
- 支持BLE 4.2的蓝牙SOC芯片与手机app之间的数据包长度(MTU)
- Android中消息机制初探(创建一个可以接收消息的子线程)
- 获取AndroidAPP当前进程的名称
- Codeforces Round #402 (Div. 2) D. String Game(二分)
- 使用SharedPreferences记录应用使用次数,判断是否加载导航页