Last active
August 29, 2015 14:25
-
-
Save felixvisee/9d2ae41b41321b2a24c4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import CoreGraphics | |
public struct Interpolation<Value> { | |
private let interpolateFunc: (from: Value, to: Value, at: CGFloat) -> Value | |
public init(interpolate interpolateFunc: (from: Value, to: Value, at: CGFloat) -> Value) { | |
self.interpolateFunc = interpolateFunc | |
} | |
public func interpolate(from: Value, to: Value, at: CGFloat) -> Value { | |
return interpolateFunc(from: from, to: to, at: at) | |
} | |
} | |
public protocol Interpolatable { | |
typealias ValueType | |
func interpolation() -> Interpolation<ValueType> | |
} | |
extension Interpolation: Interpolatable { | |
public func interpolation() -> Interpolation<Value> { | |
return self | |
} | |
} | |
extension CGFloat: Interpolatable { | |
public func interpolation() -> Interpolation<CGFloat> { | |
return Interpolation { from, to, at in | |
return (to - from) * at + from | |
} | |
} | |
} | |
public struct Keyframe<Value> { | |
public var time: CGFloat | |
public var value: Value | |
public var interpolation: Interpolation<Value> | |
public init<I: Interpolatable where I.ValueType == Value>(time: CGFloat, value: Value, interpolation: I) { | |
self.time = time | |
self.value = value | |
self.interpolation = interpolation.interpolation() | |
} | |
} | |
public extension Keyframe { | |
public init(time: CGFloat, value: Value, interpolate: (from: Value, to: Value, at: CGFloat) -> Value) { | |
self.init(time: time, value: value, interpolation: Interpolation(interpolate: interpolate)) | |
} | |
} | |
public extension Keyframe where Value: Interpolatable, Value.ValueType == Value { | |
public init(time: CGFloat, value: Value) { | |
self.init(time: time, value: value, interpolation: value) | |
} | |
} | |
public func inbetween<Value>(start start: Keyframe<Value>, end: Keyframe<Value>) -> (at: CGFloat) -> Value { | |
return { at in | |
return end.interpolation.interpolate(start.value, to: end.value, at: at) | |
} | |
} | |
do { | |
let start = Keyframe<CGFloat>(time: 0, value: 0) | |
let end = Keyframe<CGFloat>(time: 1, value: 1) | |
inbetween(start: start, end: end)(at: 0.5) // 0.5 | |
} | |
do { | |
let start = Keyframe<CGFloat>(time: 0, value: 0) | |
let end = Keyframe<CGFloat>(time: 1, value: 1) { from, to, at in | |
return (to - from) * at / 2 + from | |
} | |
inbetween(start: start, end: end)(at: 0.5) // 0.25 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment