Android属性动画——ImageView(Robots)

一、效果图


动画场景:该动画是在ImageView中显示,效果图中显示了三个动画:漂浮、左右招手,原动画是很流畅的,无丢帧,转成gif后大致能看出效果,不用在意卡顿。

二、实现原理

1.自定义Drawable,重写draw,根据onAnimationUpdate方法返回的动画进度,通过差值器计算出该帧drawable的状态,并绘制

2.调用Drawable.invalidateSelf触发View的重绘

三、代码分析

1.代码结构


2.MainActivity:测试动画Activity,无复杂逻辑

private void startAnimator(int type) {
    cancelAnimator();
    switch (type) {
        case TYPE_START:
            mAnimator = new StartRobotAnimator(this.getApplicationContext());
            break;
        case TYPE_WAVE_LEFT:
            mAnimator = new WaveRobotAnimator(this.getApplicationContext(), true);
            break;
        case TYPE_WAVE_RIGHT:
            mAnimator = new WaveRobotAnimator(this.getApplicationContext(), false);
            break;
        default:
            mAnimator = new StartRobotAnimator(this.getApplicationContext());
            break;
    }
    mImageView.setImageDrawable(mAnimator.getDrawable());
    mAnimator.start();
}

private void cancelAnimator() {
    if (mAnimator != null) {
        mAnimator.cancel();
        mAnimator = null;
    }
}

提供两个方法:开启/关闭动画


3.StartRobotAnimator:动画实现类

继承ValueAnimator,定义内部类继承Drawable


上图为StartRobotAnimator类结构,内部有较多的内部类:RobotDrawable、Body、EyeLefe...

也容易理解,Robots动画内部是多个元素在动,眼睛、身体、头、左右手。每个元素对应一个内部类。这些内部类都继承Basic。Basic中保存这些元素相同的属性。

动画绘制流程:

从ValueAnimator.start-> onAnimationUpdate-> 

Drawable.update

Drawable.onDraw.invalidateSelf -> draw

在update时,将动画进度传给Drawable,代码片段如下:

@Override
public void onAnimationUpdate(ValueAnimator animation) {
    mDrawable.update((int) (animation.getAnimatedValue()));
    mDrawable.invalidateSelf();
}

接着进入自定义Drawable的draw方法:

@Override
public void draw(@NonNull Canvas canvas) {
    if (mWidth == 0 || mHeight == 0) {
        mWidth = canvas.getWidth();
        mHeight = canvas.getHeight();
    }
    canvas.save();
    canvas.translate(mWidth / 2f - 126 / 2, mHeight / 2f - 164 / 2);//平移画布,保证绘制的robots在imageView中居中

    float T0 = DURATION;
    float t = Math.min(mTime, DURATION);
    double translateY = (-30f * t / T0 + 30) * Math.sin(3.5 * Math.PI / T0 * t + Math.PI / 2f);
    canvas.translate(0, (float) translateY);
    //绘制头、嘴巴、左右手
    mHead.draw(canvas);
    mMouth.draw(canvas, mTime);
    mHandLeft.draw(canvas, mTime);
    mHandRight.draw(canvas, mTime);
    //绘制身体、左右眼睛
    mBody.draw(canvas);
    mEyeLeft.draw(canvas, mTime);
    mEyeRight.draw(canvas, mTime);

    canvas.restore();
}

draw方法和View内部逻辑关系比较大,原理很简单,可以自己理解。按照下面的思路理解可能更方便记忆:

对画布整体做动画使用canvas.translate/rotate/scale/alpha

对某一元素做动画使用Basic类中的Matrix。

对于Matrix,可认为有三个方法,set、pre、post。set:清空矩阵之前的设置,重置矩阵 pre:左乘 post:右乘

比如要实现先平移再旋转的效果,可以setTranslate+postRotate 也可以setRotate+preTranslte。


四、源码

附上MainActivity和自定义Animator源码

