美文网首页自定义控件UI效果
Android元素分散-飘移-聚合动效

Android元素分散-飘移-聚合动效

作者: 寻水的鱼Chock | 来源:发表于2022-08-31 16:27 被阅读0次

效果预览

元素分散-飘移-聚合动效.gif

功能说明

  • 使用Canvas绘制元素移动动效,极致高效;
  • 支持任意方向元素漂移(起点、终点任意);
  • 支持修改元素图标及其大小(单位dp);
  • 支持修改动效持续时间及动画结束时回调;
  • 支持修改元素飘动个数;

使用方式

  • 在工程根目录的build.gradle中添加
allprojects {
    repositories {
        maven { url 'https://www.jitpack.io' }
        ...
    }
}
  • 添加依赖
implementation 'com.gitee.chockqiu:animation-views:1.1'
  • 在xml中添加布局
<com.chockqiu.view.ElementFloatTogetherAnimation
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
  • 确定起点及终点,开始动画&处理回调
val p0 = Point().apply {
    x = (viewStart.left + viewStart.right) / 2
    y = (viewStart.top + viewStart.bottom) / 2
}
val p1 = Point().apply {
    x = (endView.left + endView.right) / 2
    y = (endView.top + endView.bottom) / 2
}
mElement.startAnimation(p0, p1) {
    ...
}

PS: 为了起/终点坐标与预期一致,建议将View放置在跟起点终点View同一个ViewGroup中,并且动效View的宽高与ViewGroup一致,也就是match_parent(动效内部坐标系是以自身左上角为坐标原点进行绘制的),如不一致需要进行坐标转换。

实现原理

利用二阶贝塞尔曲线控制点决定曲线路径的特性,通过算法生成每一个元素的控制点,实现不同元素通过不同的路径从起点飘向终点,再加上不同元素移动动画开始的时间差,最终组合实现这么一种效果。

二阶贝塞尔曲线原理图如下:


二阶贝塞尔曲线原理图.gif

实现步骤

1)实现二阶贝塞尔曲线数学公式;


二阶贝塞尔曲线数学公式.png

具体实现详见quadToFunValue(float t, Point p0, Point p1, Point p2)函数。


2)通过算法生成每个元素的控制点,为了好看控制点需在起点与终点所在直线的中垂线上随机分布;

所以最终控制点是一个与中点M(Mx,My)距离为D的坐标,且它所在的直线是起点与终点所在直线的中垂线。

控制点计算原理.png

如何计算控制点坐标呢?
首先通过起点终点所在的直线可以计算出中垂线的斜率k2:

private double centerk(Point a, Point b) {
    //已知A(Ax,Ay),B(Bx,By); 中垂线的斜率为:
    //-1/k=-1/[(By-Ay)/(Bx-Ax)]=-(Bx-Ax)/(By-Ay)
    if (b.y == a.y) {
        return 0;
    }
    if (b.x == a.x) {
        return Double.MAX_VALUE;
    }
    return -(((b.x - a.x) * 1f / (b.y - a.y)));
}

已知随机的确定正值D,可以计算出控制点与坐标中点M(Mx,My)的坐标距离dx和dy, 数学公式如下:
等式1: dy/dx = k2
等式2: dx*dx + dy*dy = D*D
只要起点/终点确认, 则k1是一个定值,那么它的中垂线斜率k2也是定值,再加上随机的正值D,经过转换可得
dx = D*D/(k2*k2+1)
dy = (D*D*k2*k2)/(k2*k2+1)

/**
 * 斜率k时距离d对应的dx值
 *
 * @param k 斜率k
 * @param d 距离d
 * @return
 */
private double dx(double k, double d) {
    if (k == 0) {
        return 0;
    }
    if (k == Double.MAX_VALUE) {
        return d;
    }
    double dx = Math.sqrt((d * d) / (k * k + 1));
    if (d < 0) {
        return -dx;
    } else {
        return dx;
    }
}

/**
 * 斜率k时距离d对应的dy值
 *
 * @param k 斜率k
 * @param d 距离d
 * @return
 */
private double dy(double k, double d) {
    if (k == 0) {
        return d;
    }
    if (k == Double.MAX_VALUE) {
        return 0;
    }
    double dy = Math.sqrt((d * d) * (k * k) / (k * k + 1));
    if (d < 0) {
        return -dy;
    } else {
        return dy;
    }
}

在根据起点(Sx,Sy)、终点(Ex,Ey)的朝向不同,确定dx与dy的符号,可能是-dx,-dy,也可能是dx,-dy等等
最终得到控制点的精确坐标值;

控制点坐标.png
如果本文对你有帮助就点个赞支持下吧~~~

相关文章

  • Android元素分散-飘移-聚合动效

    效果预览 功能说明 使用Canvas绘制元素移动动效,极致高效; 支持任意方向元素漂移(起点、终点任意); 支持修...

  • 7/50最近在学3D动效

    在学两个3D动效,一个动效是比较简单的几个小球在转,当作入门,一个是犀牛从分散点和线聚合起来,成一个框架的动画效果...

  • 些优质移动app动效设计的建议

    一些优质移动app动效设计的建议: 1.动效不应分散用户在屏幕上重要功能上的注意力。 2.设计动效时应该考虑到应用...

  • Android Material 动效

    Material Design 组件实现 Material 动效[https://mp.weixin.qq.com...

  • #每日APP简评# SmartNews

    最初是因为动效而听闻了新闻聚合应用SmartNews(和今日头条类似的个性化聚合新闻应用) 产品初衷 Ken Su...

  • 在Axure文档中导入动效视频

    我们都遇到过如何跟开发讲清楚动效设计的问题。最近在优化云音乐Android平台的动效,Material Desig...

  • 5. Java NIO Scatter/Gather(分散/聚合

    Java NIO有内置的分散/聚合(Scatter/Gather)功能。分散聚合的概念应用场景为从channel读...

  • 2020-04-12

    Android 实现水波纹动效 ​ WaterRippleView核心文件 package com.manss.m...

  • 论状态动效中的信息传递

    首先我们简单的先将游戏内动效分为两类:“状态”动效和“行为”动效。状态动效:永远单向传递信息行为动效:动效基于交互...

  • 怎么让自己显得是一个设计老鸟

    风格定义 设计定位 规范执行 理论技巧 锦上添花_动效、手绘 所用到元素的依据

网友评论

    本文标题:Android元素分散-飘移-聚合动效

    本文链接:https://www.haomeiwen.com/subject/wtgigrtx.html