关于 android 贝赛尔曲线 动画

来源:互联网 发布:nginx配置两个域名 编辑:程序博客网 时间:2024/05/16 10:28
##关于贝赛尔曲线

####首先关于贝赛尔曲线的点的问题(二阶):

主要用的是: public void quadTo(float x,float y,float x1,float y1) 方法

参数说明:

(x,y):代表控制点的坐标.

(x1,y1):代表曲线终点的坐标

####坐标的分布: 坐标原点是在 出发点 ,然后上面为负坐标 左侧为负方向

(有点不敢证实,待分析.....)

####核心代码:

实现从一个点开始,到另外一个点的贝赛尔曲线,其中包含一些动画效果:
包括缩放和透明度的动画:

activity 代码:

    private ImageButton imageButton;
    private Button btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageButton = (ImageButton) findViewById(R.id.imagebtn);
        btn = (Button) findViewById(R.id.btn);

        btn.setOnClickListener(this);
    }
         private float getScale(ImageView target) {
        return 2f;
    }

    @Override
    public void onClick(View view) {
        imageButton.setVisibility(View.VISIBLE);
        ViewPath path = new ViewPath(); //偏移坐标
        path.moveTo(0, 0);
        path.quadTo(200, -800, 500, 10);
        ObjectAnimator anim = ObjectAnimator.ofObject(this, "fabLoc", new ViewPathEvaluator(), path.getPoints().toArray());
        addAnimation(anim, imageButton);
    }

    private void addAnimation(ObjectAnimator animator1, ImageButton target) {
        ObjectAnimator alpha = ObjectAnimator.ofFloat(target, View.ALPHA, 0.2f,1, 0.01f);
        ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, View.SCALE_X, 1, getScale(target), 1.0f);
        ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, View.SCALE_Y, 1, getScale(target), 1.0f);

        AnimatorSet all2 = new AnimatorSet();
        all2.setDuration(4800);
        all2.playTogether(alpha, scaleX, scaleY, animator1);
        all2.addListener(new AnimEndListener(target));
        all2.start();
    }

    private class AnimEndListener extends AnimatorListenerAdapter {
        private View target;

        public AnimEndListener(View target) {
            this.target = target;
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            target.setVisibility(View.GONE);
        }

        @Override
        public void onAnimationResume(Animator animation) {
            super.onAnimationResume(animation);

        }
    }

    public void setFabLoc(ViewPoint newLoc) {
        imageButton.setTranslationX(newLoc.x);
        imageButton.setTranslationY(newLoc.y);
    }

ViewPath.java 贝赛尔曲线 路径的集合

    public class ViewPoint {
    public float x;
    public float y;

    float x1, y1;

    float x2, y2;

    int operation;

    public ViewPoint(float x, float y) {
        this.x = x;
        this.y = y;
    }

    public static ViewPoint moveTo(float x, float y, int operation) {
        return new ViewPoint(x, y, operation);
    }

    public static ViewPoint lineTo(float x, float y, int operation) {
        return new ViewPoint(x, y, operation);
    }

    public static ViewPoint curveTo(float x, float y, float x1, float y1, float x2, float y2, int operation) {
        return new ViewPoint(x, y, x1, y1, x2, y2, operation);
    }

    public static ViewPoint quadTo(float x, float y, float x1, float y1, int operation) {
        return new ViewPoint(x, y, x1, y1, operation);
    }


    private ViewPoint(float x, float y, int operation) {
        this.x = x;
        this.y = y;
        this.operation = operation;
    }

    public ViewPoint(float x, float y, float x1, float y1, int operation) {
        this.x = x;
        this.y = y;
        this.x1 = x1;
        this.y1 = y1;
        this.operation = operation;
    }

    public ViewPoint(float x, float y, float x1, float y1, float x2, float y2, int operation) {
        this.x = x;
        this.y = y;
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        this.operation = operation;
    }
    }


