ActivityIndicatorAnimationBallGridPulse.swift 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  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 ActivityIndicatorAnimationBallGridPulse: ActivityIndicatorAnimating {
  7. // MARK: Properties
  8. fileprivate let timingFunction: TimingFunctionType = .default
  9. // MARK: ActivityIndicatorAnimating
  10. public func configureAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
  11. let circleSpacing: CGFloat = 2
  12. let circleSize = (size.width - circleSpacing * 2) / 3
  13. let x = (layer.bounds.size.width - size.width) / 2
  14. let y = (layer.bounds.size.height - size.height) / 2
  15. let durations: [CFTimeInterval] = [0.72, 1.02, 1.28, 1.42, 1.45, 1.18, 0.87, 1.45, 1.06]
  16. let beginTime = layer.currentMediaTime
  17. let beginTimes: [CFTimeInterval] = [-0.06, 0.25, -0.17, 0.48, 0.31, 0.03, 0.46, 0.78, 0.45]
  18. let animation = defaultAnimation
  19. // Draw circles
  20. for i in 0 ..< 3 {
  21. for j in 0 ..< 3 {
  22. let circle = ActivityIndicatorShape.circle.makeLayer(size: CGSize(width: circleSize, height: circleSize), color: color)
  23. let frame = CGRect(x: x + circleSize * CGFloat(j) + circleSpacing * CGFloat(j),
  24. y: y + circleSize * CGFloat(i) + circleSpacing * CGFloat(i),
  25. width: circleSize,
  26. height: circleSize)
  27. animation.duration = durations[3 * i + j]
  28. animation.beginTime = beginTime + beginTimes[3 * i + j]
  29. circle.frame = frame
  30. circle.add(animation, forKey: "animation")
  31. layer.addSublayer(circle)
  32. }
  33. }
  34. }
  35. }
  36. // MARK: - Setup
  37. private extension ActivityIndicatorAnimationBallGridPulse {
  38. var defaultAnimation: CAAnimationGroup {
  39. let animation = CAAnimationGroup()
  40. animation.animations = [scaleAnimation, opacityAnimation]
  41. animation.repeatCount = .infinity
  42. animation.isRemovedOnCompletion = false
  43. return animation
  44. }
  45. var scaleAnimation: CAKeyframeAnimation {
  46. let scaleAnimation = CAKeyframeAnimation(keyPath: .scale)
  47. scaleAnimation.keyTimes = [0, 0.5, 1]
  48. scaleAnimation.timingFunctionsType = [timingFunction, timingFunction]
  49. scaleAnimation.values = [1, 0.5, 1]
  50. return scaleAnimation
  51. }
  52. var opacityAnimation: CAKeyframeAnimation {
  53. let opacityAnimation = CAKeyframeAnimation(keyPath: .opacity)
  54. opacityAnimation.keyTimes = [0, 0.5, 1]
  55. opacityAnimation.timingFunctionsType = [timingFunction, timingFunction]
  56. opacityAnimation.values = [1, 0.7, 1]
  57. return opacityAnimation
  58. }
  59. }