rxjs-create-tween

Create observables that sample from easing functions on animation frames

Usage no npm install needed!

<script type="module">
  import rxjsCreateTween from 'https://cdn.skypack.dev/rxjs-create-tween';
</script>

README

RxJS Create Tween

Build Status

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.

Example

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');
    },
  });

Source

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;