ViewPathEvaluator.java:

    public class ViewPathEvaluator implements TypeEvaluator<ViewPoint> {

    // 自定义估值器:ViewPathEvaluator

    public ViewPathEvaluator() {
    }


    @Override
    public ViewPoint evaluate(float t, ViewPoint startValue, ViewPoint endValue) {

        // 返回一个路径信息,其中包含偏移坐标x和偏移坐标y。
        // 【返回用于反射调用setFabLoc时函数的传参】、

        // startValue:前一个操作路径 endValue:后一个操作路径 t:操作进度(0->1)
        // startValue和endValue为传入的路径集合数组中相邻的两个路径

        float x  ,y;

        float startX,startY;

        //分情况进行判断,计算出返回的偏移坐标:

        if(endValue.operation == ViewPath.LINE){

            //起点判断:
            startX = (startValue.operation==ViewPath.QUAD)?startValue.x1:startValue.x;

            startX = (startValue.operation == ViewPath.CURVE)?startValue.x2:startX;

            startY = (startValue.operation==ViewPath.QUAD)?startValue.y1:startValue.y;

            startY = (startValue.operation == ViewPath.CURVE)?startValue.y2:startY;

            //返回的偏移坐标计算:根据公式
            x = startX + t * (endValue.x - startX);
            y = startY+ t * (endValue.y - startY);


        }else if(endValue.operation == ViewPath.CURVE){

            //起点判断:
            startX = (startValue.operation==ViewPath.QUAD)?startValue.x1:startValue.x;
            startY = (startValue.operation==ViewPath.QUAD)?startValue.y1:startValue.y;

            float oneMinusT = 1 - t;

            //返回的偏移坐标计算:根据公式
            x = oneMinusT * oneMinusT * oneMinusT * startX +
                    3 * oneMinusT * oneMinusT * t * endValue.x +
                    3 * oneMinusT * t * t * endValue.x1+
                    t * t * t * endValue.x2;

            y = oneMinusT * oneMinusT * oneMinusT * startY +
                    3 * oneMinusT * oneMinusT * t * endValue.y +
                    3 * oneMinusT * t * t * endValue.y1+
                    t * t * t * endValue.y2;


        }else if(endValue.operation == ViewPath.MOVE){

            x = endValue.x;
            y = endValue.y;


        }else if(endValue.operation == ViewPath.QUAD){

            //起点判断:
            startX = (startValue.operation==ViewPath.CURVE)?startValue.x2:startValue.x;
            startY = (startValue.operation==ViewPath.CURVE)?startValue.y2:startValue.y;

            //返回的偏移坐标计算:根据公式
            float oneMinusT = 1 - t;
            x = oneMinusT * oneMinusT *  startX +
                    2 * oneMinusT *  t * endValue.x +
                    t * t * endValue.x1;

            y = oneMinusT * oneMinusT * startY +
                    2  * oneMinusT * t * endValue.y +
                    t * t * endValue.y1;


        }else {
            // 其他
            x = endValue.x;
            y = endValue.y;
        }


        return new ViewPoint(x,y);
    }
    }


ViewPoint.java:贝赛尔曲线的路径信息

    public class ViewPoint {

    public float x;
    public float y;

    float x1, y1;

    float x2, y2;

    int operation;

    public ViewPoint(float x, float y) {
        this.x = x;
        this.y = y;
    }

    public static ViewPoint moveTo(float x, float y, int operation) {
        return new ViewPoint(x, y, operation);
    }

    public static ViewPoint lineTo(float x, float y, int operation) {
        return new ViewPoint(x, y, operation);
    }

    public static ViewPoint curveTo(float x, float y, float x1, float y1, float x2, float y2, int operation) {
        return new ViewPoint(x, y, x1, y1, x2, y2, operation);
    }

    public static ViewPoint quadTo(float x, float y, float x1, float y1, int operation) {
        return new ViewPoint(x, y, x1, y1, operation);
    }


    private ViewPoint(float x, float y, int operation) {
        this.x = x;
        this.y = y;
        this.operation = operation;
    }

    public ViewPoint(float x, float y, float x1, float y1, int operation) {
        this.x = x;
        this.y = y;
        this.x1 = x1;
        this.y1 = y1;
        this.operation = operation;
    }

    public ViewPoint(float x, float y, float x1, float y1, float x2, float y2, int operation) {
        this.x = x;
        this.y = y;
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        this.operation = operation;
    }
    }

activity_main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageButton
        android:id="@+id/imagebtn"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerVertical="true"
        android:background="@drawable/imgbg"
        android:padding="14dp"
        android:scaleType="centerInside"
        android:src="@drawable/stop" />

    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:text="查看动画" />
    </RelativeLayout>



#### 参考链接:

http://blog.csdn.net/cxmscb/article/details/52485878

http://www.2cto.com/kf/201604/497130.html

https://github.com/diamondlin2016/LauncherView

http://www.jianshu.com/p/138ad32540ce

http://blog.csdn.net/tyk0910/article/details/51626828
0 0