前几天学了Python相关的知识,然后昨天看了一下Skype的Loading非常好看,就想要自己做一个看看.然后网上搜集了一些资料. 需要用bezier去画圆.画了圆后慢慢的拓展右边的点的位置逐渐形成了圆角.
需要四次贝塞尔画一个圆,用贝塞尔画圆需要一个因子.该因子决定了圆的程度,根据公式可以知道圆的因子:
0.551915024494f
用该因子 * 半径 可以得到贝塞尔的起始点和终点.
以圆为中心,分为四个点. 左右和上下, 这四个点就是贝塞尔的中点.
这样就绘制了一次贝塞尔.
mPath.moveTo(p0.x,p0.y);
mPath.cubicTo(p1.x, p1.y, p2.x, p2.y, p3.x,p3.y);
通过上面的绘制就需要绘制四次.
项目结构:
核心代码:
package com.softtanck.beziercircle.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import com.softtanck.beziercircle.bean.HPoint;
import com.softtanck.beziercircle.bean.VPoint;
/**
* @author : Tanck
* @Description : TODO
* @date 10/12/2015
*/
public class BezierCircle extends View {
/** 路径 */
private Path mPath;
/** 画笔*/
private Paint mFillCirclePaint;
/** 四个点*/
private VPoint p2;
private VPoint p4;
private HPoint p1;
private HPoint p3;
/** 半径*/
private int radius;
private float c;
private float blackMagic = 0.551915024494f;
private float mInterpolatedTime;
private float stretchDistance;
public BezierCircle(Context context) {
this(context, null);
}
public BezierCircle(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BezierCircle(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
/**
* 初始化操作
*/
private void init() {
mFillCirclePaint = new Paint();
mFillCirclePaint.setColor(0xFFFFFFFF);//fe626d);
mFillCirclePaint.setStyle(Paint.Style.FILL);
mFillCirclePaint.setStrokeWidth(1);
mFillCirclePaint.setAntiAlias(true);
mPath = new Path();
p2 = new VPoint();
p4 = new VPoint();
p1 = new HPoint();
p3 = new HPoint();
radius = 20;
c = radius * blackMagic;
stretchDistance = radius;
}
@Override
protected void onDraw(Canvas canvas) {
mPath.reset();
canvas.translate(radius + 10, getHeight() / 2);
if (mInterpolatedTime >= 0 && mInterpolatedTime <= 0.2) {
CircleSpecLast(mInterpolatedTime);//圆 -> 右边尖圆
} else {
updateRadius(10);
CircleModel();
movePosition();
drawCircle(canvas);
updateRadius(20);
CircleModel();
}
drawCircle(canvas);
}
/**
* 更新半径
*
* @param r
*/
private void updateRadius(int r) {
radius = r;
c = radius * blackMagic;
}
/**
* 移动位置
*/
private void movePosition() {
float offset = (getWidth() - 3 * radius - 10) * (mInterpolatedTime - 0.2f);
offset = offset > 0 ? offset : 0;
offset = offset + 2 * radius + 10;
p1.adjustAllX(offset);
p2.adjustAllX(offset);
p3.adjustAllX(offset);
p4.adjustAllX(offset);
}
/**
* 画圆
*
* @param canvas
*/
private void drawCircle(Canvas canvas) {
mPath.moveTo(p1.x, p1.y);
mPath.cubicTo(p1.right.x, p1.right.y, p2.bottom.x, p2.bottom.y, p2.x, p2.y);
mPath.cubicTo(p2.top.x, p2.top.y, p3.right.x, p3.right.y, p3.x, p3.y);
mPath.cubicTo(p3.left.x, p3.left.y, p4.top.x, p4.top.y, p4.x, p4.y);
mPath.cubicTo(p4.bottom.x, p4.bottom.y, p1.left.x, p1.left.y, p1.x, p1.y);
canvas.drawPath(mPath, mFillCirclePaint);
mPath.reset();
}
private void CircleSpecLast(float time) {//0~0.2
CircleModel();
p2.setX(radius + stretchDistance * time * 5); // 改变最右边的点x
}
private void CircleModel() {
// p2.p4属于圆左右两点
p1.setY(radius);//右边
p3.setY(-radius);// 左边
p3.x = p1.x = 0;//圆心
p3.left.x = p1.left.x = -c;
p3.right.x = p1.right.x = c;
//p1.p3属于圆的上下两点
p2.setX(radius); // 下边
p4.setX(-radius);// 上边
p2.y = p4.y = 0;//圆心
p2.top.y = p4.top.y = -c;
p2.bottom.y = p4.bottom.y = c;
}
/**
* 移动动画类
*/
private class MoveAnimation extends Animation {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
mInterpolatedTime = interpolatedTime;
invalidate();
}
}
/**
* 开始动画
*/
public void startAnimation() {
mPath.reset();
mInterpolatedTime = 0;
MoveAnimation move = new MoveAnimation();
move.setDuration(3000);
move.setInterpolator(new AccelerateDecelerateInterpolator());
startAnimation(move);
}
}
github项目地址:点击打开链接
参考资料:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0915/3457.html