Android Path曲线动画
博客专区 > IamOkay 的博客 > 博客详情
Android Path曲线动画
IamOkay 发表于2年前
Android Path曲线动画
  • 发表于 2年前
  • 阅读 1426
  • 收藏 2
  • 点赞 2
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

摘要: Android Path曲线动画

曲线动画很常见,但最著名的是贝塞尔曲线动画(贝塞尔曲线的数学原理

class BezierEvaluator implements TypeEvaluator<PointF>{  
  
        @Override  
        public PointF evaluate(float fraction, PointF startValue,  
                PointF endValue) {  
            final float t = fraction;  
            float oneMinusT = 1.0f - t;  
            PointF point = new PointF();  
              
            PointF point0 = (PointF)startValue;  
              
            PointF point1 = new PointF();  
            point1.set(width, 0);  
              
            PointF point2 = new PointF();  
            point2.set(0, height);  
              
            PointF point3 = (PointF)endValue;  
              
            point.x = oneMinusT * oneMinusT * oneMinusT * (point0.x)   
                    + 3 * oneMinusT * oneMinusT * t * (point1.x)  
                    + 3 * oneMinusT * t * t * (point2.x)  
                    + t * t * t * (point3.x);  
              
            point.y = oneMinusT * oneMinusT * oneMinusT * (point0.y)   
                    + 3 * oneMinusT * oneMinusT * t * (point1.y)  
                    + 3 * oneMinusT * t * t * (point2.y)  
                    + t * t * t * (point3.y);             
            return point;  
        }     
    }  



valueAnimator.addUpdateListener(new AnimatorUpdateListener() {            
            @Override  
            public void onAnimationUpdate(ValueAnimator animation) {  
                PointF pointF = (PointF)animation.getAnimatedValue();  
                button.setX(pointF.x);  
                button.setY(pointF.y);  
            }  
        });  

 

但是还有一类动画就是Path动画,通过PathMeasure实现Object在Path路径上动画

public class DynamicHeartView extends View {  
  
    private static final String TAG = "DynamicHeartView";  
    private static final int PATH_WIDTH = 2;  
    // 起始点  
    private static final int[] START_POINT = new int[] {  
            300, 270  
    };  
    // 爱心下端点  
    private static final int[] BOTTOM_POINT = new int[] {  
            300, 400  
    };  
    // 左侧控制点  
    private static final int[] LEFT_CONTROL_POINT = new int[] {  
            450, 200  
    };  
    // 右侧控制点  
    private static final int[] RIGHT_CONTROL_POINT = new int[] {  
            150, 200  
    };  
  
    private PathMeasure mPathMeasure;  
    private Paint mPaint;  
    private Path mPath;  
    private float[] mCurrentPosition = new float[2];  
  
    public DynamicHeartView(Context context) {  
        super(context);  
        init();  
    }  
  
    private void init() {  
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
        mPaint.setStyle(Style.STROKE);  
        mPaint.setStrokeWidth(PATH_WIDTH);  
        mPaint.setColor(Color.RED);  
  
        mPath = new Path();  
        mPath.moveTo(START_POINT[0], START_POINT[1]);  
        mPath.quadTo(RIGHT_CONTROL_POINT[0], RIGHT_CONTROL_POINT[1], BOTTOM_POINT[0],  
                BOTTOM_POINT[1]);  
        mPath.quadTo(LEFT_CONTROL_POINT[0], LEFT_CONTROL_POINT[1], START_POINT[0], START_POINT[1]);  
  
        mPathMeasure = new PathMeasure(mPath, true);  
        mCurrentPosition = new float[2];  
    }  
  
    @Override  
    protected void onDraw(Canvas canvas) {  
        super.onDraw(canvas);  
        canvas.drawColor(Color.WHITE);  
        canvas.drawPath(mPath, mPaint);  
  
        canvas.drawCircle(RIGHT_CONTROL_POINT[0], RIGHT_CONTROL_POINT[1], 5, mPaint);  
        canvas.drawCircle(LEFT_CONTROL_POINT[0], LEFT_CONTROL_POINT[1], 5, mPaint);  
  
        // 绘制对应目标  
        canvas.drawCircle(mCurrentPosition[0], mCurrentPosition[1], 10, mPaint);  
    }  
  
    // 开启路径动画  
    public void startPathAnim(long duration) {  
        // 0 - getLength()  
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, mPathMeasure.getLength());  
        Log.i(TAG, "measure length = " + mPathMeasure.getLength());  
        valueAnimator.setDuration(duration);  
        // 减速插值器  
        valueAnimator.setInterpolator(new DecelerateInterpolator());  
        valueAnimator.addUpdateListener(new AnimatorUpdateListener() {  
  
            @Override  
            public void onAnimationUpdate(ValueAnimator animation) {  
                float value = (Float) animation.getAnimatedValue();  
                // 获取当前点坐标封装到mCurrentPosition  
                mPathMeasure.getPosTan(value, mCurrentPosition, null);  
                postInvalidate();  
            }  
        });  
        valueAnimator.start();  
  
    }  
}  

http://blog.csdn.net/vrix/article/details/39206975

http://blog.csdn.net/tianjian4592/article/details/47067161

http://www.2cto.com/kf/201503/380377.html

http://blog.csdn.net/androidzhaoxiaogang/article/details/8680330

http://blog.csdn.net/linmiansheng/article/details/18763987

 

 

 

 

 

 

 

 

 

共有 人打赏支持
粉丝 165
博文 406
码字总数 301560
评论 (0)
×
IamOkay
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: