Skip to content

Instantly share code, notes, and snippets.

@sebastienwindal
Created August 6, 2017 05:15
Show Gist options
  • Save sebastienwindal/617ba02e8adf3cd1226afc964c640f82 to your computer and use it in GitHub Desktop.
Save sebastienwindal/617ba02e8adf3cd1226afc964c640f82 to your computer and use it in GitHub Desktop.
enum Easing {
// Linear interpolation (no easing)
case linear
// Quadratic easing; p^2
case quadraticIn
case quadraticOut
case quadraticInOut
// Cubic easing; p^3
case cubicIn
case cubicOut
case cubicInOut
// Quartic easing; p^4
case quarticIn
case quarticOut
case quarticInOut
// Quintic easing; p^5
case quinticIn
case quinticOut
case quinticInOut
// Sine wave easing; sin(p * PI/2)
case sineIn
case sineOut
case sineInOut
// Circular easing; sqrt(1 - p^2)
case circularIn
case circularOut
case circularInOut
// Exponential easing, base 2
case exponentialIn
case exponentialOut
case exponentialInOut
// Exponentially-damped sine wave easing
case elasticIn
case elasticOut
case elasticInOut
// Overshooting cubic easing;
case backIn
case backOut
case backInOut
// Exponentially-decaying bounce easing
case bounceIn
case bounceOut
case bounceInOut
// t: current time, b: begInnIng value, c: change In value, d: duration
func interpolate(time t:Double, beginning b:Double, change c:Double, duration d:Double) -> Double {
let normalizedT = t / d
switch self {
case .linear: return c * normalizedT + b
case .quadraticIn: return c * normalizedT * normalizedT + b
case .quadraticOut: return -c * (normalizedT) * (normalizedT - 2.0) + b
case .quadraticInOut:
var tt = t / (d / 2.0)
if (tt < 1.0) { return c/2.0 * tt * tt + b }
tt -= 1.0
return -c / 2.0 * (tt * (tt - 2.0) - 1.0) + b
case .cubicIn:
return c * normalizedT * normalizedT * normalizedT + b
case .cubicOut:
let tt = t / d - 1.0
return c * (tt * tt * tt + 1.0) + b
case .cubicInOut:
var tt = t / (d / 2.0)
if (tt < 1) { return c / 2.0 * tt * tt * tt + b }
tt -= 2.0
return c / 2.0 * (tt * tt * tt + 2.0) + b
case .quarticIn:
return c * normalizedT * normalizedT * normalizedT * normalizedT + b
case .quarticOut:
let tt = t / d - 1.0
return -c * (tt * tt * tt * tt - 1) + b
case .quarticInOut:
var tt = t / (d / 2.0)
if (tt < 1) { return c / 2.0 * tt * tt * tt * tt + b }
tt -= 2.0
return -c / 2.0 * (tt * tt * tt * tt - 2.0) + b
case .quinticIn:
return c * normalizedT * normalizedT * normalizedT * normalizedT * normalizedT + b
case .quinticOut:
let tt = t / d - 1.0
return c * (tt * tt * tt * tt * tt + 1.0) + b
case .quinticInOut:
var tt = t / (d/2.0)
if (tt < 1.0) { return c / 2.0 * tt * tt * tt * tt * tt + b }
tt -= 2.0
return c / 2.0 * (tt * tt * tt * tt * tt + 2.0) + b
case .sineIn:
return -c * cos(t/d * (Double.pi / 2.0)) + c + b
case .sineOut:
return c * sin(t/d * (Double.pi / 2.0)) + b
case .sineInOut:
return -c / 2.0 * (cos(Double.pi * t / d) - 1.0) + b
case .circularIn:
return -c * (sqrt(1 - normalizedT * normalizedT) - 1.0) + b
case .circularOut:
let tt = t / d - 1.0
return c * sqrt(1 - (tt * tt)) + b
case .circularInOut:
var tt = t / (d / 2.0)
if (tt < 1.0) { return -c / 2.0 * (sqrt(1 - tt * tt) - 1) + b }
tt -= 2.0
return c / 2.0 * (sqrt(1.0 - tt * tt) + 1.0) + b
case .exponentialIn:
return (t==0) ? b : c * pow(2.0, 10.0 * (t/d - 1.0)) + b
case .exponentialOut:
return (t==d) ? b+c : c * (-pow(2.0, -10.0 * t/d) + 1.0) + b
case .exponentialInOut:
if (t==0) { return b }
if (t==d) { return b+c }
var tt = t / (d/2.0)
if (tt < 1.0) { return c/2.0 * pow(2.0, 10.0 * (t - 1.0)) + b }
tt -= 1
return c/2.0 * (-pow(2.0, -10.0 * tt) + 2) + b
case .elasticIn:
if t == 0 { return b }
var tt = normalizedT
if (tt==1.0) { return b+c }
let p = d * 0.3
let a = c
let s = p / 4.0
tt -= 1.0
return -(a * pow(2.0,10.0 * tt) * sin( (tt * d - s ) * (2.0 * Double.pi) / p)) + b
case .elasticOut:
if t==0 { return b }
var tt = normalizedT
if tt == 1 { return b + c }
let p = d * 0.3
let a = c
let s = p / 4.0
return (a * pow(2.0,-10.0 * tt) * sin( (tt * d - s) * (2.0 * Double.pi) / p ) + c + b)
case .elasticInOut:
if t == 0 { return b }
var tt = t / (d/2.0)
if tt == 2.0 { return b + c }
let p = d * (0.3 * 1.5)
let a = c
let s = p / 4.0
if tt < 1.0 {
tt -= 1.0
return -0.5 * (a * pow(2.0,10.0 * tt) * sin( (tt * d - s) * (2.0 * Double.pi) / p)) + b
}
tt -= 1.0
return a * pow(2.0,-10.0*tt) * sin( (tt * d - s) * (2.0 * Double.pi) / p) * 0.5 + c + b
case .backIn:
let s = 1.70158
return c * normalizedT * normalizedT * ((s+1.0)*normalizedT - s) + b;
case .backOut:
let s = 1.70158
let tt = t / d - 1.0
return c * (tt * tt * ((s+1) * tt + s) + 1.0) + b
case .backInOut:
var s = 1.70158 * 1.525
var tt = t / (d / 2.0)
if (tt < 1) {
return c / 2.0 * (tt * tt * ((s + 1.0) * tt - s)) + b
}
tt -= 2.0
return c / 2.0 * (tt * tt * ((s + 1) * tt + s) + 2) + b
case .bounceIn:
return c - Easing.bounceOut.interpolate(time:d-t, beginning:0, change:c, duration:d) + b
case .bounceOut:
var tt = normalizedT
if (tt < (1.0/2.75)) {
return c * (7.5625 * tt * tt) + b
} else if (tt < (2.0/2.75)) {
tt -= (1.5/2.75)
return c * (7.5625 * tt * tt + 0.75) + b;
} else if (tt < (2.5/2.75)) {
tt -= (2.25/2.75)
return c * (7.5625*tt*tt + 0.9375) + b;
} else {
tt -= 2.625/2.75
return c * (7.5625 * tt * tt + 0.984375) + b
}
case .bounceInOut:
if (t < d/2) {
return Easing.bounceIn.interpolate(time:t*2.0, beginning:0, change:c, duration:d) * 0.5 + b
}
return Easing.bounceOut.interpolate(time:t*2.0-d, beginning:0, change:c, duration:d) * 0.5 + c * 0.5 + b
default: return 0.0
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment