iOS动画进阶 - CAKeyframeAnimation实现过山车动画

原创 2016年06月22日 22:34:59

如果移动端访问不佳,可以访问我的个人博客

偶然间在网页上看到一个过山车动画觉得很炫,就想用swift纯代码实现了一个类似的效果,因为没有设计天赋,所以就完全高仿的人家的效果-.-下面上效果图:

wcl.gif

给大家介绍一下项目中主要会用到的类:

  • CAShapeLayer
  • CAGradientLayer
  • CAKeyframeAnimation

实现的主要思路

渐变的背景用CAGradientLayer实现,其他例如山峰,草坪和轨道可以用CAShapeLayer配合UIBezierPath实现,然后云朵,树木和大地直接用CALayer通过设置contents实现,然后云朵和过山车的动画实现用CAKeyframeAnimation,这样分析其实做一个这样的动态效果并不是很难,下面就是实现过程和简单的代码示例。下载demo有完整代码

CAGradientLayer

CAGradientLayer是用来生成两种或更多颜色平滑渐变的。相比于Core Graphics来说CAGradientLayer的真正好处在于绘制使用了硬件加速。这说明通过CAGradientLayer来绘制渐变的效果比用Core Graphics的效率更高。我们通过CAGradientLayer来实现这个项目中的背景下载demo有完整代码

//初始化背景
    func initGradientLayer(size:CGSize) -> CAGradientLayer {
        let layer:CAGradientLayer = CAGradientLayer()
        layer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height - 20)
        //设置渐变的颜色
        layer.colors = [UIColor.init(colorLiteralRed: 178.0/255.0, green: 226.0/255.0, blue: 248.0/255.0, alpha: 1.0).CGColor, UIColor.init(colorLiteralRed: 232.0/255.0, green: 244.0/255.0, blue: 193.0/255.0, alpha: 1.0).CGColor]
        //设置渐变的方向为从左上到右下
        layer.startPoint = CGPoint(x: 0, y: 0)
        layer.endPoint = CGPoint(x: 1, y: 1)
        view.layer.addSublayer(layer)
        return layer
    }

屏幕快照 2016-06-22 上午12.16.14.png

CAShapeLayer

CAShapeLayer是一个通过矢量图形而不是bitmap来绘制的图层子类。你指定诸如颜色和线宽等属性,用CGPath来定义想要绘制的图形,最后CAShapeLayer就自动渲染出来了。当然,你也可以用Core Graphics直接向原始的CALyer的内容中绘制一个路径,相比直下,使用CAShapeLayer有以下一些优点:

  • 渲染快速。CAShapeLayer使用了硬件加速,绘制同一图形会比用Core Graphics快很多。

  • 高效使用内存。一个CAShapeLayer不需要像普通CALayer一样创建一个寄宿图形,所以无论有多大,都不会占用太多的内存。

  • 不会被图层边界剪裁掉。一个CAShapeLayer可以在边界之外绘制。你的图层路径不会像在使用Core Graphics的普通CALayer一样被剪裁掉(如我们在第二章所见)。

  • 不会出现像素化。当你给CAShapeLayer3D变换时,它不像一个有寄宿图的普通图层一样变得像素化。

我们用CAShapeLayer来绘制草地,山坡和过山车的轨道,下面给大家通过绘制草坪的代码简单介绍一下用法下载demo有完整代码

//初始化草坪
    func initGrasslandlayer(size:CGSize) -> CAShapeLayer {
        let grasslandOne = CAShapeLayer()
        //通过UIBezierPath来绘制路径
        let pathOne:UIBezierPath = UIBezierPath()
        pathOne.moveToPoint(CGPoint(x: 0, y: size.height - 20))
        pathOne.addLineToPoint(CGPoint(x: 0, y: size.height - 100))
        pathOne.addQuadCurveToPoint(CGPoint(x: size.width/3.0, y: size.height - 20), controlPoint: CGPoint(x: size.width/6.0, y: size.height - 100))
        grasslandOne.path = pathOne.CGPath
        //设置草坪的颜色
        grasslandOne.fillColor = UIColor.init(colorLiteralRed: 82.0/255.0, green: 177.0/255.0, blue: 44.0/255.0, alpha: 1.0).CGColor
        view.layer.addSublayer(grasslandOne)
    }

屏幕快照 2016-06-22 上午12.28.53.png

CAKeyframeAnimation

CAKeyframeAnimation类为对象提供了关键帧动画的功能。你创建一个CAKeyframeAnimation对象使用animationWithKeyPath:指定属性的关键路径,你可以指定要使用关键帧的值来控制时间和动画的行为。我们可以通过CAKeyframeAnimation来实现过山车在轨道上的的动画和云朵的动画,下面是一小段示例代码下载demo有完整代码

//添加绿色轨道的动画
    func addGreenCarPathAnimation(size:CGSize) {
        let carLayer:CALayer = CALayer()
        carLayer.frame = CGRect(x: 0, y: 0, width: 17, height: 11)
        carLayer.contents = UIImage.init(named: "otherCar")!.CGImage

        //绘制路径
        let path:UIBezierPath = UIBezierPath()
        path.lineCapStyle = .Round
        path.lineJoinStyle = .Round
        path.moveToPoint(CGPoint(x: size.width + 10, y: size.height - 7))
        path.addLineToPoint(CGPoint(x: size.width + 10, y: size.height - 77))
        path.addQuadCurveToPoint(CGPoint(x: size.width/1.8, y: size.height - 77), controlPoint: CGPoint(x: size.width - 120, y: 193))
        path.addArcWithCenter(CGPoint(x: size.width/1.9, y: size.height - 140), radius: 63, startAngle: CGFloat(0.5*M_PI), endAngle: CGFloat(2.5*M_PI), clockwise: true)
        path.addCurveToPoint(CGPoint(x: 0, y: size.height - 107), controlPoint1: CGPoint(x: size.width/1.8 - 60, y: size.height - 67), controlPoint2: CGPoint(x: 150, y: size.height/2.3-7))
        path.addLineToPoint(CGPoint(x: -100, y: size.height + 7))

        //关键帧动画作用于position
        let animation:CAKeyframeAnimation = CAKeyframeAnimation.init(keyPath: "position")
        animation.path = path.CGPath
        //动画节奏为线性动画
        animation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionLinear)
        //动画时间
        animation.duration = 6
        //动画重复次数
        animation.repeatCount = MAXFLOAT
        //动画是否逆转
        animation.autoreverses = false
        //动画速度为匀速
        animation.calculationMode = kCAAnimationCubicPaced
        //动画角度是否调整
        animation.rotationMode = kCAAnimationRotateAuto
        view.layer.addSublayer(carLayer)
        carLayer.addAnimation(animation, forKey: "carAnimation")
    }

上面的代码只是简单的示例,完整代码得去我的github上去下载,到这里也就基本上完成了,大家有什么疑问可以留言评论,谢谢大家的观看

demo地址

参考文档(非常好的一篇关于介绍CALayer的中文翻译文档,学习必看)

版权声明:本文为博主原创文章,未经博主允许不得转载。

CAKeyframeAnimation实现抖动效果

// // ViewController.m #import "ViewController.h" // 角度转弧度 #define angle2Radion(angle) (angle / ...
  • github_26672553
  • github_26672553
  • 2016年04月08日 20:25
  • 534

CAKeyframeAnimation动画的使用

/** * CAKeyframeAnimation动画 * * @param view 添加动画效果的UIView * @param keyPath 动画类型 * @p...
  • potato512
  • potato512
  • 2016年08月01日 17:41
  • 291

CAKeyframeAnimation 动画使用 开始、暂停动画

开始一个帧动画 [objc] view plaincopy - (void)showAlertAnimation  {      CAKeyframeAnimation *an...
  • zhouleizhao
  • zhouleizhao
  • 2014年07月28日 09:16
  • 2749

CAKeyframeAnimation 关键帧动画的用法

一、原理 之所以叫做关键帧动画是因为,这个类可以实现,某一属性按照一串的数值进行动画,就好像制作动画的时候一帧一帧的制作一样。 一般使用的时候  首先通过 animationWithKeyPat...
  • samuelltk
  • samuelltk
  • 2013年06月07日 15:53
  • 9221

iOS之CAKeyframeAnimation关键帧动画详解

CABasicAnimation算是CAKeyFrameAnimation的 特殊情况,即不考虑中间变换过程,只考虑起始点与目标点就可以了。而CAKeyFrameAnimation则更复杂一些,允许我...
  • Leemin_ios
  • Leemin_ios
  • 2017年05月04日 19:50
  • 309

【原】iOSCoreAnimation动画系列教程(二):CAKeyFrameAnimation【包会】

在上一篇专题文章【原】iOSCoreAnimation动画系列教程(一):CABasicAnimation【包会】中我们学习了iOS核心动画CoreAnimation中CABasicAnimation...
  • sunnyboy9
  • sunnyboy9
  • 2016年04月26日 22:45
  • 392

iOS 动画总结

iOS 动画大体可以可以分为两大类: 一类是针对UIView的动画:UIView的自带动画 另一类是针对CALayer的动画:核心动画(Core Animation) 一.  UIView自带动画:(...
  • u011404663
  • u011404663
  • 2015年07月20日 22:46
  • 648

iOS-利用UIBezierPath和CAAnimation制作路径动画

继上篇的心跳动画,今天实现一个根据心跳路径实现一个路径动画,让某一视图沿着路径进行运动.核心代码1-首先通过 drawRect 绘制心形路径- (void)drawRect:(CGRect)rect ...
  • Mazy_ma
  • Mazy_ma
  • 2017年02月16日 10:47
  • 3187

CAKeyframeAnimation(一)使用和属性全面解析

CAKeyframeAnimation       关键帧动画,也是CAPropertyAnimation的子类,与CABasicAnimation的区别是:CABasicAnimation只能...
  • longshihua
  • longshihua
  • 2016年04月15日 10:39
  • 3085

iOS动画进阶 - 实现炫酷的上拉刷新动效(二)

最近撸了一个上拉刷新的小轮子,只要遵循一个协议就能自定义自己动效的上拉刷新和加载,我自己也写了几个动效进去,下面是一个比较好的动效的实现过程 先上效果图和github地址,完整代码个demo和进入查看...
  • wang631106979
  • wang631106979
  • 2017年04月27日 20:41
  • 3431
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS动画进阶 - CAKeyframeAnimation实现过山车动画
举报原因:
原因补充:

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