package com.zmh.animation.robots;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends Activity {
    private ImageView mImageView;
    private IRobotsAnimator mAnimator;

    private final static int TYPE_START = 0x1;
    private final static int TYPE_WAVE_LEFT = 0x2;
    private final static int TYPE_WAVE_RIGHT = 0x3;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mImageView = findViewById(R.id.img);
        mAnimator = new StartRobotAnimator(this.getApplicationContext());
        mImageView.setImageDrawable(mAnimator.getDrawable());

        findViewById(R.id.btn_wave_left).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startAnimator(TYPE_WAVE_LEFT);

            }
        });

        findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startAnimator(TYPE_START);
            }
        });

        findViewById(R.id.btn_wave_right).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startAnimator(TYPE_WAVE_RIGHT);
            }
        });
    }


    private void startAnimator(int type) {
        cancelAnimator();
        switch (type) {
            case TYPE_START:
                mAnimator = new StartRobotAnimator(this.getApplicationContext());
                break;
            case TYPE_WAVE_LEFT:
                mAnimator = new WaveRobotAnimator(this.getApplicationContext(), true);
                break;
            case TYPE_WAVE_RIGHT:
                mAnimator = new WaveRobotAnimator(this.getApplicationContext(), false);
                break;
            default:
                mAnimator = new StartRobotAnimator(this.getApplicationContext());
                break;
        }
        mImageView.setImageDrawable(mAnimator.getDrawable());
        mAnimator.start();
    }

    private void cancelAnimator() {
        if (mAnimator != null) {
            mAnimator.cancel();
            mAnimator = null;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        cancelAnimator();
    }
}
package com.zmh.animation.robots;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.PathInterpolator;

class StartRobotAnimator extends ValueAnimator implements IRobotsAnimator, ValueAnimator.AnimatorUpdateListener {

    private RobotDrawable mDrawable;
    private int DURATION = 4000;


