android高级动画——贝塞尔曲线

来源:互联网 发布:ipadmini2网络不稳定 编辑:程序博客网 时间:2024/06/06 04:01

Android高级动画所有代码

简介:贝塞尔曲线是计算机图形学中相当重要的参数曲线。可以用数学公式来描述一段曲线。

用途:1、贝塞尔曲线可以帮助我们在二维平面内用平滑的曲线画出各种图形。

2、同时也可以给动画提供一个平滑的曲线运动路径。

android中我们通过Path可以画出二阶跟三阶贝塞尔曲线。复杂的图形我们可以组合几个二阶和三阶的贝塞尔曲线就可以实现。

这次整理一下沿着二阶贝塞尔曲线运动的例子。下面是一个沿着二阶贝塞尔曲线运动的小球的代码和讲解。


示例代码:

1、总共有4个代码文件activity、view、Evalutor和xml文件。

2、先分析下最重要的view文件:

public class TestMove extends View implements View.OnClickListener{    private float mCircleX,mCircleY;    //小球的圆心    private Path mMovePath;         //这是用来画贝塞尔曲线的    private Paint mPaintBezier,mPaintCircle;    //设置画贝塞尔曲线和园的画笔    private float mStartPointX,mStartPointY;    //二阶贝塞尔曲线的起始点    private float mEndPointX,mEndPointY;        //二阶贝塞尔曲线的终点    private float mFlagPointX,mFlagPointY;      //二阶贝塞尔曲线的支撑点    public TestMove(Context context) {        super(context);    }    public TestMove(Context context, AttributeSet attrs) {        super(context, attrs);        //初始化画笔        mPaintBezier=new Paint(Paint.ANTI_ALIAS_FLAG);        mPaintBezier.setStrokeWidth(8);        mPaintBezier.setStyle(Paint.Style.STROKE);        mPaintBezier.setColor(Color.BLUE);        mPaintCircle=new Paint(Paint.ANTI_ALIAS_FLAG);        mPaintCircle.setStrokeWidth(8);        mPaintCircle.setStyle(Paint.Style.FILL_AND_STROKE);        mPaintCircle.setColor(Color.BLUE);        setOnClickListener(this);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        /**         * 系统每一次需要计算大小时都会执行这个方法,比如view改变的时候。所以我们在这里         * 获得起始点、终点和支撑点         */        mStartPointX = w / 4;        mStartPointY = h / 2 - 200;        mEndPointX = w * 3 / 4;        mEndPointY = h / 2 - 200;        mFlagPointX = w / 2;        mFlagPointY = h / 2 - 400;        mCircleX=mStartPointX;        mCircleY=mStartPointY;        mMovePath=new Path();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //画圆        canvas.drawCircle(mCircleX,mCircleY,30,mPaintCircle);        //给Path设置贝塞尔曲线,然后canvas画        mMovePath.reset();        mMovePath.moveTo(mStartPointX,mStartPointY);        /**         * quadTo()绘制二阶贝塞尔曲线         * cubicTo()绘制三阶贝塞尔曲线         */        mMovePath.quadTo(mFlagPointX,mFlagPointY,mEndPointX,mEndPointY);        canvas.drawPath(mMovePath,mPaintBezier);    }    @Override    public void onClick(View v) {        PointF flagPoint1=new PointF(mFlagPointX,mFlagPointY);        PointF startPoint=new PointF(mStartPointX,mStartPointY);        PointF endPoint=new PointF(mEndPointX,mEndPointY);        /**         * 在startPoint和endPoint之间运动时返回一个ValueAnimator的值         * MoveEvalutor在它的文件里详细解释         */        ValueAnimator mValueAnimator=ValueAnimator.ofObject(new MoveEvalutor(flagPoint1),                startPoint,endPoint);        mValueAnimator.setDuration(4000);        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                /**                 * 把小球的圆心设置到运动点                 */                PointF point=(PointF) animation.getAnimatedValue();                mCircleX=point.x;                mCircleY=point.y;                invalidate();            }        });        mValueAnimator.start();    }}

3MoveEvalutor.java的代码:

/** * Created by zhaofeng on 2017/2/13. * * Evalutor允许开发者在任意类型上创建动画,以此来执行动画系统不能直接识别的动画类型。 */public class MoveEvalutor implements TypeEvaluator<PointF>{    private PointF mFlagPoint1;    public MoveEvalutor(PointF flagPoint) {        mFlagPoint1=flagPoint;    }    @Override    public PointF evaluate(float fraction, PointF startValue, PointF endValue) {        return CalculateBezierPointForQuadratic(fraction,startValue,mFlagPoint1,endValue);    }    /**     * B(t) = (1 - t)^2 * P0 + 2t * (1 - t) * P1 + t^2 * P2, t ∈ [0,1]     *计算贝塞尔曲线的运动点,这个代码在网上可以找到,二阶的三阶的。     * @param t  曲线长度比例     * @param p0 起始点     * @param p1 控制点     * @param p2 终止点     * @return t对应的点     */    public static PointF CalculateBezierPointForQuadratic(float t, PointF p0, PointF p1, PointF p2) {        PointF point = new PointF();        float temp = 1 - t;        point.x = temp * temp * p0.x + 2 * t * temp * p1.x + t * t * p2.x;        point.y = temp * temp * p0.y + 2 * t * temp * p1.y + t * t * p2.y;        return point;    }}

4、在activity_move_on_bezier.xml,在xml文件中引入view文件。

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_move_on_bezier"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.zfeng.bazier.MoveOnBezierActivity">    <com.zfeng.bazier.view.MoveOnBezierView        android:layout_width="match_parent"        android:layout_height="match_parent" /></RelativeLayout>
5、在activity中执行:

public class MoveOnBezierActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_move_on_bezier);    }}

以上就是全部的代码,点击view,小球就会沿着二阶贝塞尔曲线运动。


参考资料:

https://developer.android.com/reference/android/view/View.html

https://developer.android.com/reference/android/graphics/Path.html

https://developer.android.com/reference/android/animation/ValueAnimator.html

https://developer.android.com/reference/android/animation/TypeEvaluator.html



0 1