转载自:http://blog.csdn.net/tianjian4592/article/details/47067161

前面两篇文章主要讲解了 Path 的概念和基本使用,今天我们一起利用 Path 做个比较实用的小例子;

上一篇我们使用 Path 绘制了一个小桃心,我们这一篇继续围绕着这个小桃心进行展开:

如果对这个桃心绘制有问题或有兴趣的同学,可以链接到 Path相关方法讲解(二),此时我们的需求是这样的:

假定我们现在是一个婚恋产品,有一个“心动”的功能,用户点击“心动”按钮的时候,有一个光点快速的沿着桃心转一圈,然后整个桃心泛起光晕!

针对这个需求,很多人可能会想到以下方案:

不就一个光点沿着桃心跑一圈么,既然桃心是使用贝塞尔曲线画出来的,那么我们就可以用对应的函数模拟出这条曲线,然后算出对应位置上的点,不断将光点绘制到对应的位置上!

这个思路当然没有问题,但我们还有相对简单的方式,那就是使用 PathMeasure:

我们主要使用它两个方法:

1.getLength() - 获取路径的长度

2.getPosTan(float distance, float pos[],float tan[]) - path 为 null ,返回 false

distance 为一个 0 - getLength() 之间的值,根据这个值 PathMeasure 会计算出当前点的坐标封装到 pos 中;

上面这句话我们可以这么来理解,不管实际 Path 多么的复杂,PathMeasure 都相当于做了一个事情,就是把 Path “拉直”,然后给了我们一个接口(getLength)告诉我们path的总长度,然后我们想要知道具体某一点的坐标,只需要用相对的distance去取即可,这样就省去了自己用函数模拟path,然后计算获取点坐标的过程;

接下来,我们用代码实现这一效果:

我们先创建一个 PathMeasure ,并将创建好的 path 作为参数传入

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);

然后用一个数组纪录点的坐标:
private float[] mCurrentPosition = new float[2];

向外暴露一个开启动效的接口:

// 开启路径动画
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();
}

实时获取到当前点之后,将目标绘制到对应位置:

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);
}

到这里目标环绕 path 的效果就ok了,不管这条路径简单也好,复杂也罢,我们都可以如此简单的完成对应的效果,而不需要自己用简单或复杂函数模拟求解了;

完成了一步,自己提的需求还有一点就是光晕的问题,这个东西如何是好呢?切图?! 不需要,Android 已经给我们提供了一个好用的东西 MaskFilter ,后面我就不做了,大家有兴趣自己做的玩玩,只需要注意一点,MaskFilter 不支持硬件加速,记得关掉!

好了,PathMeasure 看似很简单,但着实很有用,有了它,再结合上 Path 、Shader、ColorMatrix  等利器,我们已经可以做出很多酷炫的效果了!

最后,完整的代码献上,请笑纳:

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();

    }
}

以上代码的效果如下,其余效果大家自行补充:

PathMeasure打造万能路径特效 - 源码下载

