Skip to content

Instantly share code, notes, and snippets.

@aarongeorge
Last active March 17, 2021 06:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aarongeorge/3abe73d67f7c9f6d6038dae52f9595fb to your computer and use it in GitHub Desktop.
Save aarongeorge/3abe73d67f7c9f6d6038dae52f9595fb to your computer and use it in GitHub Desktop.
A minimal tweening class, utilising stepped updates with optional easing
// A minimal tweening class, utilising stepped updates with optional easing
class Tween {
constructor ({ from, to, change, steps, easeFn, duration, cb }) {
this.from = from
this.to = typeof to === 'undefined' ? from + change : to
this.change = typeof change === 'undefined' ? to - from : change
this.steps = typeof steps === 'number' ? steps : duration / 16
this.duration = duration
this.easeFn = typeof easeFn !== 'function' ? t => t : easeFn
this.cb = typeof cb === 'undefined' ? () => {} : cb
this.step = 0
this.update = this.update.bind(this)
}
tick () { this.step < this.steps && this.step++ }
update (now) {
if (now > this.endTime) {
this.step = this.steps
return this.stop()
}
this.requestId = window.requestAnimationFrame(this.update)
if (this.step < (now / this.endTime) * this.steps | 0) {
this.tick()
this.cb(this.value)
}
}
start () {
this.startTime = window.performance.now()
this.endTime = this.startTime + this.duration
this.requestId = window.requestAnimationFrame(this.update)
}
stop () {
if (this.requestId) window.cancelAnimationFrame(this.requestId)
this.cb(this.value)
}
get value () { return this.from + (this.to - this.from) * this.easeFn(this.step / this.steps) }
}
// Example One (Using `from` and `to`)
const exampleOne = new Tween({
from: -10,
to: 0,
steps: 5,
duration: 1000,
cb: v => console.log(v)
}).start()
// Example Two (Using `from` and `change`)
const exampleTwo = new Tween({
from: -10,
change: 10,
steps: 5,
duration: 1000,
cb: v => console.log(v)
}).start()
// Example Three (Using `easeFn`)
const exampleThree = new Tween({
from: 0,
to: 10,
steps: 5,
duration: 1000,
cb: v => console.log(v),
easeFn: t => t < .5 ? Math.pow(t * 2, 2) / 2 : (1 - Math.pow(1 - (t * 2 - 1), 2)) / 2 + .5
}).start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment