Code Sketch


Easing function exploration via plotting
By: Lalit Pant
// This is a script to explore easing/interpolation functions via plotting

cleari()
showAxes()
showGrid()

val target = 300
val duration = 200
// change shownFn below to any of the "available" functions defined 
// further down in this script. Then run the script to see a plot of 
// how the function goes from 0 to target in the given time duration
// x axis shows time duration
// y axis shows progress towards target
val shownFn = elasticInOut(_)

def plot(xs: Seq[Int], ys: Seq[Double]) = Picture.fromVertexShape { s =>
    import s._
    beginShape()
    repeatFor(xs.zip(ys)) { case (x, y) =>
        vertex(x, y)
    }
    endShape()
}

// functions available for plotting in this script
def linear(x: Double) = x
def quad(x: Double) = math.pow(x, 2)
def cubic(x: Double) = math.pow(x, 3)

// the inbuilt Kojo easing functions take 4 inputs
// Our (simplified) plottable functions take 1 input
// the function defined below "adapts" a Kojo easing function 
// so that it becomes plottable in this script
def adaptedEasing(x: Double, easingFn: (Double, Double, Double, Double) => Double) =
    easingFn(0, target, x, duration)

def quadIn(x: Double) = adaptedEasing(x, easing.QuadIn.ease)
def quadOut(x: Double) = adaptedEasing(x, easing.QuadOut.ease)
def quadInOut(x: Double) = adaptedEasing(x, easing.QuadInOut.ease)

def elasticIn(x: Double) = adaptedEasing(x, easing.ElasticIn.ease)
def elasticOut(x: Double) = adaptedEasing(x, easing.ElasticOut.ease)
def elasticInOut(x: Double) = adaptedEasing(x, easing.ElasticInOut.ease)

def circIn(x: Double) = adaptedEasing(x, easing.CircIn.ease)
def circOut(x: Double) = adaptedEasing(x, easing.CircOut.ease)
def circInOut(x: Double) = adaptedEasing(x, easing.CircInOut.ease)

def expIn(x: Double) = adaptedEasing(x, easing.ExpoIn.ease)
def expOut(x: Double) = adaptedEasing(x, easing.ExpoOut.ease)
def expInOut(x: Double) = adaptedEasing(x, easing.ExpoInOut.ease)

// end of available functions section; add more above as desired

def normalizedYs(fn: Double => Double, xrange: Seq[Int], dest: Double): Seq[Double] = {
    val yvals = xrange.map(x => fn(x))
    val sf = dest / yvals.last
    yvals.map(y => y * sf)
}

val xs = 0 to duration
val ys = normalizedYs(shownFn, xs, target)
val pic = plot(xs, ys)
draw(pic)