美文网首页iOS进阶iOS开发iOS的UI进阶
QQ消除小红点(一键退朝)动画。

QQ消除小红点(一键退朝)动画。

作者: AidenRao | 来源:发表于2016-03-28 13:58 被阅读1925次

本来只是想写个可以拖动的小红点的,但写出乐趣来了,所以就多研究了研究,最后干脆封装了一下,可以实现给所有 View 添加黏贴效果。
GitHub 链接
效果如图:

11-22-34.jpg

一个控制点的取了两次点,才绘制出贝塞尔曲线,所以称为二次曲线,两个控制点的取了三次点,所以称为三次曲线。

绘制贝塞尔曲线有一个数字需要记住,3.6。

三阶贝塞尔曲线拟合1/4圆

即 AB 和 CD 都垂直于 AD,AB 和 CD 的距离为 AB 距离的 1/3.6,绘制出的弧线是一个非常接近 1/4 圆的弧线。

实现思路:
需要绘制黏贴效果
拖动的 View 需要盖住其它所有其它的 View
根据拖动的距离判断松手时是需要爆炸动画还是回弹动画。

效果如下

11-31-30.jpg

转换成模型图如下


11-34-14.jpg

小圆是小红点一开始的位置,大的圆是小红点拖过去的位置,小圆随着拖动距离增大而变大,两个圆的连接其实就是两贝塞尔曲线,临时点 point_temp 根据两个圆距离的增加从 p2 向 p4 移动,连接临时点和 P1 连线中点 P5 就是控制点了,即可绘制出这条贝塞尔曲线,p3 和 p5 之间的贝塞尔曲线同理。

接下来就是计算各个点的坐标了,捡起高中的数学,还是很简单的。得出各个点的坐标,然后绘制一个大圆一个小圆,中间绘制两条贝塞尔曲线,给上填充颜色。黏贴效果就出来了。每次拖动 View 的时候再重新绘制一遍。

11-47-42.jpg


需要让拖动的 View 覆盖在所有 View 上方,这个还是很重要的,要不然在 tableViewCell 里进行拖动的时候,会被其它的 Cell 盖住,我的实现方式是声明一个全屏大小的 RedDotView 添加到 [[[UIApplication sharedApplication].delegate window] 上,然后将拖动的 View 拷贝一份,放置到 RedDotView 上方,隐藏旧 View。这样拖动的 View 就能盖住所有其它的 View ,包括导航栏。

拷贝我取了个巧,直接将旧 View 绘制成一张 image,放置到新 View 上显示,

- (UIImage *)getImageFromView:(UIView *)view {
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, UIScreen.mainScreen.scale);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

爆炸效果则是给 imageView 的 animationImages 属性添加六张图片,在超出最大距离之后播放。

    NSMutableArray *array = [[NSMutableArray alloc] init];
    for (int i = 1; i < 6; i++) {
        UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"red_dot_image_%d", i]];
        [array addObject:image];
    }
    UIImageView *imageView = [[UIImageView alloc] init];
    imageView.frame = CGRectMake(0, 0, radius*2, radius*2);
    imageView.center = explosionPoint;
    imageView.animationImages = array;
    [imageView setAnimationDuration:0.25];
    [imageView setAnimationRepeatCount:1];
    [imageView startAnimating];
    [self addSubview:imageView];
    ```
    
回弹效果是给 View 一个弹簧动画,让 View 弹回旧 View 中心的位置
```objc
    [UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.2 initialSpringVelocity:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        view.center = point;
    } completion:^(BOOL finished) {
        ......
    }];
    ```
总结:还是有些遗憾,做完之后才注意到 QQ 的实现上,p1 和 p3 连线并不经过圆心,所以效果和 QQ 的还是有些差别,另外为了让中间的贝塞尔曲线不会和大圆重合,中间的贝塞尔曲线我用的是两条贝塞尔曲线实现,这样更圆滑一些,但也留了个坑,中间的弧度还是得再调整一下。

参考资料:
[QQ手机版 5.0“一键下班”设计小结](https://isux.tencent.com/qq-mobile-off-duty.html)

相关文章

  • QQ消除小红点(一键退朝)动画。

    本来只是想写个可以拖动的小红点的,但写出乐趣来了,所以就多研究了研究,最后干脆封装了一下,可以实现给所有 View...

  • 高仿QQ红点消除动画

    前言 一直觉得qq的红点动画比较叼,今天研究了一下,主要是绘制不规则图形和左右晃动动画,希望可以帮到你们. 废话不...

  • iPhone 微信快速消除未读消息小红点

    问题 微信没有一键已读功能,对话列表中未读消息的小红点一多,对于笔者这样的强迫症来说真的很难忍受,要想消除这些小红...

  • QQ小红点

    QQ小红点消息气泡拖来拽去是不是很有意思?这篇文章主要介绍QQ小红点消息气泡库的实现,实现后的效果是使用简单,功能...

  • 【算法分析】QQ“一键退朝”之详细计算方法

    Tips:由于简书好像不支持Latex公式,所以为了效果,有关公式部分截取了我发表在CSDN上的博文,地址:AZZ...

  • Android 贝塞尔曲线,QQ 删除小红点类似效果实现

    看到 QQ拖动删除小红点的动画效果,就想着做个类似的效果,没找到Android 版的教程,于是就自己撸了一个,代码...

  • 小红点

    有时 太阳是个小红点 国土在地图上是个小红点 小红点 是指路的明灯 是跳动的火焰 我也有许多小红点 QQ、微信、微...

  • 通知到来,各级页面添加小红点

    需求描述 微信消息列表中的小红点为一级小红点点击订阅号后,订阅列表页面为二级小红点点击某一个订阅号后,消除该订阅号...

  • QQ杂音消除

    http://jingyan.baidu.com/article/a3761b2b8c013a1576f9aad1...

  • QQ小红点(二) DragPointView

    传送门 https://github.com/javonleee/DragPointView 前言 之前写了自定义...

网友评论

  • manajay:讲解很仔细
  • DrunkenMouse:楼主,我今天把感兴趣的几个功能全部实现并理清了思路,感觉可以给你几个意见,还望不要介意。
    RedDot:可直接在cellModel的set方法里判断有无此值,有就创建控件并赋值 没有就不创建。

    获取一个View的显示内容也可以直接通过View的对象方法,snapshotViewAfterScreenUpdates直接获取到

    常用的方法可以封装到一个延展类中,需要时导入或直接放入到宏定义里

    获取字符串所需大小的简单设置
    CGSize size = [_buttonTitle sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:24],NSForegroundColorAttributeName:[UIColor whiteColor]}];

    GooeySlide里的圆弧路径,我看楼主你写的有点乱,就整理了一下
    路径经过的关键点大致为:从自身左上角的(0, 0)
    开始addLineTo(_keyWindow.frame.size.width/2,0),依次为起点绘制一个圆弧,圆弧终
    点为(_keyWindow.frame.size.width/2,_keyWindow.frame.size.height),最后又画
    到(0,_keyWindow.frame.size.height)闭合路径。
    由于控制曲线弯曲的点是幕中间位置的x+_diff,而diff初始时又为0,所以此时没有圆弧显示
    AidenRao:@DrankMouse 非常非常感谢,明天认认真真看看,:smile:
  • 257f312dccb8:没钱打赏,就只能默默喜欢下了!
  • 8bef82b761ae:初中几何没学:sweat:
    AidenRao:@梦儿飘 快高考,翻出书来看看
  • 一缕殇流化隐半边冰霜:厉害!!大神请收下我的膝盖!!看了你的JMAnimationDemo,膜拜!!
    AidenRao:@一缕殇流化隐半边冰霜 不是鼻涕效果吗:sweat_smile:
    一缕殇流化隐半边冰霜:@饶志臻 哈哈。。看过的!!那个果冻效果确实当时一眼看了惊人!!:kissing_heart::kissing_heart:
    AidenRao:@一缕殇流化隐半边冰霜 大部分是看kitter yang的<<A GUIDE TO IOS ANIMATION2.0>>写的,你可以买本这个书学着也写写
  • f8fe5ea845a3:能否留下代码对应的模型图,含有代码中ABCDEF等那些点的模型图。
    AidenRao:@masterkk 。我没有模型图,自己在纸上画的关键点。。。主要是了解一下实现思路,你想写的话可以自己设置关键点的位置。
  • e5c9d7c978e9:不明觉厉,原来一个消息的红点,背后还有这么多知识啊?还以为就只是一个小动画而已😁😁😁
  • 553b48ed1016:不明觉历。
  • 跬步千里_LenSky:写的好厉害!好酷!
    AidenRao:@成王拜扣 :smile:谢谢
  • Ryan文濤:那串算法看得好懵。。。
  • 遛遛食:🐂🐂🐂

本文标题:QQ消除小红点(一键退朝)动画。

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