偶然間在網(wǎng)頁上看到一個過山車動畫覺得很炫,就想用
swift
純代碼實現(xiàn)了一個類似的效果利耍,因為沒有設計天賦隘梨,所以就完全高仿的人家的效果-.-下面上效果圖:
給大家介紹一下項目中主要會用到的類:
CAShapeLayer
CAGradientLayer
CAKeyframeAnimation
實現(xiàn)的主要思路
漸變的背景用CAGradientLayer
實現(xiàn)轴猎,其他例如山峰咬崔,草坪和軌道可以用CAShapeLayer
配合UIBezierPath
實現(xiàn)垮斯,然后云朵,樹木和大地直接用CALayer
通過設置contents
實現(xiàn)扰肌,然后云朵和過山車的動畫實現(xiàn)用CAKeyframeAnimation
曙旭,這樣分析其實做一個這樣的動態(tài)效果并不是很難桂躏,下面就是實現(xiàn)過程和簡單的代碼示例。下載demo有完整代碼
CAGradientLayer
CAGradientLayer
是用來生成兩種或更多顏色平滑漸變的剂习。相比于Core Graphics
來說CAGradientLayer
的真正好處在于繪制使用了硬件加速鳞绕。這說明通過CAGradientLayer
來繪制漸變的效果比用Core Graphics
的效率更高们何。我們通過CAGradientLayer
來實現(xiàn)這個項目中的背景下載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
}
CAShapeLayer
CAShapeLayer
是一個通過矢量圖形而不是bitmap
來繪制的圖層子類冤竹。你指定諸如顏色和線寬等屬性贴见,用CGPath
來定義想要繪制的圖形,最后CAShapeLayer就自動渲染出來了镣衡。當然档悠,你也可以用Core Graphics
直接向原始的CALyer的內容中繪制一個路徑辖所,相比直下,使用CAShapeLayer
有以下一些優(yōu)點:
- 渲染快速吆视。
CAShapeLayer
使用了硬件加速酥宴,繪制同一圖形會比用Core Graphics
快很多拙寡。
- 高效使用內存。一個
CAShapeLayer
不需要像普通CALayer
一樣創(chuàng)建一個寄宿圖形般堆,所以無論有多大淮摔,都不會占用太多的內存始赎。
- 不會被圖層邊界剪裁掉。一個
CAShapeLayer
可以在邊界之外繪制。你的圖層路徑不會像在使用Core Graphics
的普通CALayer
一樣被剪裁掉(如我們在第二章所見)筋搏。
- 不會出現(xiàn)像素化奔脐。當你給
CAShapeLayer
做3D
變換時,它不像一個有寄宿圖的普通圖層一樣變得像素化髓迎。
我們用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)
}
CAKeyframeAnimation
CAKeyframeAnimation
類為對象提供了關鍵幀動畫的功能凛忿。你創(chuàng)建一個CAKeyframeAnimation
對象使用animationWithKeyPath:
指定屬性的關鍵路徑店溢,你可以指定要使用關鍵幀的值來控制時間和動畫的行為床牧。我們可以通過CAKeyframeAnimation
來實現(xiàn)過山車在軌道上的的動畫和云朵的動畫福澡,下面是一小段示例代碼下載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
//動畫節(jié)奏為線性動畫
animation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionLinear)
//動畫時間
animation.duration = 6
//動畫重復次數(shù)
animation.repeatCount = MAXFLOAT
//動畫是否逆轉
animation.autoreverses = false
animation.calculationMode = kCAAnimationCubicPaced
//動畫角度是否調整
animation.rotationMode = kCAAnimationRotateAuto
view.layer.addSublayer(carLayer)
carLayer.addAnimation(animation, forKey: "carAnimation")
}
上面的代碼只是簡單的示例除秀,完整代碼得去我的github上去下載册踩,到這里也就基本上完成了效拭,大家有什么疑問可以留言評論缎患,謝謝大家的觀看