放yy直播点赞动画

简介: 最近在做直播相关的东西,这个动画是IOS先撸出来的,后来android这边要模仿,大部分直播应用都有很炫酷的点赞动画,所以也没什么好稀奇的。如果有现成的轮子了,就没必要自己再造了,后来参照了程序亦非猿的实现,做了些修改,最终效果还不错。 live.gif 刚开始自己造轮子的时候也走了些弯路,最初是给这些图标一些随机的初始速度和偏移量然后慢慢上升,效果总是不大好,差了点意思。后来仔

最近在做直播相关的东西,这个动画是IOS先撸出来的,后来android这边要模仿,大部分直播应用都有很炫酷的点赞动画,所以也没什么好稀奇的。如果有现成的轮子了,就没必要自己再造了,后来参照了程序亦非猿的实现,做了些修改,最终效果还不错。


live.gif

刚开始自己造轮子的时候也走了些弯路,最初是给这些图标一些随机的初始速度和偏移量然后慢慢上升,效果总是不大好,差了点意思。后来仔细研究发现这些图标上升的路线并不是直线,而是一个三阶贝塞尔曲线。

  一阶贝塞尔曲线,实际上就是一条连接两点的直线段。
  二阶贝塞尔曲线,就是两点间的一条抛物线,利用一个控制点来控制抛物线的形状。
  三阶贝塞尔曲线,则需要一个起点,一个终点,两个控制点来控制曲线的形状。

三节贝塞尔曲线的公式


公式.png

公式中:P0,是我们的起点,P3是终点,P1,P2是途径的两个点,而t则是一个因子,取值范围是0-1。
整个曲线的生成过程


过程.gif

实现代码如下,调用的时候只需要在构造方法中传入两个随机点即可。

    public class BesselEvaluator implements TypeEvaluator<float[]> {
        private float point1[] = new float[2], point2[] = new float[2];

        public BesselEvaluator(float[] point1, float[] point2) {
            this.point1 = point1;
            this.point2 = point2;
        }

        @Override
        public float[] evaluate(float fraction, float[] point0, float[] point3) {
            float[] currentPosition = new float[2];
            currentPosition[0] = point0[0] * (1 - fraction) * (1 - fraction) * (1 - fraction)
                    + point1[0] * 3 * fraction * (1 - fraction) * (1 - fraction)
                    + point2[0] * 3 * (1 - fraction) * fraction * fraction
                    + point3[0] * fraction * fraction * fraction;
            currentPosition[1] = point0[1] * (1 - fraction) * (1 - fraction) * (1 - fraction)
                    + point1[1] * 3 * fraction * (1 - fraction) * (1 - fraction)
                    + point2[1] * 3 * (1 - fraction) * fraction * fraction
                    + point3[1] * fraction * fraction * fraction;
            return currentPosition;
        }
    }

详细的动画实现可以参考一步一步教你实现Periscope点赞效果,但很显然我这里完成点赞动画,任务还没有完成。有几个问题需要解决:允许连续点赞,而且是计数的,什么时候把点赞的数量抛给服务器;我怎么看到其他用户点赞,或者其他用户怎么看的到我点赞。

先看第一个问题吧,什么时候把点赞数量抛给服务器?由于产品经理带着小姨子跑路了,Ios和android两个端的策略还不太一样,但我们达成的基本共识就是:不能点一次抛一次,抛的次数越少越好。Ios是本地维护一个count,没隔一段时间检测count有增加,就抛一次。android这里是连续点击的时间间隔大于一个约定值,就认为本轮点赞结束,然后抛一次。以前有研究过单击双击,这次连续点击也来了,该来的总要来的。

public class MainActivity extends AppCompatActivity {

    long mLastTime = 0;
    long mCurTime = 0;
    private final int DELAY = 500;//连续点击的临界点
    BubbleView bubbleView;
    private int mClickCount = 0;
    private int currLikeCount;
    private TextView likeCount;
    private Timer delayTimer;
    private TimerTask timeTask;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            praiseRequest(mClickCount);
            delayTimer.cancel();
            super.handleMessage(msg);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        bubbleView=(BubbleView)findViewById(R.id.praise_anim);
        bubbleView.setDefaultDrawableList();
        likeCount = (TextView) findViewById(R.id.like_count);
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                mCurTime = System.currentTimeMillis();
                if (mCurTime - mLastTime < DELAY) {
                    mClickCount++;
                } else {
                    mClickCount = 1;
                }
                currLikeCount++;
                likeCount.setText(String.valueOf(currLikeCount));
                delay();
                mLastTime = mCurTime;
                bubbleView.startAnimation(bubbleView.getWidth(), bubbleView.getHeight());
            }
        });
    }

    private void delay() {
        if (timeTask != null)
            timeTask.cancel();

        timeTask = new TimerTask() {
            @Override
            public void run() {
                Message message = new Message();
                mHandler.sendMessage(message);
            }
        };
        delayTimer = new Timer();
        delayTimer.schedule(timeTask, DELAY);
    }

    /**
     * 点赞请求网络
     */
    private void praiseRequest(int count) {

    }
}

