iOS动画进阶 - 手摸手教你写ShineButton动画

原创 2017年02月16日 00:32:35

移动端访问不佳,请访问我的个人博客

前段时间在github上看见一个非常nice的动画效果,可惜是安卓的,想着用swift写一个iOS版的,下下来源代码研究了一下,下面是我写代码的心路历程

先上图和demo的地址

分析动画过程

刚开始看的时候感觉这个动画很炫酷,实现起来应该挺复制的,后来我将gif图逐一分解,浏览了一下安卓的实现过程,大致了解的实现的过程,下面是一些关键的动画步骤:

  1. 第一步是里面图片的缩放动画,使用CALayer配合CAKeyframeAnimation来实现;
  2. 第二步是是里面一个圆环逐渐变大的过程,使用CAShapeLayer配合CAKeyframeAnimation来实现;
  3. 第三步是最外面一层太阳的扩散效果同样也使用CAShapeLayer配合CAKeyframeAnimation来实现;
  4. 最后是闪烁和颜色变化的的效果,使用CABasicAnimationCADisplayLink来实现。

一、缩放动画的实现

这个实现的过程相对而言比较简单,用CALayer做为mask来实现下图心形的图片,然后用CAKeyframeAnimation来实现动画,values的值为[0.4, 1, 0.9, 1],差值器模式为kCAAnimationCubic,下面是实现结果和关键代码:

public func startAnim() {
    let anim = CAKeyframeAnimation(keyPath: "transform.scale")
    anim.duration  = animDuration
    anim.values = [0.4, 1, 0.9, 1]
    anim.calculationMode = kCAAnimationCubic
    maskLayer.add(anim, forKey: "scale")
}

二、圆环扩散动画的实现

首先圆环我们用CAShapeLayer来绘制一个圆环,然后通过CAKeyframeAnimation来改变圆环的path就可以了,下面是实现结果和关键代码:

public func startAnim() {
    let anim = CAKeyframeAnimation(keyPath: "path")
    anim.duration = params.animDuration * 0.1
    let size = frame.size
    let fromPath = UIBezierPath(arcCenter: CGPoint.init(x: size.width/2, y: size.height/2), radius: 1, startAngle: 0, endAngle: CGFloat(M_PI) * 2.0, clockwise: false).cgPath
    let toPath = UIBezierPath(arcCenter: CGPoint.init(x: size.width/2, y: size.height/2), radius: size.width/2 * CGFloat(params.shineDistanceMultiple), startAngle: 0, endAngle: CGFloat(M_PI) * 2.0, clockwise: false).cgPath
    anim.delegate = self
    anim.values = [fromPath, toPath]
    anim.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)]
    anim.isRemovedOnCompletion = false
    anim.fillMode = kCAFillModeForwards
    shapeLayer.add(anim, forKey: "path")
}

三、太阳的扩散效果实现

首先我们得先算出每个太阳的位置和将要扩散到的位置,然后用CAShapeLayer绘制出太阳,用CAKeyframeAnimation实现扩散的效果,下面是实现后的结果和关键代码 :

public func startAnim() {
    let radius = frame.size.width/2 * CGFloat(params.shineDistanceMultiple*1.4)
    var startAngle: CGFloat = 0
    let angle = CGFloat(M_PI*2/Double(params.shineCount)) + startAngle
    if params.shineCount%2 != 0 {
        startAngle = CGFloat(M_PI*2 - (Double(angle)/Double(params.shineCount)))
    }
    for i in 0..<params.shineCount {
        let bigShine = shineLayers[i]
        let bigAnim = getAngleAnim(shine: bigShine, angle: startAngle + CGFloat(angle)*CGFloat(i), radius: radius)
        let smallShine = smallShineLayers[i]
        var radiusSub = frame.size.width*0.15*0.66
        if params.shineSize != 0 {
            radiusSub = params.shineSize*0.66
        }
        let smallAnim = getAngleAnim(shine: smallShine, angle: startAngle + CGFloat(angle)*CGFloat(i) - CGFloat(params.smallShineOffsetAngle)*CGFloat(M_PI)/180, radius: radius-radiusSub)
        bigShine.add(bigAnim, forKey: "path")
        smallShine.add(smallAnim, forKey: "path")
    }
    let angleAnim = CABasicAnimation(keyPath: "transform.rotation")
    angleAnim.duration = params.animDuration * 0.87
    angleAnim.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    angleAnim.fromValue = 0
    angleAnim.toValue = CGFloat(params.shineTurnAngle)*CGFloat(M_PI)/180
    angleAnim.delegate = self
    add(angleAnim, forKey: "rotate")
}

