相信很多人都聽說過貝塞爾曲線,但是作為Android程序員的我們可能也沒有具體的使用過貝塞爾曲線!好吧!是我之前沒用過.......
關于貝塞爾曲線的介紹我就不多羅嗦了晚上有很多的文章,這里我給出一篇供大家參考:
http://blog.csdn.net/cdnight/article/details/48468653
這里給出一個github的開源庫,大家可以看看貝塞爾曲線的效果:
https://github.com/venshine/BezierMaker
挺好玩的,總的來說貝塞爾曲線最低為2階且理論上無上限。
本篇文章通過一個簡單的例子,來初步探索一下貝塞爾曲線,廢話不多說我們開始。
獻上效果圖:
1.gif
是不是挺有意思的呢?
實現思路:
1、畫一條路徑
通過Path工具類
2、獲取手指移動的點的坐標,并將該點作為貝塞爾曲線的控制點
重寫onTouchEvent()方法
3、實現回彈動畫
自定義一個Animtion,當然也可以不自定義
具體代碼實現
設置畫筆:
private void init() {
pointA = new Point(100, 300);
pointB = new Point(500, 300);
pointCenter = new Point(200, 300);
mPaint = new Paint();
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(10);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setAntiAlias(true);
}
畫路徑:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
bezierPath.reset();
bezierPath.moveTo(pointA.x, pointA.y);
//quadTo方法用于畫貝塞爾曲線
bezierPath.quadTo(pointCenter.x, pointCenter.y, pointB.x, pointB.y);
//閉合path
// bezierPath.close();
canvas.drawPath(bezierPath, mPaint);
}
這里要注意的是path的quadTo(int cx,int cy,int px,int py)方法,這個方法就是用于畫貝塞爾曲線的。參數cx、cy分別表示控制點的x、y坐標,px、py分別表示結束點的x、y坐標。要注意rQuadTo()方法的區別
重寫onTouchEvent方法:
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
int x = 0;
int y = 0;
switch (action) {
case MotionEvent.ACTION_DOWN: {
}
case MotionEvent.ACTION_MOVE: {
x = (int) event.getX();
y = (int) event.getY();
pointCenter.set(x, y);
}
break;
case MotionEvent.ACTION_UP: {
x = (int) event.getX();
y = (int) event.getY();
startCallbackAnim(x, y);
}
break;
}
invalidate();
return true;
}
最后寫一個動畫:
private void startCallbackAnim(int x, int y) {
ResetAnimation animation = new ResetAnimation(x, y);
animation.setDuration(300);
this.startAnimation(animation);
}
/**
* 自定義一個會彈動畫
*/
class ResetAnimation extends Animation {
int orginX;
int orginY;
public ResetAnimation(int x, int y) {
orginX = x;
orginY = y;
}
/**
* 這個方法是為一個自定義動畫需要重寫的方法
*
* @param interpolatedTime 動畫時間0~1.0
* @param t
*/
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
int newX = (int) ((orginX - 200) * (1 - interpolatedTime) + 200);
int newY = (int) ((orginY - 300) * (1 - interpolatedTime) + 300);
pointCenter.set(newX, newY);
invalidate();
super.applyTransformation(interpolatedTime, t);
}
}
代碼很簡單大家可以自己去實現以下!