Skip to content

Instantly share code, notes, and snippets.

@erica
Last active April 12, 2017 00:23
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save erica/f33cdc7172135475d31d9aa743515e1c to your computer and use it in GitHub Desktop.
Save erica/f33cdc7172135475d31d9aa743515e1c to your computer and use it in GitHub Desktop.
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