Experiments >

Restoring an easing function

Experiment #4815th March, 2021by Joshua Nussbaum

Last week I created a pausible tweened store, but it didn’t work right with easing functions.

I did some investigating, and the problem was that when un-pausing a tween, the easing function starts over again from the beginning. For example: say you have a tween setup for a duration 4 seconds, if we pause at 2.5 seconds, and then continue on, we have 1.5 seconds remaining. But we don’t want the easing to start from scratch (time=0), we want the easing to continue on from the last paused time (2.5s).

The challenge is that svelte’s tweened store doesn’t share how much time was elapsed. I could re-write the entire tweened store from scratch to capture the time elapsed, but I used a hack instead. Since the easing(t) function receives the elapsed time as parameter t, I can wrap the easing function and capture the elapsed time:

// store time elapsed
let elapsed

// wrap the easing function
const wrappedEasingFn = t => {
  // capture the time elapsed
  elapsed = t

  // call actual easing function
  return elasticInOut(t)
}

// use the wrapped function when defininf the store
const store = tweened(0, {duration: 0, easing: wrappedEasingFn})

Then to restore the easing:

// compute amount remaining using the globally stored `elapsed` var,
// it's a value between 0 to 1.0
const remaining = 1-elapsed
// compute remaining time
const remainingMs = remaining*duration
// create a patched version of the easing function
// that skews the parameter t to take into account time elapsed before the pause
const skewedEasing = t => easing(elapsed + (t*remaining))

// trigger the continuation of the tween
store.set(max, {duration: remainingMs, easing: skewedEasing})

Code

https://svelte.dev/repl/675a44d7781e4bb4bf00f13caae261c5?version=3.35.0

view all experiments

Stay tuned in

Learn how to add more experimentation to your workflow