文档章节

Android 实现Path曲线动画两种方案

IamOkay
 IamOkay
发布于 2016/05/18 17:07
字数 641
阅读 7.4K
收藏 2

精选30+云产品,助力企业轻松上云!>>>

Path动画是一种非常特殊的动画,可以理解为动画沿着Path路径移动。构建Path动画有两种方式,第一种是基于TypeEvalutor,该类用于控制View的状态、位置等。另一种是通过PathMeasure,这种可以更加直观的定义路径,同样也可以定义draw绘图等。

 

方案一:通过TypeEvalutor定义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);  
            }  
        });  

 

方案二:PathMeasure动画

但是还有一类动画就是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

IamOkay

粉丝 206
博文 493
码字总数 412482
作品 0
海淀
程序员
私信 提问
Android高级动画(3)

目录 Android高级动画(1)http://www.jianshu.com/p/48554844a2db Android高级动画(2)http://www.jianshu.com/p/89cfd9042b1e Android高级动画(3)http://www.jianshu.com/p/d6cc8d2189......

大公爵
2017/07/05
0
0
创建Material Design风格的Android应用--使用自定义动画

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

码农明明
2014/11/13
7.9K
0
图片和图形之矢量绘制(Vector drawables)(3)

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

lichong951
2018/05/25
0
0
Android动画曲线库AndroidEasingFunctions

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

大学霸
2018/05/17
113
0
SVGA 动效格式调研

人眼通过动态图形的视觉残留产生动感,于是有了动效. 动态图形 无论是在 AE & Animate 中创作图形, 调节关键帧设置变化函数; 还是利用 PS 逐帧绘制导出 GIF, 本质上都是在产生一组连贯的序列画...

flutter-talk
2019/07/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

FusionConputer热迁移过程记录

一、迁移原因   云平台集群内存资源不足,已超过设定阈值,内存资源已紧急告警。 二、解决思路   启用新集群,并将老集群中部分虚拟机热迁移至新集群 三、迁移的前提条件   1.被迁移虚...

osc_flwkfqx5
今天
13
0
使用 ServerLess 实现云原生

笔者有幸经历了 IaaS(OS)、CaaS(Container),在这两年又听到了 FaaS(Funtion),这也是运维开发领域里的第三个阶段了吧,今天我将从一个不懂得开发的系统工程师视角以及结合之前的几篇系...

osc_t59f3rc0
今天
18
0
作为软件测试的前辈你能不能给迷茫中的我一点建议?

一、为什么迷茫? 假如前面迷雾一片,作为司机的你,敢踩油门往前冲吗? 大多数人是不敢的。 因为你看不清自己的位置和发展的方向。 同理,一切对未来的恐慌、畏惧、纠结、迷茫,也是因为你看...

osc_auwur47t
今天
12
0
神经机器翻译的直观解释

作者|Renu Khandelwal 编译|VK 来源|Towards Data Science 什么是神经机器翻译? 神经机器翻译是一种将一种语言翻译成另一种语言的技术。一个例子是把英语转换成印地语。让我们想想,如果你在...

osc_u61lmlkv
今天
0
0
用Tableau实现动画数据可视化

作者|PRANAV DAR 编译|VK 来源|Analytics Vidhya 概述 动画可视化是一种艺术,它很容易在Tableau中创造出来 我们将在这里使用开源数据集,并在Tableau中创建自己的动画可视化 介绍 我是动画视...

osc_1oqjcug0
今天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部