四、最后再将这些动画通过一定规律结合起来

上图是将之前动画步骤组合起来后的效果,上面的一些代码只是部分代码,全部代码可以去我的github地址上去下在浏览,如果大家喜欢可以点一个start,有更好的想法也可以提出来,大家一起交流一下,最后谢谢大家阅读~~

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wang631106979/article/details/55230455

iOS 点击按钮的抖动动画

#pragma mark - **************** 列表中按钮点击动画效果 -(void)shakeToShow:(UIButton *)button{     CAKeyfr...
  • allanGold
  • allanGold
  • 2016-11-17 13:41:05
  • 1974

iOS UIButton按钮颜色渐变动画

self.rotateButton.imageView.alpha = 0.2; NSLog(@" rotateButtonImgChange "); [UIView ani...
  • elsonpeng
  • elsonpeng
  • 2016-10-12 14:38:52
  • 2911

iOS取消按钮点击时的动画效果

当存在图片或者背景图片时,点击图片往往意味着高亮,但是高亮的同时往往还伴随着按钮按下的动画效果,取消这种动画效果只需两步 Btn.adjustImageWhenHighlighted =NO; [...
  • u011342403
  • u011342403
  • 2017-03-03 13:38:40
  • 1088

UIButton自定义路径动画

之前看了一个别人做的汉堡动画的动效,非常有意思,然后在花瓣网上找了一个差不多的,自己尝试着做了一下。花瓣网上找的动效 最终代码实现的效果 https://github.com/BearRan/Ch...
  • xiongbaoxr
  • xiongbaoxr
  • 2016-03-14 23:53:18
  • 4964

iOS:CAAnimation动画集合:移动/旋转/缩放/弹簧/翻页效果/落叶动画

QuartzCore框架下CAAnimation的动画集合:移动、旋转、缩放、弹簧、组合动画以及各种翻页效果和落叶动画。移动- (void)move { // 位置移动 CABasic...
  • liuq0725
  • liuq0725
  • 2017-11-23 15:12:28
  • 661

iOS 简单动画效果实现的三种方式

【在ios开发中,动画是廉价的】 一、首尾式动画 代码示例: // beginAnimations表示此后的代码要“参与到”动画中 [UIView beginA...
  • iOSbird
  • iOSbird
  • 2016-06-27 23:45:42
  • 2851

iOS 自定义加载等待动画

一般来说,我们的项目中请求网络数据是一个比较耗时的操作,在请求的过程中如果给用户只展示空白的页面或者默认的页面,难免显得有些单调,这个时候我们可以添加一个指示动画,开始请求的时候运行动画,数据请求下来...
  • wbxiaowangzi
  • wbxiaowangzi
  • 2015-11-02 14:08:39
  • 3671

IOS 圆圈加载动画(中间带有文本,可放进度值等)

IOS 加载动画 进度条
  • u011154007
  • u011154007
  • 2016-10-31 12:49:33
  • 1246

iOS 动画解析 圆球加载动画 XLBallLoading

一、显示效果二、原理分析1、拆解动画从效果图来看,动画可拆解成两部分:放大动画、位移动画 放大动画 比较简单,这里主要来分析一下位移动画(1)、先去掉缩放效果:(2)、去掉其中的一个圆球现在基本可以...
  • u013282507
  • u013282507
  • 2017-04-12 19:43:28
  • 1812

iOS点击button放大后缩小效果,类似QQ、微信选择图片时的特效。

点击button放大后缩小效果,类似QQ、微信选择图片时的特效。          button.transform = CGAffineTransformIdentity; ...
  • sevenquan
  • sevenquan
  • 2016-03-30 11:21:28
  • 2956
收藏助手
不良信息举报
您举报文章:iOS动画进阶 - 手摸手教你写ShineButton动画
举报原因:
原因补充:

(最多只允许输入30个字)