mirror of
https://github.com/exyte/Macaw.git
synced 2024-10-10 19:37:32 +03:00
Animation refactoring
This commit is contained in:
parent
23594868c6
commit
d2c3f0e65c
@ -131,19 +131,23 @@ class ThirdPageCustomView: MacawView {
|
||||
|
||||
super.init(node: group, coder: aDecoder)
|
||||
|
||||
let cloud1ShapeAnimation = Animation(observableProperty: cloud1.posProperty,
|
||||
let cloud1ShapeAnimation = Animation(observableValue: cloud1.posProperty,
|
||||
finalValue:Transform.move(120, my: 120).scale(0.3, sy: 0.3),
|
||||
animationDuration: 1.5)
|
||||
|
||||
let cloud2ShapeAnimation = Animation(observableProperty: cloud2.posProperty,
|
||||
let cloud2ShapeAnimation = Animation(observableValue: cloud2.posProperty,
|
||||
finalValue:Transform.move(100, my: 320).scale(0.075, sy: 0.075),
|
||||
animationDuration: 1.5)
|
||||
|
||||
let cloud3ShapeAnimation = Animation(observableProperty: cloud3.posProperty,
|
||||
let cloud3ShapeAnimation = Animation(observableValue: cloud3.posProperty,
|
||||
finalValue:Transform.move(220, my: 420).scale(0.15, sy: 0.15),
|
||||
animationDuration: 1.5)
|
||||
|
||||
let animation = [cloud1ShapeAnimation, cloud2ShapeAnimation, cloud3ShapeAnimation].sequence().looped().infiniteLoop()
|
||||
let animation = [
|
||||
cloud1ShapeAnimation,
|
||||
cloud2ShapeAnimation,
|
||||
cloud3ShapeAnimation
|
||||
].sequence().looped().infiniteLoop()
|
||||
super.addAnimation(animation)
|
||||
|
||||
// super.addAnimation(cloud1ShapeAnimation)
|
||||
|
@ -15,7 +15,7 @@
|
||||
574223901CA5448C001EE463 /* Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5742238F1CA5448C001EE463 /* Animation.swift */; };
|
||||
574223921CA55360001EE463 /* AnimationSubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 574223911CA55360001EE463 /* AnimationSubscription.swift */; };
|
||||
574BDD921CAA7FC50031D313 /* IntInterpolation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 574BDD911CAA7FC50031D313 /* IntInterpolation.swift */; };
|
||||
574BDD941CAA80070031D313 /* TypeInterpolation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 574BDD931CAA80070031D313 /* TypeInterpolation.swift */; };
|
||||
574BDD941CAA80070031D313 /* Interpolable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 574BDD931CAA80070031D313 /* Interpolable.swift */; };
|
||||
574BDD961CAA861B0031D313 /* CGFloatInterpolation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 574BDD951CAA861B0031D313 /* CGFloatInterpolation.swift */; };
|
||||
574BDD981CAA86CC0031D313 /* CGPointInterpolation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 574BDD971CAA86CC0031D313 /* CGPointInterpolation.swift */; };
|
||||
574BDD9A1CAAA5540031D313 /* DoubleInterpolation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 574BDD991CAAA5540031D313 /* DoubleInterpolation.swift */; };
|
||||
@ -89,7 +89,7 @@
|
||||
5742238F1CA5448C001EE463 /* Animation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Animation.swift; sourceTree = "<group>"; };
|
||||
574223911CA55360001EE463 /* AnimationSubscription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimationSubscription.swift; sourceTree = "<group>"; };
|
||||
574BDD911CAA7FC50031D313 /* IntInterpolation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntInterpolation.swift; sourceTree = "<group>"; };
|
||||
574BDD931CAA80070031D313 /* TypeInterpolation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeInterpolation.swift; sourceTree = "<group>"; };
|
||||
574BDD931CAA80070031D313 /* Interpolable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Interpolable.swift; sourceTree = "<group>"; };
|
||||
574BDD951CAA861B0031D313 /* CGFloatInterpolation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGFloatInterpolation.swift; sourceTree = "<group>"; };
|
||||
574BDD971CAA86CC0031D313 /* CGPointInterpolation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGPointInterpolation.swift; sourceTree = "<group>"; };
|
||||
574BDD991CAAA5540031D313 /* DoubleInterpolation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoubleInterpolation.swift; sourceTree = "<group>"; };
|
||||
@ -186,7 +186,7 @@
|
||||
5742238D1CA5414E001EE463 /* AnimationLoop.swift */,
|
||||
5742238F1CA5448C001EE463 /* Animation.swift */,
|
||||
574223911CA55360001EE463 /* AnimationSubscription.swift */,
|
||||
574BDD931CAA80070031D313 /* TypeInterpolation.swift */,
|
||||
574BDD931CAA80070031D313 /* Interpolable.swift */,
|
||||
);
|
||||
path = animation;
|
||||
sourceTree = "<group>";
|
||||
@ -456,7 +456,7 @@
|
||||
B03275FB1C78772F000BDD33 /* Line.swift in Sources */,
|
||||
B032760A1C78772F000BDD33 /* Transform.swift in Sources */,
|
||||
B032760C1C78772F000BDD33 /* Cursor.swift in Sources */,
|
||||
574BDD941CAA80070031D313 /* TypeInterpolation.swift in Sources */,
|
||||
574BDD941CAA80070031D313 /* Interpolable.swift in Sources */,
|
||||
B03275EF1C78772F000BDD33 /* LineCap.swift in Sources */,
|
||||
573AA6A41CAE402C00F30607 /* RevertedAnimation.swift in Sources */,
|
||||
573AA6A61CAE41D400F30607 /* LoopedAnimation.swift in Sources */,
|
||||
|
@ -1,41 +1,34 @@
|
||||
import Foundation
|
||||
|
||||
public protocol CommonAnimation {
|
||||
|
||||
public protocol Animatable {
|
||||
func animate(progress: Double)
|
||||
func getDuration() -> Double
|
||||
}
|
||||
|
||||
public class Animation<T: InterpolatingType>: CommonAnimation {
|
||||
public class Animation<T: Interpolable>: Animatable {
|
||||
|
||||
var property: ObservableValue<T>?
|
||||
let value: ObservableValue<T>
|
||||
|
||||
var start: T?
|
||||
var final: T?
|
||||
var duration: Double = 0
|
||||
let start: T
|
||||
let final: T
|
||||
let duration: Double
|
||||
|
||||
public required init(observableProperty: ObservableValue<T>?, startValue: T?, finalValue: T?, animationDuration: Double) {
|
||||
property = observableProperty
|
||||
public required init(observableValue: ObservableValue<T>, startValue: T, finalValue: T, animationDuration: Double) {
|
||||
value = observableValue
|
||||
start = startValue
|
||||
final = finalValue
|
||||
duration = animationDuration
|
||||
|
||||
}
|
||||
|
||||
public convenience init(observableProperty: ObservableValue<T>?, finalValue: T, animationDuration: Double) {
|
||||
self.init(observableProperty: observableProperty, startValue: observableProperty?.get(), finalValue: finalValue, animationDuration: animationDuration )
|
||||
public convenience init(observableValue: ObservableValue<T>, finalValue: T, animationDuration: Double) {
|
||||
self.init(observableValue: observableValue, startValue: observableValue.get(), finalValue: finalValue, animationDuration: animationDuration )
|
||||
}
|
||||
|
||||
public func animate(progress: Double) {
|
||||
|
||||
guard let start = start else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let final = final else {
|
||||
return
|
||||
}
|
||||
|
||||
property?.set(start.interpolate(final, progress: progress))
|
||||
value.set(start.interpolate(final, progress: progress))
|
||||
}
|
||||
|
||||
public func getDuration() -> Double {
|
||||
|
@ -20,10 +20,6 @@ class AnimationLoop {
|
||||
|
||||
animationSubscriptions.forEach { subscription in
|
||||
|
||||
guard let animation = subscription.anim else {
|
||||
return
|
||||
}
|
||||
|
||||
if subscription.startTime == .None {
|
||||
subscription.startTime = displayLink.timestamp
|
||||
}
|
||||
@ -33,7 +29,7 @@ class AnimationLoop {
|
||||
}
|
||||
|
||||
let timePosition = displayLink.timestamp - startTime
|
||||
let position = timePosition / animation.getDuration()
|
||||
let position = timePosition / subscription.anim.getDuration()
|
||||
|
||||
if position > 1.0 {
|
||||
toRemove.append(subscription)
|
||||
|
@ -2,15 +2,15 @@ import Foundation
|
||||
|
||||
class AnimationSubscription {
|
||||
|
||||
var anim: CommonAnimation?
|
||||
let anim: Animatable
|
||||
|
||||
var startTime: CFTimeInterval?
|
||||
|
||||
init( animation: CommonAnimation ) {
|
||||
init( animation: Animatable ) {
|
||||
anim = animation
|
||||
}
|
||||
|
||||
func moveToTimeFrame(position: Double, advance: Double) {
|
||||
anim?.animate(position)
|
||||
anim.animate(position)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Foundation
|
||||
|
||||
public protocol InterpolatingType {
|
||||
public protocol Interpolable {
|
||||
func interpolate(endValue: Self, progress: Double) -> Self
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import UIKit
|
||||
|
||||
extension CGFloat: InterpolatingType {
|
||||
extension CGFloat: Interpolable {
|
||||
public func interpolate(endValue: CGFloat, progress: Double) -> CGFloat {
|
||||
return self * CGFloat(1.0 - progress) + endValue * CGFloat(progress)
|
||||
return self + (endValue - self) * CGFloat(progress)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import UIKit
|
||||
|
||||
extension CGPoint: InterpolatingType {
|
||||
extension CGPoint: Interpolable {
|
||||
public func interpolate(endValue: CGPoint, progress: Double) -> CGPoint {
|
||||
return CGPoint(x: self.x.interpolate(endValue.x, progress: progress),
|
||||
y: self.y.interpolate(endValue.y, progress: progress))
|
||||
|
@ -1,7 +1,7 @@
|
||||
import Foundation
|
||||
|
||||
extension Double: InterpolatingType {
|
||||
extension Double: Interpolable {
|
||||
public func interpolate(endValue: Double, progress: Double) -> Double {
|
||||
return self * (1.0 - progress) + endValue * progress
|
||||
return self + (endValue - self) * progress
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
import Foundation
|
||||
|
||||
extension Int: InterpolatingType {
|
||||
extension Int: Interpolable {
|
||||
public func interpolate(endValue: Int, progress: Double) -> Int {
|
||||
|
||||
return Int(Double(self) * (1.0 - progress) + Double(endValue) * progress)
|
||||
return Int(Double(self) + Double(endValue - self) * progress)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Foundation
|
||||
|
||||
extension Transform: InterpolatingType {
|
||||
extension Transform: Interpolable {
|
||||
public func interpolate(endValue: Transform, progress: Double) -> Transform {
|
||||
return Transform(m11: self.m11.interpolate(endValue.m11, progress: progress),
|
||||
m12: self.m12.interpolate(endValue.m12, progress: progress),
|
||||
|
@ -1,7 +1,7 @@
|
||||
import Foundation
|
||||
|
||||
public extension SequenceType where Generator.Element: CommonAnimation{
|
||||
public func sequence() -> CommonAnimation {
|
||||
public extension SequenceType where Generator.Element: Animatable{
|
||||
public func sequence() -> Animatable {
|
||||
let sequence = AnimationSequence(animations:[])
|
||||
self.forEach { animation in
|
||||
sequence.addAnimation(animation)
|
||||
@ -11,20 +11,20 @@ public extension SequenceType where Generator.Element: CommonAnimation{
|
||||
}
|
||||
}
|
||||
|
||||
public class AnimationSequence: CommonAnimation {
|
||||
public class AnimationSequence: Animatable {
|
||||
|
||||
var sequence: [CommonAnimation] = []
|
||||
var sequence: [Animatable] = []
|
||||
|
||||
|
||||
public required init(animations: [CommonAnimation]) {
|
||||
public required init(animations: [Animatable]) {
|
||||
sequence.appendContentsOf(animations)
|
||||
}
|
||||
|
||||
public convenience init(animation: CommonAnimation) {
|
||||
public convenience init(animation: Animatable) {
|
||||
self.init(animations: [animation])
|
||||
}
|
||||
|
||||
public func addAnimation(animation: CommonAnimation) {
|
||||
public func addAnimation(animation: Animatable) {
|
||||
sequence.append(animation)
|
||||
}
|
||||
|
||||
|
@ -1,27 +1,23 @@
|
||||
import Foundation
|
||||
|
||||
public extension CommonAnimation {
|
||||
public func looped() -> CommonAnimation {
|
||||
public extension Animatable {
|
||||
public func looped() -> Animatable {
|
||||
return LoopedAnimation(animation: self)
|
||||
}
|
||||
}
|
||||
|
||||
public class LoopedAnimation: CommonAnimation {
|
||||
var loopedlAnimation: CommonAnimation?
|
||||
public class LoopedAnimation: Animatable {
|
||||
let loopedlAnimation: Animatable
|
||||
|
||||
public required init(animation: CommonAnimation) {
|
||||
public required init(animation: Animatable) {
|
||||
loopedlAnimation = AnimationSequence(animations: [animation, RevertedAnimation(animation: animation)])
|
||||
}
|
||||
|
||||
public func animate(progress: Double) {
|
||||
loopedlAnimation?.animate(progress)
|
||||
loopedlAnimation.animate(progress)
|
||||
}
|
||||
|
||||
public func getDuration() -> Double {
|
||||
guard let duration = loopedlAnimation?.getDuration() else {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
return duration
|
||||
return loopedlAnimation.getDuration()
|
||||
}
|
||||
}
|
||||
|
@ -6,22 +6,22 @@ public enum RepetitiveAnimationType {
|
||||
case Infinite
|
||||
}
|
||||
|
||||
public extension CommonAnimation {
|
||||
public func infiniteLoop() -> CommonAnimation {
|
||||
public extension Animatable {
|
||||
public func infiniteLoop() -> Animatable {
|
||||
return RepetitiveAnimation(animation: self)
|
||||
}
|
||||
|
||||
public func loop(count: Int) -> CommonAnimation {
|
||||
public func loop(count: Int) -> Animatable {
|
||||
return RepetitiveAnimation(animation: self, count: count)
|
||||
}
|
||||
}
|
||||
|
||||
public class RepetitiveAnimation: CommonAnimation {
|
||||
public class RepetitiveAnimation: Animatable {
|
||||
|
||||
var loopAnimation: CommonAnimation?
|
||||
var loopsCount = 0
|
||||
let loopAnimation: Animatable
|
||||
var loopsCount: Int
|
||||
|
||||
public required init(animation: CommonAnimation, type: RepetitiveAnimationType, count: Int) {
|
||||
public required init(animation: Animatable, type: RepetitiveAnimationType, count: Int) {
|
||||
loopAnimation = animation
|
||||
loopsCount = count
|
||||
|
||||
@ -30,11 +30,11 @@ public class RepetitiveAnimation: CommonAnimation {
|
||||
}
|
||||
}
|
||||
|
||||
public convenience init(animation: CommonAnimation, count: Int) {
|
||||
public convenience init(animation: Animatable, count: Int) {
|
||||
self.init(animation: animation, type: .Finite, count: count)
|
||||
}
|
||||
|
||||
public convenience init(animation: CommonAnimation) {
|
||||
public convenience init(animation: Animatable) {
|
||||
self.init(animation: animation, type: .Infinite, count: 0)
|
||||
}
|
||||
|
||||
@ -42,14 +42,10 @@ public class RepetitiveAnimation: CommonAnimation {
|
||||
let progressInterval = 1.0 / Double(loopsCount)
|
||||
let relativeProgress = (progress % progressInterval) * Double(loopsCount)
|
||||
|
||||
loopAnimation?.animate(relativeProgress)
|
||||
loopAnimation.animate(relativeProgress)
|
||||
}
|
||||
|
||||
public func getDuration() -> Double {
|
||||
guard let duration = loopAnimation?.getDuration() else {
|
||||
return 0
|
||||
}
|
||||
|
||||
return Double(loopsCount) * duration
|
||||
return Double(loopsCount) * loopAnimation.getDuration()
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,24 @@
|
||||
import Foundation
|
||||
|
||||
|
||||
public extension CommonAnimation {
|
||||
public func revert() -> CommonAnimation {
|
||||
public extension Animatable {
|
||||
public func revert() -> Animatable {
|
||||
return RevertedAnimation(animation: self)
|
||||
}
|
||||
}
|
||||
|
||||
public class RevertedAnimation: CommonAnimation {
|
||||
var originalAnimation: CommonAnimation?
|
||||
public class RevertedAnimation: Animatable {
|
||||
let originalAnimation: Animatable
|
||||
|
||||
public required init(animation: CommonAnimation) {
|
||||
public required init(animation: Animatable) {
|
||||
originalAnimation = animation
|
||||
}
|
||||
|
||||
public func animate(progress: Double) {
|
||||
originalAnimation?.animate(1.0 - progress)
|
||||
originalAnimation.animate(1.0 - progress)
|
||||
}
|
||||
|
||||
public func getDuration() -> Double {
|
||||
guard let duration = originalAnimation?.getDuration() else {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
return duration
|
||||
return originalAnimation.getDuration()
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public class MacawView: UIView {
|
||||
renderer.render()
|
||||
}
|
||||
|
||||
public func addAnimation(animation: CommonAnimation) {
|
||||
public func addAnimation(animation: Animatable) {
|
||||
let subscription = AnimationSubscription(animation: animation)
|
||||
self.loop?.animationSubscriptions.append(subscription)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user