第二个问题由于暂时没条件做推送,所以只能客户端每隔一段时间轮一次接口了,如果相比较上次数量有增加,动画上就弹出相应数量的爱心数,这里就需要给屏幕上允许出现的爱心数量设置一个最大值,要不然一瞬间弹出几百个甚至上千个肯定要悲剧了。


576DB36E-F179-47A0-A216-8C05381BCC94-1540-0000D86DB0CDA3D2.gif

后期将做进一步的拓展,实现详情效果

目录
相关文章
|
9月前
在PPT中制作倒计时效果,第二弹!
该视频中介绍的方法是使用PPT的加载项功能来完成。使用此方法问题还是比较多,比如可能制作时加载不出倒计时控制,也可能播放时一片空白……
74 2
在PPT中制作倒计时效果,第二弹!
|
10月前
|
JSON 自然语言处理 前端开发
用D3制作一张有翻页特效的手撕日历(只需100行代码)
在D3中用十分简单的代码就可以实现丰富的动画,下面来看一下手撕日历的动画效果吧
191 1
用D3制作一张有翻页特效的手撕日历(只需100行代码)
|
6月前
30行代码实现微信朋友圈自动点赞
首先祝大家新年快乐,过年了,允许我水一篇博客。不知道大家都回老家了没,不过我是没有回去,晚上吃完年夜饭看到很多人发朋友圈,为了增进和大家的友谊,于是就想着给大家点个赞,无奈内容太多了,就搞个自动化脚本,原理和前两天我写的30行代码实现蚂蚁森林自动偷能量一样,这里不再赘述,直接上代码。
97 1
|
9月前
|
iOS开发 MacOS Windows
视频 | 把万彩动画中的卡通人物放入PPT中
我试过window下的剪辑软件pr、剪映、达芬奇,都不能成功导出透明背景的GIF图片,最后在MacOS下用Final cut pro和Compressor成功导出了。
169 1
|
12月前
|
小程序 开发者
如何实现一个好看的金币效果
如图,是我最新上线的游戏【彩虹星球大冒险】中的金币拾取效果,打金币作为这个游戏中的一个非常重要的体验,把金币拾取效果做的好看就显得尤为重要。今天就跟大家分享一个,如何实现一个这样好看的金币拾取效果。 观察一下上面的动图,金币从出现到消失总共是分为两个过程的。 金币从爆炸的物体中向上弹出,并进行旋转下落 玩家碰到金币后,金币放大旋转然后飞到屏幕的左上角记录金币的位置后消失 接下来我们以一个具体的实例,来逐步的实现整个金币效果。
140 0
如何实现一个好看的金币效果
|
前端开发
前端知识学习案例7-开发企业网站7-实现轮播标题依次动画
前端知识学习案例7-开发企业网站7-实现轮播标题依次动画
51 0
前端知识学习案例7-开发企业网站7-实现轮播标题依次动画
|
前端开发 容器
#yyds干货盘点# 前端歌谣的刷题之路-第一百四十八题-三列布局-绝对定位
#yyds干货盘点# 前端歌谣的刷题之路-第一百四十八题-三列布局-绝对定位
50 0
#yyds干货盘点# 前端歌谣的刷题之路-第一百四十八题-三列布局-绝对定位
|
前端开发 容器
#yyds干货盘点# 前端歌谣的刷题之路-第一百四十七题-三列布局-浮动
#yyds干货盘点# 前端歌谣的刷题之路-第一百四十七题-三列布局-浮动
66 0
#yyds干货盘点# 前端歌谣的刷题之路-第一百四十七题-三列布局-浮动
|
JavaScript 数据可视化 虚拟化
用贪吃蛇小游戏的思路手写一个无限循环滚动轮播图
在某些业务场景下,接入第三方库实现轮播图效果可能并没有那么好用,笔者在接入Swiper插件失败后,还是决定手写一个。那么关于手写轮播图有很多文章已经讲过了,其核心原理是将图片排成一排,设置外层的Div超出隐藏,然后改变定位来实现轮播效果,这样通常不能首尾循环滚动,本文记录了一种对无限循环滚动效果的实现方式。
|
前端开发
#yyds干货盘点 前端歌谣的刷题之路-第十四题-设置盒子的一个宽和高
#yyds干货盘点 前端歌谣的刷题之路-第十四题-设置盒子的一个宽和高
78 0
#yyds干货盘点 前端歌谣的刷题之路-第十四题-设置盒子的一个宽和高