From cae8b46e3c482be7703b01f2bd132828d6437155 Mon Sep 17 00:00:00 2001 From: Phimage Date: Fri, 29 Jun 2018 13:51:24 +0200 Subject: [PATCH 1/4] New activity indicator `newtonCradle` and `circlePendulum` --- .../IBAnimatable.xcodeproj/project.pbxproj | 8 ++ ...vityIndicatorAnimationCirclePendulum.swift | 97 +++++++++++++++++++ ...tivityIndicatorAnimationNewtonCradle.swift | 75 ++++++++++++++ .../Common/ActivityIndicatorFactory.swift | 17 +++- Sources/Enums/ActivityIndicatorType.swift | 2 + .../ActivityIndicatorAnimatable.swift | 3 +- 6 files changed, 199 insertions(+), 3 deletions(-) create mode 100644 Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationCirclePendulum.swift create mode 100644 Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationNewtonCradle.swift diff --git a/IBAnimatable/IBAnimatable.xcodeproj/project.pbxproj b/IBAnimatable/IBAnimatable.xcodeproj/project.pbxproj index 088331ec..85685931 100644 --- a/IBAnimatable/IBAnimatable.xcodeproj/project.pbxproj +++ b/IBAnimatable/IBAnimatable.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ 3676E7DF2059457A0003B9DF /* DesignableNavigationBar.swift in Headers */ = {isa = PBXBuildFile; fileRef = E27FD2391ECD7D8A00F74840 /* DesignableNavigationBar.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 48A167122063CD0D00D7BCFB /* ConicalGradientLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48A167112063CD0D00D7BCFB /* ConicalGradientLayer.swift */; }; 48D80DCA20403DAC00D3137B /* AnimatableTabBarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D80DC920403DAC00D3137B /* AnimatableTabBarItem.swift */; }; + C40AE6A220E6210100B24A44 /* ActivityIndicatorAnimationNewtonCradle.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40AE6A120E6210100B24A44 /* ActivityIndicatorAnimationNewtonCradle.swift */; }; C414765F209C1BD700945C8B /* ActivityIndicatorAnimationTripleGear.swift in Sources */ = {isa = PBXBuildFile; fileRef = C414765E209C1BD700945C8B /* ActivityIndicatorAnimationTripleGear.swift */; }; C41A0E80209A39660069555A /* ActivityIndicatorAnimationHeartBeat.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A0E7F209A39660069555A /* ActivityIndicatorAnimationHeartBeat.swift */; }; C41A0E82209A3C1B0069555A /* ActivityIndicatorAnimationTriforce.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A0E81209A3C1B0069555A /* ActivityIndicatorAnimationTriforce.swift */; }; @@ -32,6 +33,7 @@ C456071F209BAACB002B1DF4 /* ActivityIndicatorAnimationCircleDashStrokeSpin.swift in Sources */ = {isa = PBXBuildFile; fileRef = C456071E209BAACB002B1DF4 /* ActivityIndicatorAnimationCircleDashStrokeSpin.swift */; }; C46DC3E12099863A00501E63 /* ActivityIndicatorAnimationCircleStrokeSpin.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46DC3E02099863A00501E63 /* ActivityIndicatorAnimationCircleStrokeSpin.swift */; }; C46DC3E32099895E00501E63 /* ActivityIndicatorAnimationGear.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46DC3E22099895E00501E63 /* ActivityIndicatorAnimationGear.swift */; }; + C489AD1E20E640B300273B77 /* ActivityIndicatorAnimationCirclePendulum.swift in Sources */ = {isa = PBXBuildFile; fileRef = C489AD1D20E640B300273B77 /* ActivityIndicatorAnimationCirclePendulum.swift */; }; C49C08DD20A05072002FCAFD /* ActivityIndicatorAnimationRupee.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49C08DC20A05072002FCAFD /* ActivityIndicatorAnimationRupee.swift */; }; E20DAEB82003662900BE1C88 /* GradientMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20DAEB72003662900BE1C88 /* GradientMode.swift */; }; E20DAEBA2003682F00BE1C88 /* RadialGradientLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20DAEB92003682F00BE1C88 /* RadialGradientLayer.swift */; }; @@ -229,6 +231,7 @@ /* Begin PBXFileReference section */ 48A167112063CD0D00D7BCFB /* ConicalGradientLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConicalGradientLayer.swift; sourceTree = ""; }; 48D80DC920403DAC00D3137B /* AnimatableTabBarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatableTabBarItem.swift; sourceTree = ""; }; + C40AE6A120E6210100B24A44 /* ActivityIndicatorAnimationNewtonCradle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorAnimationNewtonCradle.swift; sourceTree = ""; }; C414765E209C1BD700945C8B /* ActivityIndicatorAnimationTripleGear.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorAnimationTripleGear.swift; sourceTree = ""; }; C41A0E7F209A39660069555A /* ActivityIndicatorAnimationHeartBeat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorAnimationHeartBeat.swift; sourceTree = ""; }; C41A0E81209A3C1B0069555A /* ActivityIndicatorAnimationTriforce.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorAnimationTriforce.swift; sourceTree = ""; }; @@ -236,6 +239,7 @@ C456071E209BAACB002B1DF4 /* ActivityIndicatorAnimationCircleDashStrokeSpin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorAnimationCircleDashStrokeSpin.swift; sourceTree = ""; }; C46DC3E02099863A00501E63 /* ActivityIndicatorAnimationCircleStrokeSpin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorAnimationCircleStrokeSpin.swift; sourceTree = ""; }; C46DC3E22099895E00501E63 /* ActivityIndicatorAnimationGear.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorAnimationGear.swift; sourceTree = ""; }; + C489AD1D20E640B300273B77 /* ActivityIndicatorAnimationCirclePendulum.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorAnimationCirclePendulum.swift; sourceTree = ""; }; C49C08DC20A05072002FCAFD /* ActivityIndicatorAnimationRupee.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorAnimationRupee.swift; sourceTree = ""; }; E20DAEB72003662900BE1C88 /* GradientMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientMode.swift; sourceTree = ""; }; E20DAEB92003682F00BE1C88 /* RadialGradientLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadialGradientLayer.swift; sourceTree = ""; }; @@ -614,6 +618,8 @@ C41A0E81209A3C1B0069555A /* ActivityIndicatorAnimationTriforce.swift */, C456071E209BAACB002B1DF4 /* ActivityIndicatorAnimationCircleDashStrokeSpin.swift */, C49C08DC20A05072002FCAFD /* ActivityIndicatorAnimationRupee.swift */, + C40AE6A120E6210100B24A44 /* ActivityIndicatorAnimationNewtonCradle.swift */, + C489AD1D20E640B300273B77 /* ActivityIndicatorAnimationCirclePendulum.swift */, ); path = Animations; sourceTree = ""; @@ -1093,6 +1099,7 @@ E27FD25F1ECD7D8A00F74840 /* PresentationPresenter.swift in Sources */, C4511F371F93F1B2002E0FAF /* UIBezierPathExtension.swift in Sources */, E27FD28F1ECD7D8A00F74840 /* TransitionType.swift in Sources */, + C40AE6A220E6210100B24A44 /* ActivityIndicatorAnimationNewtonCradle.swift in Sources */, E27FD2CF1ECD7D8A00F74840 /* AnimatableTableViewCell.swift in Sources */, E27FD2821ECD7D8A00F74840 /* ColorType.swift in Sources */, E27FD2641ECD7D8A00F74840 /* PanInteractiveAnimator.swift in Sources */, @@ -1204,6 +1211,7 @@ E20DAEBA2003682F00BE1C88 /* RadialGradientLayer.swift in Sources */, E27FD2CB1ECD7D8A00F74840 /* AnimatableScrollView.swift in Sources */, E27FD2C41ECD7D8A00F74840 /* AnimatableActivityIndicatorView.swift in Sources */, + C489AD1E20E640B300273B77 /* ActivityIndicatorAnimationCirclePendulum.swift in Sources */, E27FD2911ECD7D8A00F74840 /* CALayerExtension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationCirclePendulum.swift b/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationCirclePendulum.swift new file mode 100644 index 00000000..588d82b0 --- /dev/null +++ b/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationCirclePendulum.swift @@ -0,0 +1,97 @@ +// +// ActivityIndicatorAnimationCirclePendulum.swift +// IBAnimatable +// +// Created by phimage on 29/06/2018. +// Copyright © 2018 IBAnimatable. All rights reserved. +// + +import Foundation + +import UIKit + +public class ActivityIndicatorAnimationCirclePendulum: ActivityIndicatorAnimating { + + // MARK: Properties + + fileprivate let duration: CFTimeInterval = 1 + fileprivate let ratio: CGFloat = 7 + fileprivate let ballCount: Int = 3 + + #if LG + fileprivate let trueColor = true + #else + fileprivate let trueColor = false + #endif + fileprivate let colors: [UIColor] = [.red, .blue, .yellow] + + fileprivate var ballSize: CGFloat = 0 + + // MARK: ActivityIndicatorAnimating + + public func configureAnimation(in layer: CALayer, size: CGSize, color: UIColor) { + ballSize = size.height / ratio + var xPos = (size.width - (CGFloat(ballCount) * ballSize)) / 2 + let yPos = size.height - ballSize / 2 + + for i in 0 ..< ballCount { + let ball = ActivityIndicatorShape.circle.makeLayer(size: CGSize(width: ballSize, height: ballSize), color: trueColor ? colors[i]: color) + ball.frame = CGRect(x: xPos, y: yPos, width: ballSize, height: ballSize) + ball.add(makeAnimation(for: ball, in: layer, size: size, pos: i), forKey: "animation") + layer.addSublayer(ball) + xPos += ballSize + } + } +} + +private extension ActivityIndicatorAnimationCirclePendulum { + + func makeAnimation(for ball: CALayer, in layer: CALayer, size: CGSize, pos: Int) -> CAAnimation { + let angle = 2 * atan(ballSize / (size.height - ballSize / 2)) + + var animations: [CAKeyframeAnimation] = [] // only 3 balls, code not generic yet, how to compute angles? + + let rotateAnimation = CAKeyframeAnimation(keyPath: .position) + var animPos = 0 + rotateAnimation.path = UIBezierPath(arcCenter: CGPoint(x: size.width / 2, y: size.height / 2), + radius: size.height / 2, + startAngle: CGFloat.pi / 2 + angle, + endAngle: 2 * CGFloat.pi + CGFloat.pi / 2 - angle, + clockwise: true).cgPath + rotateAnimation.duration = duration + rotateAnimation.timingFunctionType = .easeInOut + rotateAnimation.beginTime = duration * CFTimeInterval((pos + animPos) % ballCount) + animations.append(rotateAnimation) + + let rotateAnimation2 = CAKeyframeAnimation(keyPath: .position) + animPos += 1 + rotateAnimation2.path = UIBezierPath(arcCenter: CGPoint(x: size.width / 2, y: size.height / 2), + radius: size.height / 2, + startAngle: 2 * CGFloat.pi + CGFloat.pi / 2 - angle, + endAngle: 2 * CGFloat.pi + CGFloat.pi / 2, + clockwise: true).cgPath + rotateAnimation2.duration = duration + rotateAnimation2.timingFunctionType = .easeOutExpo + rotateAnimation2.beginTime = duration * CFTimeInterval((pos + animPos) % ballCount) + animations.append(rotateAnimation2) + + let rotateAnimation3 = CAKeyframeAnimation(keyPath: .position) + animPos += 1 + rotateAnimation3.path = UIBezierPath(arcCenter: CGPoint(x: size.width / 2, y: size.height / 2), + radius: size.height / 2, + startAngle: 2 * CGFloat.pi + CGFloat.pi / 2, + endAngle: 2 * CGFloat.pi + CGFloat.pi / 2 + angle, + clockwise: true).cgPath + rotateAnimation3.duration = duration + rotateAnimation3.timingFunctionType = .easeOutExpo + rotateAnimation3.beginTime = duration * CFTimeInterval((pos + animPos) % ballCount) + animations.append(rotateAnimation3) + + let animation = CAAnimationGroup() + animation.animations = animations + animation.duration = duration * CFTimeInterval(ballCount) + animation.repeatCount = .infinity + animation.isRemovedOnCompletion = false + return animation + } +} diff --git a/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationNewtonCradle.swift b/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationNewtonCradle.swift new file mode 100644 index 00000000..386bdf16 --- /dev/null +++ b/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationNewtonCradle.swift @@ -0,0 +1,75 @@ +// +// ActivityIndicatorAnimationNewtonCradle.swift +// IBAnimatable +// +// Created by phimage on 29/06/2018. +// Copyright © 2018 IBAnimatable. All rights reserved. +// + +import UIKit + +public class ActivityIndicatorAnimationNewtonCradle: ActivityIndicatorAnimating { + + // MARK: Properties + + fileprivate let duration: CFTimeInterval = 0.4 + fileprivate let ratio: CGFloat = 7 + fileprivate let ballCount: Int = 5 + fileprivate let timingFunction: TimingFunctionType = .easeOutQuad + + fileprivate var ballSize: CGFloat = 0 + + // MARK: ActivityIndicatorAnimating + + public func configureAnimation(in layer: CALayer, size: CGSize, color: UIColor) { + ballSize = size.height / ratio + var xPos = (size.width - (CGFloat(ballCount) * ballSize)) / 2 + let yPos = size.height - ballSize / 2 + + var balls: [CALayer] = [] + for _ in 0 ..< ballCount { + let ball = ActivityIndicatorShape.circle.makeLayer(size: CGSize(width: ballSize, height: ballSize), color: color) + ball.frame = CGRect(x: xPos, y: yPos, width: ballSize, height: ballSize) + balls.append(ball) + xPos += ballSize + } + + let firstBall = balls.removeFirst() + firstBall.add(makeAnimation(for: firstBall, in: layer, size: size, reverse: true), forKey: "animation") + layer.addSublayer(firstBall) + + let lastBall = balls.removeLast() + lastBall.add(makeAnimation(for: lastBall, in: layer, size: size, reverse: false), forKey: "animation") + layer.addSublayer(lastBall) + + for ball in balls { + layer.addSublayer(ball) + } + } +} + +private extension ActivityIndicatorAnimationNewtonCradle { + + func makeAnimation(for ball: CALayer, in layer: CALayer, size: CGSize, reverse: Bool) -> CAAnimation { + let rotateAnimation = CAKeyframeAnimation(keyPath: .position) + rotateAnimation.path = UIBezierPath(arcCenter: CGPoint(x: ball.frame.origin.x + ballSize / 2, y: size.height / 2), + radius: size.height / 2, + startAngle: CGFloat.pi / 2, + endAngle: reverse ? CGFloat.pi: 0, + clockwise: reverse).cgPath + rotateAnimation.duration = duration + rotateAnimation.autoreverses = true + rotateAnimation.timingFunctionType = timingFunction + + if reverse { + rotateAnimation.beginTime = duration * 2 + } + + let animation = CAAnimationGroup() + animation.animations = [rotateAnimation] + animation.duration = duration * 4 + animation.repeatCount = .infinity + animation.isRemovedOnCompletion = false + return animation + } +} diff --git a/Sources/ActivityIndicators/Common/ActivityIndicatorFactory.swift b/Sources/ActivityIndicators/Common/ActivityIndicatorFactory.swift index d5ca8afe..f95256a5 100755 --- a/Sources/ActivityIndicators/Common/ActivityIndicatorFactory.swift +++ b/Sources/ActivityIndicators/Common/ActivityIndicatorFactory.swift @@ -7,7 +7,18 @@ import UIKit public struct ActivityIndicatorFactory { public static func makeActivityIndicator(activityIndicatorType: ActivityIndicatorType) -> ActivityIndicatorAnimating { - switch activityIndicatorType { + return activityIndicatorType.animator + } +} + +extension ActivityIndicatorType { + + func configureAnimation(in layer: CALayer, size: CGSize, color: UIColor) { + self.animator.configureAnimation(in: layer, size: size, color: color) + } + + var animator: ActivityIndicatorAnimating { + switch self { case .none: fatalError("Invalid ActivityIndicatorAnimating") case .audioEqualizer: @@ -86,6 +97,10 @@ public struct ActivityIndicatorFactory { return ActivityIndicatorAnimationTriforce() case .rupee: return ActivityIndicatorAnimationRupee() + case .newtonCradle: + return ActivityIndicatorAnimationNewtonCradle() + case .circlePendulum: + return ActivityIndicatorAnimationCirclePendulum() } } } diff --git a/Sources/Enums/ActivityIndicatorType.swift b/Sources/Enums/ActivityIndicatorType.swift index 04eed61d..cd079469 100755 --- a/Sources/Enums/ActivityIndicatorType.swift +++ b/Sources/Enums/ActivityIndicatorType.swift @@ -46,4 +46,6 @@ public enum ActivityIndicatorType: String, IBEnum { case heartBeat case triforce case rupee + case newtonCradle + case circlePendulum } diff --git a/Sources/Protocols/ActivityIndicator/ActivityIndicatorAnimatable.swift b/Sources/Protocols/ActivityIndicator/ActivityIndicatorAnimatable.swift index 1d0d6adb..3001588a 100755 --- a/Sources/Protocols/ActivityIndicator/ActivityIndicatorAnimatable.swift +++ b/Sources/Protocols/ActivityIndicator/ActivityIndicatorAnimatable.swift @@ -48,8 +48,7 @@ private extension ActivityIndicatorAnimatable where Self: UIView { return } - let activityIndicator = ActivityIndicatorFactory.makeActivityIndicator(activityIndicatorType: animationType) - activityIndicator.configureAnimation(in: layer, size: bounds.size, color: color) + animationType.configureAnimation(in: layer, size: bounds.size, color: color) layer.speed = 1 } From 331f141400f29d6fbb97f349125aa408cfa03a23 Mon Sep 17 00:00:00 2001 From: Phimage Date: Sat, 30 Jun 2018 08:42:26 +0200 Subject: [PATCH 2/4] Update CHANGELOG and DOC for `newtonCradle` and `circlePendulum` --- CHANGELOG.md | 1 + Documentation/ActivityIndicators.md | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f01e097..c146f970 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ N/A - Add `preferred` presentation modal size. [#566](https://github.com/IBAnimatable/IBAnimatable/pull/566) by [@phimage](https://github.com/phimage) - Add `conical` gradient type. [#567](https://github.com/IBAnimatable/IBAnimatable/pull/567) by [@phimage](https://github.com/phimage) - Animatable `timingFunction` parameter could now be used with all animation types. [#571](https://github.com/IBAnimatable/IBAnimatable/pull/571) by [@phimage](https://github.com/phimage) +- Add new activity indicators `newtonCradle` and `circlePendulum`. [#573](https://github.com/IBAnimatable/IBAnimatable/pull/573) by [@phimage](https://github.com/phimage) #### Bugfixes diff --git a/Documentation/ActivityIndicators.md b/Documentation/ActivityIndicators.md index cd981aaf..d4d5356c 100644 --- a/Documentation/ActivityIndicators.md +++ b/Documentation/ActivityIndicators.md @@ -61,6 +61,9 @@ You can see an example of each animation in the demo app. Launch the app, then t 36. [HeartBeat](#heartbeat) 37. [Triforce](#triforce) 37. [Rupe](#rupe) +38. [NewtonCradle](#triforce) +39. [CirclePendulum](#circlependulum) + ### AudioEqualizer @@ -213,3 +216,11 @@ You can see an example of each animation in the demo app. Launch the app, then t ### Rupe ![ActivityIndicator - Rupe](https://raw.githubusercontent.com/IBAnimatable/IBAnimatable-Misc/master/IBAnimatable/ActivityIndicatorRupe.gif) + +### NewtonCradle + +![ActivityIndicator - NewtonCradle](https://raw.githubusercontent.com/IBAnimatable/IBAnimatable-Misc/master/IBAnimatable/ActivityIndicatorNewtonCradle.gif) + +### CirclePendulum + +![ActivityIndicator - CirclePendulum](https://raw.githubusercontent.com/IBAnimatable/IBAnimatable-Misc/master/IBAnimatable/ActivityIndicatorCirclePendulum.gif) From b94fdaaadacc57e3504025d707fbe57218406d4d Mon Sep 17 00:00:00 2001 From: Phimage Date: Sat, 30 Jun 2018 21:58:02 +0200 Subject: [PATCH 3/4] Better heat beating for `hearBeat` activity indicator --- .../Animations/ActivityIndicatorAnimationHeartBeat.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationHeartBeat.swift b/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationHeartBeat.swift index 1ad4838a..e373e239 100644 --- a/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationHeartBeat.swift +++ b/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationHeartBeat.swift @@ -12,7 +12,7 @@ public class ActivityIndicatorAnimationHeartBeat: ActivityIndicatorAnimating { // MARK: Properties - fileprivate let duration: CFTimeInterval = 1 + fileprivate let duration: CFTimeInterval = 0.8 // MARK: ActivityIndicatorAnimating @@ -33,12 +33,12 @@ private extension ActivityIndicatorAnimationHeartBeat { var defaultAnimation: CABasicAnimation { let scaleAnimation = CABasicAnimation(keyPath: .scale) - scaleAnimation.timingFunctionType = .easeIn + scaleAnimation.timingFunctionType = .easeOutBack scaleAnimation.duration = duration scaleAnimation.repeatCount = .infinity scaleAnimation.autoreverses = true scaleAnimation.fromValue = 1 - scaleAnimation.toValue = 0.7 + scaleAnimation.toValue = 0.8 scaleAnimation.isRemovedOnCompletion = false return scaleAnimation } From c6a8e7ba1479a7264d76675f48da6281e1ced41e Mon Sep 17 00:00:00 2001 From: Eric Marchand Date: Wed, 4 Jul 2018 14:32:38 +0200 Subject: [PATCH 4/4] Allow to edit variable to apply colors on activity indicator `triforce` and `circlePendulum` Use primary colors for `circlePendulum` Add doc about it --- Documentation/ActivityIndicators.md | 16 +++++++++++++++- ...ctivityIndicatorAnimationCirclePendulum.swift | 10 +++++----- .../ActivityIndicatorAnimationTriforce.swift | 4 ++-- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/Documentation/ActivityIndicators.md b/Documentation/ActivityIndicators.md index d4d5356c..6d2c72f4 100644 --- a/Documentation/ActivityIndicators.md +++ b/Documentation/ActivityIndicators.md @@ -61,7 +61,7 @@ You can see an example of each animation in the demo app. Launch the app, then t 36. [HeartBeat](#heartbeat) 37. [Triforce](#triforce) 37. [Rupe](#rupe) -38. [NewtonCradle](#triforce) +38. [NewtonCradle](#newtoncradle) 39. [CirclePendulum](#circlependulum) @@ -224,3 +224,17 @@ You can see an example of each animation in the demo app. Launch the app, then t ### CirclePendulum ![ActivityIndicator - CirclePendulum](https://raw.githubusercontent.com/IBAnimatable/IBAnimatable-Misc/master/IBAnimatable/ActivityIndicatorCirclePendulum.gif) + +## Easter eggs 🥚🐰 + +Compile this framework with flag + +- 🛡 `TRIFORCE` to reveal the true color of the `Triforce`: + - 🔺`red` for power. + - 🍃`green` for courage. + - 🔹`blue` for wisdom. +- 📺 `LG` to use the primary colors on `CirclePendulum`. + +### For Cocoapod + +Use in Podfile `build_settings['OTHER_SWIFT_FLAGS'] = '-THE_FLAG'` diff --git a/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationCirclePendulum.swift b/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationCirclePendulum.swift index 588d82b0..b9f15ac2 100644 --- a/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationCirclePendulum.swift +++ b/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationCirclePendulum.swift @@ -14,16 +14,16 @@ public class ActivityIndicatorAnimationCirclePendulum: ActivityIndicatorAnimatin // MARK: Properties - fileprivate let duration: CFTimeInterval = 1 + public var duration: CFTimeInterval = 0.8 fileprivate let ratio: CGFloat = 7 fileprivate let ballCount: Int = 3 #if LG - fileprivate let trueColor = true + public var primaryColor = true #else - fileprivate let trueColor = false + public var primaryColor = false #endif - fileprivate let colors: [UIColor] = [.red, .blue, .yellow] + fileprivate let colors: [UIColor] = [.magenta, .yellow, .cyan] fileprivate var ballSize: CGFloat = 0 @@ -35,7 +35,7 @@ public class ActivityIndicatorAnimationCirclePendulum: ActivityIndicatorAnimatin let yPos = size.height - ballSize / 2 for i in 0 ..< ballCount { - let ball = ActivityIndicatorShape.circle.makeLayer(size: CGSize(width: ballSize, height: ballSize), color: trueColor ? colors[i]: color) + let ball = ActivityIndicatorShape.circle.makeLayer(size: CGSize(width: ballSize, height: ballSize), color: primaryColor ? colors[i]: color) ball.frame = CGRect(x: xPos, y: yPos, width: ballSize, height: ballSize) ball.add(makeAnimation(for: ball, in: layer, size: size, pos: i), forKey: "animation") layer.addSublayer(ball) diff --git a/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationTriforce.swift b/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationTriforce.swift index 553240e8..ee518f49 100644 --- a/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationTriforce.swift +++ b/Sources/ActivityIndicators/Animations/ActivityIndicatorAnimationTriforce.swift @@ -14,9 +14,9 @@ public class ActivityIndicatorAnimationTriforce: ActivityIndicatorAnimating { fileprivate let duration: CFTimeInterval = 3 / 2 #if TRIFORCE - fileprivate let trueColor = true + public var trueColor = true #else - fileprivate let trueColor = false + public var trueColor = false #endif // MARK: ActivityIndicatorAnimating