ActivityIndicatorAnimationBallRotate.swift 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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 ActivityIndicatorAnimationBallRotate: ActivityIndicatorAnimating {
  7. // MARK: Properties
  8. fileprivate let duration: CFTimeInterval = 1
  9. fileprivate let timingFunction = CAMediaTimingFunction(controlPoints: 0.7, -0.13, 0.22, 0.86)
  10. // MARK: ActivityIndicatorAnimating
  11. public func configureAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
  12. let circleSize: CGFloat = size.width / 5
  13. // Draw circles
  14. let leftCircle = ActivityIndicatorShape.circle.makeLayer(size: CGSize(width: circleSize, height: circleSize), color: color)
  15. let rightCircle = ActivityIndicatorShape.circle.makeLayer(size: CGSize(width: circleSize, height: circleSize), color: color)
  16. let centerCircle = ActivityIndicatorShape.circle.makeLayer(size: CGSize(width: circleSize, height: circleSize), color: color)
  17. leftCircle.opacity = 0.8
  18. leftCircle.frame = CGRect(x: 0, y: (size.height - circleSize) / 2, width: circleSize, height: circleSize)
  19. rightCircle.opacity = 0.8
  20. rightCircle.frame = CGRect(x: size.width - circleSize, y: (size.height - circleSize) / 2, width: circleSize, height: circleSize)
  21. centerCircle.frame = CGRect(x: (size.width - circleSize) / 2, y: (size.height - circleSize) / 2, width: circleSize, height: circleSize)
  22. let circle = CALayer()
  23. let frame = CGRect(x: (layer.bounds.size.width - size.width) / 2,
  24. y: (layer.bounds.size.height - size.height) / 2,
  25. width: size.width,
  26. height: size.height)
  27. circle.frame = frame
  28. circle.addSublayer(leftCircle)
  29. circle.addSublayer(rightCircle)
  30. circle.addSublayer(centerCircle)
  31. circle.add(animation, forKey: "animation")
  32. layer.addSublayer(circle)
  33. }
  34. }
  35. // MARK: - Setup
  36. private extension ActivityIndicatorAnimationBallRotate {
  37. var animation: CAAnimationGroup {
  38. let animation = CAAnimationGroup()
  39. animation.animations = [scaleAnimation, rotateAnimation]
  40. animation.duration = duration
  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.timingFunctions = [timingFunction, timingFunction]
  49. scaleAnimation.values = [1, 0.6, 1]
  50. scaleAnimation.duration = duration
  51. return scaleAnimation
  52. }
  53. var rotateAnimation: CAKeyframeAnimation {
  54. let rotateAnimation = CAKeyframeAnimation(keyPath: .rotationZ)
  55. rotateAnimation.keyTimes = [0, 0.5, 1]
  56. rotateAnimation.timingFunctions = [timingFunction, timingFunction]
  57. rotateAnimation.values = [0, CGFloat.pi, 2 * CGFloat.pi]
  58. rotateAnimation.duration = duration
  59. return rotateAnimation
  60. }
  61. }