package com.tomandjerry.coolanim.lib.pellet; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.os.Build; import android.view.animation.AccelerateDecelerateInterpolator; import com.tomandjerry.coolanim.lib.Config; /** * Created by weicheng on 16/1/31. */ public class FirstPellet extends Pellet { //第一个出现初始球的大小 private final int FIRST_CIRCLE_START_RADIUS = 40; //环绕行星最大半径 private final int SECOND_CIRCLE_MAX_RADIUS = 10; //黄色圆的线粗最小值 private final int THIRD_CIRCLE_MIN_STROKEWIDTH = 15; //环绕行星角度间隔 private final int DIVIDE_DEGREES = 36; private Paint mPaint; private RectF mRectF; //蓝圆半径 private int mFirCirRadius; //环绕行星半径 private int mSecCirRadius; //黄环圆半径 private int mThiCirRadius; //黄环线粗 private int mThiCirStrokeWidth; //环绕圆旋转角度 private int mAroundCirDegrees; //环绕弧线旋转角度 private int mAroundArcDegrees; //环绕弧线长度 private int mAroundArcLength; //最后的蓝圆,对应最开始的蓝圆 private int mPreFirCirRadius; private ValueAnimator mFirAnimator; private ValueAnimator mSecAnimator; private ValueAnimator mThiAnimator; private ValueAnimator mFouAnimator; private ValueAnimator mFifAnimator; private int mEndCirIRadius; private int mEndCirMRadius; private int mEndCirORadius; private ValueAnimator mEndAnimator; // 正在结束,只绘制结束动画 private boolean isMoveEnd = false; public FirstPellet(int x, int y) { super(x, y); } @Override protected void initConfig() { mEndMovingLength = -25; mPaint = new Paint(); mPaint.setStyle(Paint.Style.STROKE); mPaint.setAntiAlias(true); mRectF = new RectF(getCurX() - 45, getCurY() - 45, getCurX() + 45, getCurY() + 45); } @Override protected void initAnim() { //初始的蓝色球大小变化 mFirAnimator = ValueAnimator.ofInt(FIRST_CIRCLE_START_RADIUS, FIRST_CIRCLE_START_RADIUS + 10, FIRST_CIRCLE_START_RADIUS).setDuration(500); mFirAnimator.setRepeatCount(0); mFirAnimator.addUpdateListener( new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mFirCirRadius = (int) animation.getAnimatedValue(); } } ); mFirAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationRepeat(animation); mPreFirCirRadius = 0;//将顶层的蓝色圆半径置0; mThiCirRadius = 0; mThiCirStrokeWidth = 0; mSecAnimator.start(); } }); //环绕行星动画 mSecAnimator = ValueAnimator.ofFloat(0, 1).setDuration(2000); mSecAnimator.setRepeatCount(0); mSecAnimator.addUpdateListener( new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float zoroToOne = (float) animation.getAnimatedValue(); //环绕行星的旋转角度 mAroundCirDegrees = (int) (90 + 180 * zoroToOne); if (zoroToOne < 0.5f) { zoroToOne = zoroToOne * 2; //环绕行星的大小变化 mSecCirRadius = (int) (zoroToOne * SECOND_CIRCLE_MAX_RADIUS); } else { zoroToOne = (1 - zoroToOne) * 2; mSecCirRadius = (int) (zoroToOne * SECOND_CIRCLE_MAX_RADIUS); } } } ); mSecAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); mFouAnimator.start(); mThiAnimator.start(); } }); //环绕结束后蓝色圆有一个变大的动作 mThiAnimator = ValueAnimator.ofInt(FIRST_CIRCLE_START_RADIUS, FIRST_CIRCLE_START_RADIUS + 10, 20, 20).setDuration(500); mThiAnimator.setRepeatCount(0); mThiAnimator.addUpdateListener( new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mFirCirRadius = (int) animation.getAnimatedValue(); } } ); //环绕结束黄色的圆出现覆盖并缩小 mFouAnimator = ValueAnimator.ofFloat(0, 1).setDuration(1000); mFouAnimator.setRepeatCount(0); mFouAnimator.addUpdateListener( new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mThiCirRadius = (int) (20 + 80 * (1 - (float) animation.getAnimatedValue()));//变化范围60~20. mThiCirStrokeWidth = 15 + (int) ((float) animation.getAnimatedValue() * THIRD_CIRCLE_MIN_STROKEWIDTH); } } ); mFouAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); mFifAnimator.start(); } }); // //弧形动画旋转启动,弧形角度长度变化+蓝色球放大动画 mFifAnimator = ValueAnimator.ofFloat(0, 0.5f, 1, 2).setDuration(2000); mFifAnimator.setRepeatCount(0); mFifAnimator.addUpdateListener( new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float zoroToOne = (float) animation.getAnimatedValue(); if (zoroToOne < 0.5f) { mAroundArcDegrees = (int) (-120 + 880 * zoroToOne); zoroToOne = zoroToOne * 2; mAroundArcLength = (int) (180 * zoroToOne); } else if (zoroToOne <= 1.000f) { mAroundArcDegrees = (int) (-120 + 880 * zoroToOne); zoroToOne = (1 - zoroToOne) * 2; mAroundArcLength = (int) (180 * zoroToOne); } else { mAroundArcLength = 0; zoroToOne = zoroToOne - 1; mPreFirCirRadius = (int) (40 * zoroToOne); } } } ); mFifAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); mFifAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); if (mAnimatorStateListen != null) { mAnimatorStateListen.onAnimatorEnd(); } } }); } @Override public void startAnim() { mFirAnimator.start(); } @Override public void initEndAnim() { mEndAnimator = ValueAnimator.ofFloat(0, 1, 2).setDuration(mDuration); // mEndAnimator.setRepeatCount(2); mEndAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float zoroToOne = (float) animation.getAnimatedValue(); if (zoroToOne <= 1.0f) { mCurX = (int) (mPerX + zoroToOne * mEndMovingLength); mEndCirIRadius = (int) (MAX_RADIUS_CIRCLE * zoroToOne); if (zoroToOne <= 0.5f) { zoroToOne = 2 * zoroToOne; } else { zoroToOne = 1 - 2 * (zoroToOne - 0.5f); } mEndCirMRadius = (int) (MAX_RADIUS_CIRCLE * zoroToOne); } else { if (!isMoveEnd) { isMoveEnd = true; if (mAnimatorStateListen != null) { mAnimatorStateListen.onMoveEnd(); } } zoroToOne = 2 - zoroToOne; mEndCirIRadius = (int) (MAX_RADIUS_CIRCLE * zoroToOne); if (zoroToOne >= 0.5f) { zoroToOne = (1.0f - zoroToOne) * 2; } else { zoroToOne = zoroToOne * 2; } mEndCirORadius = (int) (MAX_RADIUS_CIRCLE * zoroToOne); } } }); mEndAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { if (mAnimatorStateListen != null) { mAnimatorStateListen.onAllAnimatorEnd(); } } }); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void drawSelf(Canvas canvas) { super.drawSelf(canvas); if (!isMoveEnd) { //蓝色球 mPaint.setColor(Color.BLUE); mPaint.setStrokeWidth(mFirCirRadius); canvas.drawCircle(getCurX(), getCurY(), mFirCirRadius / 2, mPaint); //环绕行星 //TODO 关系 mPaint.setColor(Config.GREEN); for (int i = 0; i < 10; i++) { canvas.save(); mPaint.setStrokeWidth(mSecCirRadius); canvas.rotate(90 + i * DIVIDE_DEGREES + mAroundCirDegrees, getCurX(), getCurY()); canvas.drawCircle(getCurX(), getCurY() - 60, mSecCirRadius / 2, mPaint); canvas.restore(); } //环绕结束,黄色球包围 mPaint.setColor(Config.YELLOW); mPaint.setStrokeWidth(mThiCirStrokeWidth); canvas.drawCircle(getCurX(), getCurY(), mThiCirRadius / 2, mPaint); //扇形弧线 mPaint.setColor(Color.BLUE); mPaint.setStrokeWidth(20); canvas.drawArc(mRectF, mAroundArcDegrees, mAroundArcLength, false, mPaint); mPaint.setColor(Color.BLUE); mPaint.setStrokeWidth(mPreFirCirRadius); canvas.drawCircle(getCurX(), getCurY(), mPreFirCirRadius / 2, mPaint); } if (mIsEnd) { if (!mIsEndAnimStart) { mEndAnimator.start(); mIsEndAnimStart = true; } mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(Config.BLUE); canvas.drawCircle(getCurX(), getCurY(), mEndCirIRadius, mPaint); mPaint.setColor(Config.RED); canvas.drawCircle(getCurX(), getCurY(), mEndCirMRadius, mPaint); mPaint.setColor(Config.YELLOW); canvas.drawCircle(getCurX(), getCurY(), mEndCirORadius, mPaint); mPaint.setStyle(Paint.Style.STROKE); return; } } }