Last active
April 12, 2017 00:23
-
-
Save erica/f33cdc7172135475d31d9aa743515e1c 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 Cocoa | |
extension BinaryFloatingPoint { | |
public var doubleValue: Double { | |
guard !(self is Double) else { return self as! Double } | |
guard !(self is Float) else { return Double(self as! Float) } | |
guard !(self is Float80) else { return Double(self as! Float80) } | |
guard !(self is CGFloat) else { return Double(self as! CGFloat) } | |
fatalError("Unsupported floating point type") | |
} | |
} | |
public enum InterpolationCurve { case linear, easeIn, easeOut, easeInOut } | |
public protocol Interpolating { | |
func interpolate(to value: Self, by percent: Double, curve: InterpolationCurve) -> Self | |
} | |
extension BinaryFloatingPoint { | |
public func interpolate(to value: Self, by percent: Double, style: InterpolationCurve = .linear) -> Self { | |
let distance = (value - self).doubleValue | |
switch style { | |
case .linear: | |
return self + Self(distance * percent) | |
case .easeIn: | |
return self + Self(distance * pow(percent, 3)) | |
case .easeOut: | |
return self + Self(distance * (1 - pow(1 - percent, 3))) | |
case .easeInOut where percent < 0.5: | |
return self + Self(0.5 * distance * pow(percent * 2, 3)) | |
case .easeInOut: | |
return self + Self(0.5 * distance * (2 - pow(2 - 2 * percent, 3))) | |
} | |
} | |
} | |
for percent in stride(from: 0.0, through: 1.0, by: 0.05) { | |
0.0.interpolate(to: 1.0, by: percent, style: .linear) | |
0.0.interpolate(to: 1.0, by: percent, style: .easeIn) | |
0.0.interpolate(to: 1.0, by: percent, style: .easeOut) | |
0.0.interpolate(to: 1.0, by: percent, style: .easeInOut) | |
} | |
extension CGPoint: Interpolating { | |
public func interpolate(to value: CGPoint, by percent: Double, curve: InterpolationCurve) -> CGPoint { | |
return CGPoint( | |
x: self.x.interpolate(to: value.x, by: percent, style: curve), | |
y: self.y.interpolate(to: value.y, by: percent, style: curve) | |
) | |
} | |
} | |
let p1 = CGPoint.zero | |
let p2 = CGPoint(x: 1, y: 1) | |
for percent in stride(from: 0.0, through: 1.0, by: 0.05) { | |
let px = p1.interpolate(to: p2, by: percent, curve: .easeInOut) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment