Skip to content

Instantly share code, notes, and snippets.

@qwtel
Last active November 6, 2018 18:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qwtel/0fcb501cd405252ae7d5ccc8a987f372 to your computer and use it in GitHub Desktop.
Save qwtel/0fcb501cd405252ae7d5ccc8a987f372 to your computer and use it in GitHub Desktop.
rxjs5 tweening helper function. Creates a tween observable that emits samples from an easing function via requestAnimationFrame.
import { Observable } from 'rxjs/Observable';
/**
* Creates an observable that emits samples from an easing function on every animation frame
* for a duration `d` ms.
*
* The first emitted value will be a sample form the easing function at `t = 0`,
* and the last emitted value is guaranteed to be the easing function at `t = d`.
*
* It can be used with any of [Robert Penner's easing functions](http://robertpenner.com/easing/),
* i.e. functions with a signature of `(t, b, c, d, s)`, where
* `t`: current time, `b`: beginning value, `c`: change in value, `d`: total duration, `s`: optional
*
* @param {function(t: number, b: number, c: number, d: number, [s]: number): number} easingFunction
* - the easing fuction to sample from; can use any of Robert Penner's easing functions
* @param {number} b - beginning value and 2nd parameter of the easing function
* @param {number} c - change in value (or end value) and 3rd parameter of the easing function
* @param {number} d - total duration of the tween in ms and 4th parameter of the easing function
* @param {number} [s] - 5th parameter of the easing function (optional)
* @return {Observable<number>}
* - an observable emitting samples of the easing function on animation frames for `d` ms
*/
export function createTween(easingFunction, b, c, d, s) {
return Observable.create((observer) => {
let startTime;
let id = requestAnimationFrame(function sample(time) {
startTime = startTime || time;
const t = time - startTime;
if (t < d) {
observer.next(easingFunction(t, b, c, d, s));
id = requestAnimationFrame(sample);
} else {
observer.next(easingFunction(d, b, c, d, s));
id = requestAnimationFrame(() => observer.complete());
}
});
return () => { if (id) { cancelAnimationFrame(id); } };
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment