美文网首页实用轮子iOS DeveloperiOS开发
QQ黏性动画(神奇的形变BadgeValue动画效果)--iOS

QQ黏性动画(神奇的形变BadgeValue动画效果)--iOS

作者: ZhengYaWei | 来源:发表于2017-01-01 00:22 被阅读278次

       今天跨年,就在跨年中写篇博客吧。因为从上海转战广州,在广州认识的人太少,所以即使是跨年也没什么事,所以暂时只和技术为伴。先看一下动画效果,源代码链接:https://github.com/ZhengYaWei1992/QQStickAnimation

qq黏性动画

       以上这种效果可能在消息提示的时候会使用到,如即时通讯的消息提示按钮或者用于代替主界面的badgeValue。

        先剖析一下这个动画的结构,表面上看起来主要部分是一个带有数字的红色控件模块,外加一个爆炸的动画(说明:爆炸的实际上是想做成动画效果的,无奈找不到合适的素材,所以用💥代替)。实际上红色的部分主要是由三部分组成,分别为:带有数字的按钮UIButton、由一个路径转换而成的CAShapeLayer形变效果、形变效果图的尾端的另一个红色的圆形UIView。这里要注意,形变效果的另一末尾端是一个红色的圆形UIView,只是有一半和形变图形重叠。随着圆形UIButton拖动距离增加,红色的圆形UIView的半径组件变小,当距离超过一个特定范围的时候,红色的圆形UIView以及形变的CAShapeLayer会消失。最后松开手指的时候会出现爆炸💥的动画。

        再说下这种动画所用到的技术。

        一、毫无疑问首先会用到拖动手势,很多拖动逻辑的都是在UIPanGestureRecognizer的手势事件中进行判断的。

        二、运用数学中的股股定理计算重要的点坐标。然后通过UIBezierPath绘制填充路径。下面会详细讲解如何计算重要点的坐标值。

        三、CAShapeLayer的应用,主要是把路径转换成图形,也就是效果图中的形变效果。其实核心代码也就只是一句。

    具体实现:

    1、 首先创建一个继承于UIButton的类(圆形带数字的红色UIButton),然后通过重载将父视图的View传过来。

- (instancetype)initWithFrame:(CGRect)frame withSuperView:(UIView *)badgeSuperView{

       if (self == [super initWithFrame:frame]) {

               self.bageValueSuperView = badgeSuperView;

                [self setup];

          }

                 return self;

}

2、设置圆形带数字的红色UIButton的相关属性,然后为这个按钮添加上UIPanGestureRecognizer拖动手势。另外还要创建形变效果图的尾端的另一个红色的圆形UIView对象以及相关属性。这一步实际就是上面的[self setup];方法的实现。

3、接下来看一下拖动手势中的代码。相关注释在代码中

- (void)pan:(UIPanGestureRecognizer *)pan{

          CGPoint tranP = [pan translationInView:self];

          CGPoint center = self.center;

           center.x += tranP.x;

           center.y += tranP.y;

           self.center = center;

            [pan setTranslation:CGPointZero inView:self]; 

            //这个方法主要是计算圆形UIButton和圆形UIView的中心点之间的距离

           CGFloat distance = [self distanceWithSmallCicle:self.smallCircle bigCircle:self];

          //这里设置小圆半径随着距离拉大而缩小

          CGFloat radius = self.bounds.size.width * 0.5;

           radius -= distance/10.0;

          self.smallCircle.bounds = CGRectMake(0, 0, radius * 2, radius * 2);

          self.smallCircle.layer.cornerRadius = radius;

/*******************路径转为形状******************************/

        if (self.smallCircle.hidden == NO) {

                //这里是计算形变路径关键的六个点,然后返回一个路径的方法,具体计算下面会有图解。把路径转换成图形shapeLayer可以根据路径生成形状。shapeLayer是CAShapeLayer的实例对象。

                    UIBezierPath *path = [self pathWithSmallCircle:self.smallCircle bigCircle:self];

                   self.shapeLayer.path = path.CGPath;

                    [self.bageValueSuperView.layer insertSublayer:_shapeLayer atIndex:0];

         }

/**********************关键业务逻辑处理*****************************/

              //拖动距离大于60的话就隐藏形变路径和红色UIView

           if (distance > 60) {

                   self.smallCircle.hidden = YES;

                  [self.shapeLayer removeFromSuperlayer];     

           }

//拖动结束,距离大于60就隐藏所有控件,展示爆炸动画。小于60就展示原本的状态

          if (pan.state == UIGestureRecognizerStateEnded) {

                    if (distance < 60) {

                          self.center = self.smallCircle.center;

                         self.smallCircle.hidden = NO;

                          [self.shapeLayer removeFromSuperlayer];

                     }else{

                           //播放一个动画,动画执行完毕,移除所有控件。

                          //动画代码这里省略,具体可以下载源代码。源代码下载链接在最上方

                    }

           }

}

     4.这里就主要来剖析一下,形变区域的相关计算问题。

形变区域图解

      绘制红色形变区域关键的一步是计算出图中A、B、C、D、O、P四个点的位置,其中O和P点分别为AD何BC曲线的控制点。计算出六个点的位置后,便可通过贝塞尔曲线连接六个点,最后关闭路径、添加填充,便可形成一个封闭图形。六个点的具体计算是通过勾股定理计算,计算六个点的坐标,图中的辅助线很重要。根据辅助线我们不难发现凡是图中标记为Θ的角度,他们的值都相等。通过两个圆的圆心位置,不难计算出Θ值。根据Θ值以及圆心位置,便可轻而易举的计算出A、B、C、D四个点的值。另外还需要注意的是,OP的连线垂直于两个圆心所在的直线,且OA和BP的长度为两个圆心距离的一半,进而根据OA和BP外加图中的虚线辅助线,可分别计算出O点和P点圆心所在的位置。最后便可形成一个封闭区域。说了这么多,接下来可以下载一下源代码研究下。链接见上方😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀v😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀新年快乐!!!!!

相关文章

网友评论

    本文标题:QQ黏性动画(神奇的形变BadgeValue动画效果)--iOS

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