ActivityIndicatorAnimationBallPulseRise.swift 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. //
  2. // Created by Tom Baranes on 23/08/16.
  3. // Copyright (c) 2016 IBAnimatable. All rights reserved.
  4. //
  5. import UIKit
  6. public class ActivityIndicatorAnimationBallPulseRise: ActivityIndicatorAnimating {
  7. // MARK: Properties
  8. fileprivate let duration: CFTimeInterval = 1
  9. fileprivate var deltaY: CGFloat = 0
  10. fileprivate let timingFunction = CAMediaTimingFunction(controlPoints: 0.15, 0.46, 0.9, 0.6)
  11. // MARK: ActivityIndicatorAnimating
  12. public func configureAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
  13. let circleSpacing: CGFloat = 2
  14. let circleSize = (size.width - 4 * circleSpacing) / 5
  15. let x = (layer.bounds.size.width - size.width) / 2
  16. let y = (layer.bounds.size.height - circleSize) / 2
  17. deltaY = size.height / 2
  18. for i in 0 ..< 5 {
  19. let circle = ActivityIndicatorShape.circle.makeLayer(size: CGSize(width: circleSize, height: circleSize), color: color)
  20. let frame = CGRect(x: x + circleSize * CGFloat(i) + circleSpacing * CGFloat(i),
  21. y: y,
  22. width: circleSize,
  23. height: circleSize)
  24. circle.frame = frame
  25. if i % 2 == 0 {
  26. circle.add(evenAnimation, forKey: "animation")
  27. } else {
  28. circle.add(oddAnimation, forKey: "animation")
  29. }
  30. layer.addSublayer(circle)
  31. }
  32. }
  33. }
  34. // MARK: - Setup Odd
  35. private extension ActivityIndicatorAnimationBallPulseRise {
  36. var oddAnimation: CAAnimation {
  37. let scaleAnimation = oddScaleAnimation
  38. let translateAnimation = oddTranslateAnimation
  39. let animation = CAAnimationGroup()
  40. animation.animations = [scaleAnimation, translateAnimation]
  41. animation.duration = duration
  42. animation.repeatCount = .infinity
  43. animation.isRemovedOnCompletion = false
  44. return animation
  45. }
  46. var oddScaleAnimation: CAKeyframeAnimation {
  47. let scaleAnimation = CAKeyframeAnimation(keyPath: .scale)
  48. scaleAnimation.keyTimes = [0, 0.5, 1]
  49. scaleAnimation.timingFunctions = [timingFunction, timingFunction]
  50. scaleAnimation.values = [0.4, 1.1, 0.75]
  51. scaleAnimation.duration = duration
  52. return scaleAnimation
  53. }
  54. var oddTranslateAnimation: CAKeyframeAnimation {
  55. let translateAnimation = CAKeyframeAnimation(keyPath: .translationY)
  56. translateAnimation.keyTimes = [0, 0.25, 0.75, 1]
  57. translateAnimation.timingFunctions = [timingFunction, timingFunction, timingFunction]
  58. translateAnimation.values = [0, deltaY, -deltaY, 0]
  59. translateAnimation.duration = duration
  60. return translateAnimation
  61. }
  62. }
  63. // MARK: - Even Odd
  64. private extension ActivityIndicatorAnimationBallPulseRise {
  65. var evenAnimation: CAAnimation {
  66. let scaleAnimation = evenScaleAnimation
  67. let translateAnimation = evenTranslateAnimation
  68. let animation = CAAnimationGroup()
  69. animation.animations = [scaleAnimation, translateAnimation]
  70. animation.duration = duration
  71. animation.repeatCount = .infinity
  72. animation.isRemovedOnCompletion = false
  73. return animation
  74. }
  75. var evenScaleAnimation: CAKeyframeAnimation {
  76. let scaleAnimation = CAKeyframeAnimation(keyPath: .scale)
  77. scaleAnimation.keyTimes = [0, 0.5, 1]
  78. scaleAnimation.timingFunctions = [timingFunction, timingFunction]
  79. scaleAnimation.values = [1.1, 0.4, 1]
  80. scaleAnimation.duration = duration
  81. return scaleAnimation
  82. }
  83. var evenTranslateAnimation: CAKeyframeAnimation {
  84. let translateAnimation = CAKeyframeAnimation(keyPath: .translationY)
  85. translateAnimation.keyTimes = [0, 0.25, 0.75, 1]
  86. translateAnimation.timingFunctions = [timingFunction, timingFunction, timingFunction]
  87. translateAnimation.values = [0, -deltaY, deltaY, 0]
  88. translateAnimation.duration = duration
  89. return translateAnimation
  90. }
  91. }