Android动画之小球拟合动画实例
实现效果:
动画组成:
1.通过三阶贝塞尔曲线来拟合圆,拟合系数的由来,以及怎么选控制点.
2.利用画布canvas.translate,以及scale,rotate的方法,来渐变绘制的过程.
3.熟悉拟合过程.
4.不熟悉的话,先绘制辅助点的移动路线,对理解两个圆的分裂的拟合过程有好处.
package com.example.administrator.animationworkdemo.views; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PathMeasure; import android.util.AttributeSet; import android.view.View; import java.util.concurrent.CyclicBarrier; /** * 这个例子中,大家可以发现作者的拟合做的并不是很好,连接的地方比较生硬,大家可以思考下如何改善 * 贝塞尔曲线绘制比较复杂,大家在学习过程中,可以仿照示例中的,将辅助点和线绘制出来,这样会看的更清楚一点 */ public class BallShapeChangeView extends View { // 使用贝塞尔曲线来拟合圆的magic number //C 是三阶贝塞尔曲线拟合 圆的 误差最小 获得控制点的参数. private static final float C = 0.551915024494f; private Paint mPaint; private int mRadiusBig = 120, mRadiusSmall = (int) (mRadiusBig / 2f), mWidth, mHeight, mMimWidth = (int) (mRadiusSmall * 2 * 3)/*fill view mim width*/; private float mFraction = 0, mFractiOnDegree= 0, /*degree*/ mLength, mDistanceBezier; private Path mPathCircle, mPathBezier; private ValueAnimator mValueAnimator; private float[] mPointData = new float[8];// 4个数据点 顺时针排序,从左边开始 private float[] mPointCtrl = new float[16];// 8个控制点 private float[] mPos = new float[2]; private PathMeasure mPathMeasure; private Path mPathBezier2; public BallShapeChangeView(Context context, AttributeSet attrs) { super(context, attrs); mPaint = new Paint(); mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(0xFF7C191E); mPaint.setAntiAlias(true); mPathCircle = new Path(); mPathBezier = new Path(); mPathBezier2 = new Path(); mPathMeasure = new PathMeasure(); mValueAnimator = ValueAnimator.ofFloat(0, 1, 0); mValueAnimator.setDuration(3000); mValueAnimator.setRepeatCount(Integer.MAX_VALUE); mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mFraction = (float) animation.getAnimatedValue(); mFractiOnDegree= animation.getAnimatedFraction(); invalidate(); } }); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 为了能够更好的控制绘制的大小和位置,当然,初学者写死也是可以的 super.onMeasure(widthMeasureSpec, heightMeasureSpec); mWidth = MeasureSpec.getSize(widthMeasureSpec); mHeight = MeasureSpec.getSize(heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (widthMode != MeasureSpec.AT_MOST && heightMode != MeasureSpec.AT_MOST) { if (mWidth
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!