    StartRobotAnimator(Context context) {
        this.setDuration(DURATION);
        this.setIntValues(0, DURATION);
        this.setInterpolator(new LinearInterpolator());
        mDrawable = new RobotDrawable(context);
        addUpdateListener(this);
    }

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        mDrawable.update((int) (animation.getAnimatedValue()));
        mDrawable.invalidateSelf();
    }

    @Override
   public Drawable getDrawable() {
        return mDrawable;
    }

    private class RobotDrawable extends Drawable {

        private int mTime;
        private Body mBody;
        private EyeLeft mEyeLeft;
        private EyeRight mEyeRight;
        private HandLeft mHandLeft;
        private HandRight mHandRight;
        private Head mHead;
        private Mouth mMouth;
        private int mWidth;
        private int mHeight;

        RobotDrawable(Context context) {
            mBody = new Body(context);
            mEyeLeft = new EyeLeft(context);
            mEyeRight = new EyeRight(context);
            mHandLeft = new HandLeft(context);
            mHandRight = new HandRight(context);
            mHead = new Head(context);
            mMouth = new Mouth(context);

        }


        @Override
        public void setAlpha(int alpha) {

        }

        private void update(int time) {
            mTime = time;
        }

        @Override
        public void draw(@NonNull Canvas canvas) {
            if (mWidth == 0 || mHeight == 0) {
                mWidth = canvas.getWidth();
                mHeight = canvas.getHeight();
            }
            canvas.save();
            canvas.translate(mWidth / 2f - 126 / 2, mHeight / 2f - 164 / 2);

            float T0 = DURATION;
            float t = Math.min(mTime, DURATION);
            double translateY = (-30f * t / T0 + 30) * Math.sin(3.5 * Math.PI / T0 * t + Math.PI / 2f);
            canvas.translate(0, (float) translateY);

            mHead.draw(canvas);
            mMouth.draw(canvas, mTime);
            mHandLeft.draw(canvas, mTime);
            mHandRight.draw(canvas, mTime);

            mBody.draw(canvas);
            mEyeLeft.draw(canvas, mTime);
            mEyeRight.draw(canvas, mTime);

            canvas.restore();
        }

        @Override
        public void setColorFilter(ColorFilter colorFilter) {

        }

        @Override
        public int getOpacity() {
            return PixelFormat.UNKNOWN;
        }
    }

    private class Body extends Basic {

        Body(Context context) {
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.body);
            mBitmap = Bitmap.createScaledBitmap(mBitmap, 57, 59, true);
        }

        private void draw(Canvas canvas) {
            mMatrix.setTranslate(34, 103);
            canvas.drawBitmap(mBitmap, mMatrix, null);
        }
    }

    private class EyeLeft extends Eye {

        EyeLeft(Context context) {
            mTransX = 28;
            mTransY = 57;
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.eye_left);
            mBitmap = Bitmap.createScaledBitmap(mBitmap, 18, 22, true);
            mBmpSmall = BitmapFactory.decodeResource(context.getResources(), R.drawable.small_eye_left);
            mBmpSmall = Bitmap.createScaledBitmap(mBmpSmall, 17, 5, true);
        }
    }

    private class EyeRight extends Eye {


        EyeRight(Context context) {
            mTransX = 80;
            mTransY = 57;
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.eye_right);
            mBitmap = Bitmap.createScaledBitmap(mBitmap, 18, 22, true);

            mBmpSmall = BitmapFactory.decodeResource(context.getResources(), R.drawable.small_eye_right);
            mBmpSmall = Bitmap.createScaledBitmap(mBmpSmall, 17, 5, true);
        }
    }

    class Eye extends Basic {
        Bitmap mBmpSmall;
        Matrix mSmall = new Matrix();
        final float[] mTimes = {50f, 200f};
        final float[] mProgress = {1f, 0.15f, 1f};
        final Interpolator[] mInterpolator = {
                new PathInterpolator(0.33f, 0.00f, 0.67f, 1.00f),
                new PathInterpolator(0.33f, 0.00f, 0.67f, 1.00f)
        };

        Interpolator mStartInterpolator = new PathInterpolator(0.03f, 0.59f, 0.49f, 1.00f);
        int mTransX;
        int mTransY;

        void draw(Canvas canvas, int time) {
            mMatrix.setTranslate(mTransX, mTransY);
            mSmall.setTranslate(mTransX + 1, mTransY + mBitmap.getHeight() / 2f + 1);
            if (time <= 350) {
                float progress = mStartInterpolator.getInterpolation(time / 350f);
                mMatrix.postScale(1, progress, mTransX + mBitmap.getWidth() / 2f, mTransY + mBitmap.getHeight() / 2f);
                canvas.drawBitmap(mBmpSmall, mSmall, null);
            }

            if (time >= 2350 && time <= 2600) {
                float scale = getProgress(time - 2350, mTimes, mProgress, mInterpolator);
                mMatrix.postScale(1, scale, mTransX + mBitmap.getWidth() / 2f, mTransY + mBitmap.getHeight() / 2f);
            }
            canvas.drawBitmap(mBitmap, mMatrix, null);
        }
    }

    private class HandLeft extends Basic {

        private Interpolator interpolator = new PathInterpolator(0.21f, 0.00f, 0.29f, 1.00f);
        private int DURATION = 750;

        HandLeft(Context context) {
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.hand_left);
            mBitmap = Bitmap.createScaledBitmap(mBitmap, 19, 27, true);
        }

        private void draw(Canvas canvas, int time) {
            time = Math.min(time, DURATION);
            float progress = interpolator.getInterpolation(time * 1f / DURATION) * 60f - 60f;
            mMatrix.setTranslate(16, 116);
            mMatrix.postRotate(progress, 37, 114);
            canvas.drawBitmap(mBitmap, mMatrix, null);
        }
    }

    private class HandRight extends Basic {
        private Interpolator interpolator = new PathInterpolator(0.21f, 0.00f, 0.29f, 1.00f);
        private int DURATION = 750;

        HandRight(Context context) {
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.hand_right);
            mBitmap = Bitmap.createScaledBitmap(mBitmap, 19, 27, true);
        }

        private void draw(Canvas canvas, int time) {
            time = Math.min(time, DURATION);
            float progress = 60f - interpolator.getInterpolation(time * 1f / DURATION) * 60f;
            mMatrix.setTranslate(90, 116);
            mMatrix.postRotate(progress, 88, 114);
            canvas.drawBitmap(mBitmap, mMatrix, null);
        }
    }

    private class Head extends Basic {
        Head(Context context) {
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.head);
            mBitmap = Bitmap.createScaledBitmap(mBitmap, 126, 103, true);
        }

        private void draw(Canvas canvas) {
            canvas.drawBitmap(mBitmap, mMatrix, null);
        }

    }

    private class Mouth extends Basic {
        private final Paint mPaint = new Paint();

        Mouth(Context context) {
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.mouth);
            mBitmap = Bitmap.createScaledBitmap(mBitmap, 12, 8, true);
        }

        private void draw(Canvas canvas, int time) {
            time = Math.min(Math.max(0, time - 200), 150);
            mPaint.setAlpha(255 * time / 150);
            mMatrix.setTranslate(57, 81);
            canvas.drawBitmap(mBitmap, mMatrix, mPaint);

        }
    }

    private class Basic {

        Bitmap mBitmap;
        Matrix mMatrix = new Matrix();

        float getProgress(int time, float[] times, float[] progresss, Interpolator[] interpolators) {
            float progress = 0f;
            float t;
            if (time <= times[0]) {
                t = 1f * time / times[0];
                progress = progresss[0] + interpolators[0].getInterpolation(t) * (progresss[1] - progresss[0]);
            } else if (time <= times[0] + times[1]) {
                t = 1f * (time - times[0]) / times[1];
                progress = progresss[1] + interpolators[1].getInterpolation(t) * (progresss[2] - progresss[1]);
            } else if (time <= times[0] + times[1] + times[2]) {
                t = 1f * (time - times[1] - times[0]) / times[2];
                progress = progresss[2] + interpolators[2].getInterpolation(t) * (progresss[3] - progresss[2]);
            } else if (time <= times[0] + times[1] + times[2] + times[3]) {
                t = 1f * (time - times[2] - times[1] - times[0]) / times[3];
                progress = progresss[3] + interpolators[3].getInterpolation(t) * (0 - progresss[3]);
            }
            return progress;
        }
    }

}
package com.zmh.animation.robots;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.PathInterpolator;

