ActivityIndicatorAnimationBallRotateChase.swift 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. //
  2. // Created by Tom Baranes on 23/08/16.
  3. // Copyright © 2016 IBAnimatable. All rights reserved.
  4. //
  5. import UIKit
  6. public class ActivityIndicatorAnimationBallRotateChase: ActivityIndicatorAnimating {
  7. // MARK: Properties
  8. fileprivate let duration: CFTimeInterval = 1.5
  9. // MARK: ActivityIndicatorAnimating
  10. public func configureAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
  11. let circleSize = size.width / 5
  12. for i in 0 ..< 5 {
  13. let factor = Float(i) * 1.0 / 5
  14. let circle = ActivityIndicatorShape.circle.makeLayer(size: CGSize(width: circleSize, height: circleSize), color: color)
  15. let animation = rotateAnimation(rate: factor,
  16. x: layer.bounds.size.width / 2,
  17. y: layer.bounds.size.height / 2,
  18. size: CGSize(width: size.width - circleSize,
  19. height: size.height - circleSize))
  20. circle.frame = CGRect(x: 0, y: 0, width: circleSize, height: circleSize)
  21. circle.add(animation, forKey: "animation")
  22. layer.addSublayer(circle)
  23. }
  24. }
  25. }
  26. // MARK: - Setup
  27. // swiftlint:disable variable_name_min_length
  28. private extension ActivityIndicatorAnimationBallRotateChase {
  29. func rotateAnimation(rate: Float, x: CGFloat, y: CGFloat, size: CGSize) -> CAAnimationGroup {
  30. let fromScale = 1 - rate
  31. let toScale = 0.2 + rate
  32. let timeFunc = CAMediaTimingFunction(controlPoints: 0.5, 0.15 + rate, 0.25, 1.0)
  33. let scaleAnimation = CABasicAnimation(keyPath: .scale)
  34. scaleAnimation.duration = duration
  35. scaleAnimation.repeatCount = .infinity
  36. scaleAnimation.fromValue = fromScale
  37. scaleAnimation.toValue = toScale
  38. let positionAnimation = CAKeyframeAnimation(keyPath: .position)
  39. positionAnimation.duration = duration
  40. positionAnimation.repeatCount = .infinity
  41. positionAnimation.path = UIBezierPath(arcCenter: CGPoint(x: x, y: y),
  42. radius: size.width / 2,
  43. startAngle: 3 * CGFloat.pi / 2,
  44. endAngle: 3 * CGFloat.pi / 2 + 2 * CGFloat.pi,
  45. clockwise: true).cgPath
  46. let animation = CAAnimationGroup()
  47. animation.animations = [scaleAnimation, positionAnimation]
  48. animation.timingFunction = timeFunc
  49. animation.duration = duration
  50. animation.repeatCount = .infinity
  51. animation.isRemovedOnCompletion = false
  52. return animation
  53. }
  54. }
  55. // swiftlint:enable variable_name_min_length