PathMeasure打造万能路径动效相关推荐

  1. Path特效之PathMeasure打造万能路径动效

    转自:http://blog.csdn.net/u013831257/article/details/51565591 Path之玩出花样 作者微博: @GcsSloop [本系列相关文章] 可以看到 ...

  2. Android使用SVG矢量图打造酷炫动效!

    一个真正酷炫的动效往往让人虎躯一震,话不多说,咱们先瞅瞅效果: 如果你想看 GAStudio Github主页,请戳这里: 如果你想看 GAStudio更多技术文章,请戳这里: QQ技术交流群:277 ...

  3. 动效引擎_要做动效?这75款动效工具让你无所不能(上)

    原标题:要做动效?这75款动效工具让你无所不能(上) 动效这两年崛起非常之迅猛,几乎是网页设计领域最强大的设计趋势之一.无论是在设计师群体还是在用户当中,它的受欢迎程度都非常之高,大家都对它津津乐道. ...

  4. 动效素材极速交付: 腾讯PAG动效组件技术揭秘

    编者按:音视频产品中的动效素材需求是源源不断的,例如贴纸花字,转场特效,照片和视频模板等,并且对它们的产量,上线速度,以及视觉效果都有比较高的要求.但在传统工作流中的交付成本却非常高,需要通过代码来手 ...

  5. 动效设计原理:从卡通动画到UI动效

    UI是基于静态页面来设计的,页面之间通过跳转切换.在设计过程中,设计师很重视单页的视觉效果,却经常忽略了对界面跳转的处理.这些未经处理的跳 转由于没有提供足够的预期,所以用户在使用时经常会觉得困惑.与 ...

  6. 三看 SVG Web 动效

    CSS3 动效玩腻了吗?没关系的,我们还有 SVG. Welikesmall 是一个互联网品牌宣传代理,这是我见过的最喜欢使用 SVG 做动效的网页设计团队.事实上,越来越多的网页动效达人选择在 SV ...

  7. H5动效的常见制作手法 - 腾讯ISUX

    众所周知,一个元素,动往往比静更吸引眼球: 一套操作界面,合适的动态交互反馈能给用户带来更好的操作体验: 一个H5运营宣传页,炫酷的动画特效定能助力传播和品牌打造. 近两年,小到loading动画,表 ...

  8. lottie 导出html,Lottie Web动效基本原理

    前段时间在<Lottie Web动效在React中的构建>一文中和大家聊了如何通过lottie-web将AE导出来的JSON文件自动生成动效.在该文中,聊的主要是设计软件Figma.Ske ...

  9. 行业思考 | 酷炫动效是否利于你的产品设计?

    本文为PMCAFF专栏作者南可出品 前言 写这篇文章的起因是前段时间在Meidum上读到的一篇驳斥dribbble发展现状的文章.文章发表在16年,其中提到:"我不认为dribbble解决了 ...

  10. HTML5培训教程学习之动效制作

    近年来,HTML5应用愈发广泛,并有取代Flash的趋势.很多人知道利用HTML5可以做出好的动作效果,但你知道它是怎么做出来的吗?今天小千就来给大家分享一下HTML5培训教程中动效制作的几种方法. ...

最新文章

  1. 并行机调度问题matlab,顺序依赖并行机调度问题介绍
  2. ArcServer for Java 讲座
  3. jdk javac运行不了_Intellij IDEA搭建jdk源码阅读环境
  4. U盘为什么还有剩余空间,但却提示说空间不够
  5. PyQt5 技术篇-QWidget、Dialog设置界面固定大小、不可拉伸方法实例演示
  6. 大规模微服务利器:eBPF + Kubernetes
  7. Spring系列(二):Bean注解用法介绍
  8. SQL- AND OR Order by INSERT INTO
  9. Java 设计模式之Mediator调节者模式
  10. “System.AccessViolationException”类型的未经处理的异常在 System.Data.dll 中发生
  11. PHP表单常用正则表达式(URL、HTTP、手机、邮箱等)
  12. DataScience:风控场景之金融评分卡模型构建—将逻辑回归LoR模型结果转为评分卡之详细攻略
  13. python与开源gis空间分析_Python 与开源GIS:数据处理、空间分析与地图制图
  14. h5制作导出html,H5制作工具Hype的导出功能详解
  15. 企业服务器系统怎么做,如何搭建一个小型企业服务器机房?6个步骤学起来!...
  16. JavaScript 教程「2」:注释、输入输出、变量
  17. 驱动精灵 v9.61 去广告最终版绿色清爽单文件
  18. 扫地机器人哪个牌子好?合格的扫地机器人推荐
  19. 记录【1】Vue遇到的bug , 点击按钮出现Cannot read property 'toString' of undefined的解决方法
  20. sql server2008处理笛卡儿积的逻辑——记一次解决疑惑

热门文章

  1. Unity 接入旷视Face进行人脸融合
  2. 微信小程序开发需要哪些技术?
  3. 字体如何设计,这几点很重要
  4. Python递归绘制谢尔宾斯基三角形
  5. 清华大学计算机考研信息汇总
  6. 程序员有文化,多可怕!
  7. excel如何实现中文单词自动翻译成英文?这个公式教你了
  8. Microsoft Lync2013客户端下载
  9. [Lync]lync同步通讯簿
  10. 【Jmeter配合switchyomega 脚本录制】