Creates an observable that emits samples from an easing function on every animation frame for a fixed duration.
Supports arbitrary easing functions. Works well with tween-functions
.
import { createTween } from 'rxjs-create-tween';
import { easeOutSine } from 'tween-functions';
click$
.switchMap(() => {
const startX = 0; // px
const endX = 300; // px
const duration = 250; // ms
return createTween(easeOutSine, startX, endX, duration);
})
.subscribe({
// emits a value on every animation frame
next: (x) => {
// guaranteed to start with `startX` and end with `endX`.
el.style.transform = `translateX(${x})`;
},
// completes 1 frame after the last value was emitted
complete: () => {
el.style.transform = '';
el.classList.add('completed');
},
});
export function createTween(easingFunction, b, c, d, s) {
return Observable.create(function(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(function() {
return observer.complete();
});
}
});
return function() {
if (id) {
cancelAnimationFrame(id);
}
};
});
}
export default createTween;