class WaveRobotAnimator extends ValueAnimator implements IRobotsAnimator, ValueAnimator.AnimatorUpdateListener {

    private RobotDrawable mDrawable;


    WaveRobotAnimator(Context context, boolean left) {
        this.setDuration(1700);
        this.setIntValues(0, 1700);
        this.setInterpolator(new LinearInterpolator());
        mDrawable = new RobotDrawable(context, left);
        addUpdateListener(this);
    }

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        mDrawable.update((int) (animation.getAnimatedValue()));
        mDrawable.invalidateSelf();
    }

    @Override
    public Drawable getDrawable() {
        return mDrawable;
    }

    private class RobotDrawable extends Drawable {

        private int mTime;
        private Body mBody;
        private EyeLeft mEyeLeft;
        private EyeRight mEyeRight;
        private HandLeft mHandLeft;
        private HandRight mHandRight;
        private Head mHead;
        private Mouth mMouth;
        private int mWidth;
        private int mHeight;
        private boolean mIsLeft;

        RobotDrawable(Context context, boolean left) {
            mIsLeft = left;
            mBody = new Body(context);
            mEyeLeft = new EyeLeft(context);
            mEyeRight = new EyeRight(context);
            mHandLeft = new HandLeft(context);
            mHandRight = new HandRight(context);
            mHead = new Head(context);
            mMouth = new Mouth(context);

        }


        @Override
        public void setAlpha(int alpha) {

        }

        private void update(int time) {
            mTime = time;
        }

        @Override
        public void draw(@NonNull Canvas canvas) {
            if (mWidth == 0 || mHeight == 0) {
                mWidth = canvas.getWidth();
                mHeight = canvas.getHeight();
            }
            canvas.save();
            if (mIsLeft) {
                canvas.scale(-1, 1, canvas.getWidth() / 2f, canvas.getHeight() / 2f);
            }
            canvas.translate(mWidth / 2f - 126 / 2, mHeight / 2f - 164 / 2);
            float bodyProgress = mBody.getProgress(mTime);
            canvas.rotate(bodyProgress, 63, 164);

            canvas.save();
            float headProgress = mHead.getProgress(mTime);
            canvas.rotate(headProgress, 63, 103);

            mHead.draw(canvas);
            mEyeLeft.draw(canvas, mTime);
            mEyeRight.draw(canvas, mTime);
            mMouth.draw(canvas);
            canvas.restore();

            mBody.draw(canvas);
            mHandLeft.draw(canvas, mTime);
            mHandRight.draw(canvas, mTime);
            canvas.restore();
        }

        @Override
        public void setColorFilter(ColorFilter colorFilter) {

        }

        @Override
        public int getOpacity() {
            return PixelFormat.UNKNOWN;
        }
    }

    private class Body extends Basic {
        private final Interpolator[] mInterpolator = {
                new PathInterpolator(0.48f, 0.06f, 0.52f, 0.94f),
                new PathInterpolator(0.47f, 0.00f, 0.77f, 0.63f),
                new PathInterpolator(0.34f, -0.68f, 0.55f, -1.14f),
                new PathInterpolator(0.48f, 0.00f, 0.52f, 1.00f)
        };
        private final float[] mProgress = {0f, 18f, 17.7f, 18.0f};

        Body(Context context) {
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.body);
            mBitmap = Bitmap.createScaledBitmap(mBitmap, 57, 59, true);
        }

        private void draw(Canvas canvas) {
            mMatrix.setTranslate(34, 103);
            canvas.drawBitmap(mBitmap, mMatrix, null);
        }

        float getProgress(int time) {
            return getProgress(time, mTimes, mProgress, mInterpolator);
        }
    }

    private class EyeLeft extends Eye {

        EyeLeft(Context context) {
            mTransX = 28;
            mTransY = 57;
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.eye_left);
            mBitmap = Bitmap.createScaledBitmap(mBitmap, 18, 22, true);
        }
    }

    private class EyeRight extends Eye {

        EyeRight(Context context) {
            mTransX = 80;
            mTransY = 57;
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.eye_right);
            mBitmap = Bitmap.createScaledBitmap(mBitmap, 18, 22, true);
        }
    }

    class Eye extends Basic {
        final float[] mTimes = {50f, 200f};
        final float[] mProgress = {1f, 0.15f, 1f};
        final Interpolator[] mInterpolator = {
                new PathInterpolator(0.33f, 0.00f, 0.67f, 1.00f),
                new PathInterpolator(0.33f, 0.00f, 0.67f, 1.00f)
        };
        int mTransX;
        int mTransY;

        void draw(Canvas canvas, int time) {
            mMatrix.setTranslate(mTransX, mTransY);

            if (time >= 1000 && time <= 1250) {
                float scale = getProgress(time - 1000, mTimes, mProgress, mInterpolator);
                mMatrix.postScale(1, scale, mTransX + mBitmap.getWidth() / 2f, mTransY + mBitmap.getHeight() / 2f);
            }
            canvas.drawBitmap(mBitmap, mMatrix, null);
        }
    }

    private class HandLeft extends Basic {
        private final float[] mProgress = {0f, 116f, 80f, 116f};
        private final Interpolator[] mInterpolator = {
                new PathInterpolator(0.44f, 0.20f, 0.71f, 1.00f),
                new PathInterpolator(0.48f, 0.00f, 0.44f, 1.00f),
                new PathInterpolator(0.53f, 0.00f, 0.61f, 1.00f),
                new PathInterpolator(0.17f, 0.00f, 0.52f, 1.00f)
        };

        HandLeft(Context context) {
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.hand_left);
            mBitmap = Bitmap.createScaledBitmap(mBitmap, 19, 27, true);
        }

        private void draw(Canvas canvas, int time) {
            float progress = getProgress(time, mTimes, mProgress, mInterpolator);
            mMatrix.setTranslate(16, 116);
            mMatrix.postRotate(progress, 37, 114);
            canvas.drawBitmap(mBitmap, mMatrix, null);
        }
    }

    private class HandRight extends Basic {
        private final float[] mProgress = {0f, -25f, -24.6f, -25f};
        private final Interpolator[] mInterpolator = {
                new PathInterpolator(0.48f, 0.06f, 0.52f, 0.94f),
                new PathInterpolator(0.47f, 0.00f, 0.77f, 0.63f),
                new PathInterpolator(0.34f, -0.68f, 0.55f, -1.14f),
                new PathInterpolator(0.48f, 0.00f, 0.52f, 1.00f)
        };

        HandRight(Context context) {
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.hand_right);
            mBitmap = Bitmap.createScaledBitmap(mBitmap, 19, 27, true);
        }

        private void draw(Canvas canvas, int time) {
            float progress = getProgress(time, mTimes, mProgress, mInterpolator);
            mMatrix.setTranslate(90, 116);
            mMatrix.postRotate(progress, 88, 114);
            canvas.drawBitmap(mBitmap, mMatrix, null);
        }
    }

    private class Head extends Basic {
        private final float[] mProgress = {0f, 18f, 17.7f, 18f};
        private final Interpolator[] mInterpolator = {
                new PathInterpolator(0.48f, 0.60f, 0.52f, 0.94f),
                new PathInterpolator(0.47f, 0.00f, 0.77f, 0.63f),
                new PathInterpolator(0.34f, -0.68f, 0.55f, -1.14f),
                new PathInterpolator(0.48f, 0.00f, 0.52f, 1.00f)
        };

        Head(Context context) {
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.head);
            mBitmap = Bitmap.createScaledBitmap(mBitmap, 126, 103, true);
        }

        private void draw(Canvas canvas) {
            canvas.drawBitmap(mBitmap, mMatrix, null);
        }

        float getProgress(int time) {
            return getProgress(time, mTimes, mProgress, mInterpolator);
        }

    }

    private class Mouth extends Basic {

        Mouth(Context context) {
            mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.mouth);
            mBitmap = Bitmap.createScaledBitmap(mBitmap, 12, 8, true);
        }

        private void draw(Canvas canvas) {
            mMatrix.setTranslate(57, 81);
            canvas.drawBitmap(mBitmap, mMatrix, null);

        }
    }

    private class Basic {

        final float[] mTimes = {700f, 200f, 250f, 550f};

        Bitmap mBitmap;
        Matrix mMatrix = new Matrix();

        float getProgress(int time, float[] times, float[] progresss, Interpolator[] interpolators) {
            float progress = 0f;
            float t;
            if (time <= times[0]) {
                t = 1f * time / times[0];
                progress = progresss[0] + interpolators[0].getInterpolation(t) * (progresss[1] - progresss[0]);
            } else if (time <= times[0] + times[1]) {
                t = 1f * (time - times[0]) / times[1];
                progress = progresss[1] + interpolators[1].getInterpolation(t) * (progresss[2] - progresss[1]);
            } else if (time <= times[0] + times[1] + times[2]) {
                t = 1f * (time - times[1] - times[0]) / times[2];
                progress = progresss[2] + interpolators[2].getInterpolation(t) * (progresss[3] - progresss[2]);
            } else if (time <= times[0] + times[1] + times[2] + times[3]) {
                t = 1f * (time - times[2] - times[1] - times[0]) / times[3];
                progress = progresss[3] + interpolators[3].getInterpolation(t) * (0 - progresss[3]);
            }
            return progress;
        }
    }

}

五、项目源码

github:https://github.com/ZhangMingHua001/Robots

csdn:

猜你喜欢

转载自blog.csdn.net/lantianZMH01/article/details/80039200