文档章节

Android Path曲线动画

IamOkay
 IamOkay
发布于 2016/05/18 17:07
字数 459
阅读 1841
收藏 2

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

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

 

 

 

 

 

 

 

 

 

© 著作权归作者所有

共有 人打赏支持
IamOkay
粉丝 187
博文 459
码字总数 372015
作品 0
海淀
程序员
创建Material Design风格的Android应用--使用自定义动画

动画在Material Design设计中给用户反馈放用户点击时,并且在程序用户界面中提供连贯的视觉。Material主题为按钮(Button)和activity的转换提供了一些默认的动画,在android5.0(api 21)和...

码农明明
2014/11/13
0
0
Android动画曲线库AndroidEasingFunctions

Android动画曲线库AndroidEasingFunctions AndroidEasingFunction是基于Easing Function(缓动函数)的Android动画曲线库。它提供了九大类27种动画曲线效果,可以使对应的属性按照时间进行变...

大学霸
05/17
0
0
【Animations】用动画移动视图(5)

原文 概要 屏幕上的对象通常需要重新定位。这可能是由于用户交互或在幕后完成某些处理而发生的。而不是立即更新对象位置,这会导致它从一个区域闪烁到另一个区域,您应该使用动画将其从开始位...

lichong951
05/28
0
0
Android SVG、Vector和VectorDrawable矢量图及动画

Vector图像,第三方Sharp库,阿里巴巴的SVG图。 阿里巴巴矢量图库(http://www.iconfont.cn/) Android矢量图(一)--VectorDrawable基础- https://www.jianshu.com/p/0972a0d290e9 android下一些...

desaco
10/18
0
0
图片和图形之矢量绘制(Vector drawables)(3)

原文 概述 A VectorDrawable是一个矢量图形,在XML文件中定义为一组点,线和曲线及其相关的颜色信息。使用矢量绘图的主要优点是图像可伸缩性。它可以在不损失显示质量的情况下进行缩放,这意...

lichong951
05/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

防止快速重复点击的两种思维

防止重复执行的两种思维 场景 下单时,提交按钮,因为网络卡顿或者手快重复点击,导致重复提交订单; 微博,更新个人状态或发表评论时,快速多次点击[发送]按钮,导致相同的信息发送多次. 解决思路 ...

黄威
25分钟前
0
0
在windows环境下使用Virtualbox虚拟Debian系统来运行Docker

标题绕口。 我之前一直使用 Virtualbox 和 homestead 来运行我的 PHP 开发环境。最近决心开始尝试 DevOps,使得开发、部署容器化,来化解人为操作失误和环境不兼容等问题造成的各种损失。就打...

zgldh
27分钟前
0
0
python map()

map()函数 map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。(利用生成器的原理,并不马上返回值,...

南桥北木
41分钟前
0
0
分享几个 SpringBoot 实用的小技巧

前言 最近分享的一些源码、框架设计的东西。我发现大家热情不是特别高,想想大多数应该还是正儿八经写代码的居多;这次就分享一点接地气的: SpringBoot 使用中的一些小技巧。 算不上多高大上...

Java干货分享
42分钟前
2
0
day123-20181021-英语流利阅读-待学习

这款新字体,比记忆面包还管用 Lala 2018-10-21 1.今日导读 字体能跟学习效果有什么关系?你还别说,来自澳洲的心理学家和设计师们,还真创造了一款号称能够帮助大家记忆信息、增强学习效果的...

飞鱼说编程
53分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部