0.2.1 • Published 8 years ago

rotoscope v0.2.1

Weekly downloads
2
License
MIT
Repository
github
Last release
8 years ago

Rotoscope

A library designed to make parallax effortless and enjoyable!

Join the community on Slack!

Slack Status

Installation

npm install rotoscope

Build and run

$ npm run build
$ npm start

Examples

http://codepen.io/turissinitechnologies/full/wGwzvm/

Why Rotoscope?

Parallax is an awesome effect that can give your website and web app that surprise and delight that users will love you for. While parallax is awesome, it is not trivial to implement beyond simple translates. For complex animations, a more robust tool is needed and that tool is Rotoscope.

Rotoscope itself is a super lightweight parallax library that works on the idea of timeline-based animations. This library specializes only in parallax and is 100% dependency free. It is also compatible with existing javascript animation frameworks like Greensock.

To make parallax drawing as performant as possible, rotoscope implements a two part render cycle: Updating and then Drawing. Separating the render cycle into updating and drawing allows your animations to becomes very complex without taking a performance hit. Your users will love the results!

Rotoscope is also based on timelines, which allow you to treat complex animations as a single unit. This will change the way you think about animation and also promote animations that are DRY, testable and really, really fun to show off.

If you are building complex animations or parallax effects, rotoscope will becomes an indispensible tool.

Features

  • Timeline based animations in your parallax
  • High performance rendering
  • Very flexible Clip interface that separates update and drawing
  • Immutable API
  • Promotes DRY parallax animations
  • Supports animation chaining in parallax
  • Compatible with most existing animation libraries.
  • Video parallax

Hello World example

To begin our parallax, we start by creating a rotoscope instance. The rotoscope object is what enables us to have super performant parallax. All methods on this object are chainable and immutable. This means that when any of the methods below are called, you are returned a different rotoscope instance. This prevents unintended side effects from creeping into other, unrelated parts of your code.

We should start by importing our createRotoscope function to create a rotoscope instance with a scroll target. A scroll target is any element that will emit scroll events. In most cases, this will probably be the window:

  import { createRotoscope } from 'rotoscope';

  const rotoscope = createRotoscope(window);

After we create a rotoscope object, we should define its bounds. bounds simply describe when scroll events should effect parallax. In the example below, we should see animation updates between scroll positions 50 and 150.

  const rotoscopeWithBounds = rotoscope.bounds({
    start: 50,
    duration: 100
  });

We should now add some animations. By default, rotoscope instances are created with a single root timeline that encompasses the entire animation. This timeline is the argument in the animation factory example below. We first create a greenBallClip, which is a custom clip function that takes time as an argument:

const rotoscopeWithAnimations = rotoscopeWithBounds.animate(function (timeline) {
  const greenBallClip = function (time) {
      var dist = 400;
      var y = -time * dist;
      var translate = 'scale3d(' + time + ', ' + time + ', 1)';

      return function () {
          greenBall.style.transform = translate;
      };
  };

  return timeline.appendChild(greenBallClip, {
    start: 0,
    duration: 100
  });

})

We can then start listening to scroll events and begin parallaxing

  rotoscopeWithAnimations.start();

Clip

In the animation factory above, we create a Clip function and append it to the timeline. Clip functions are what drives the animation and are broken down into two parts: Update and Draw. The first part, Update, is the calculation that happens before Draw. This part of the process takes a single argument, time, that is always a value between 0 and 1. You an think of time as percent.

The Update function should take the time and calculate what the next frame will look like. It should return a function that will actually draw that frame. This is a core concept in rotoscope and enables powerful and performant animations.

In the following example, we create a clip that moves an element, greenBall, anywhere between 0 and 400 pixels:

const greenBallClip = function (time) {
      var dist = 400;
      var y = time * dist;
      var translate = 'translate3d(' + y + 'px, 0, 0)';

      return function () {
          greenBall.style.transform = translate;
      };
  };

Timeline

Timelines allow us to compose animations together to truly make something special. They behave like trees (Like the DOM) and have children, which are clip functions and other timelines. They have an immutable API so appending a child will return a completely new timeline instance.

Adding our greenBallClip to a timeline:

const myTimeline = createTimeline();

myTimeline.appendChild(greenBallClip, {
  offset: 0,
  duration: 10,
  fill: 'both'
});

You can also 'glue' two clip functions together on a timeline. Say, for instance, that you wanted a red ball to move after the green ball was done. You could manually define an offset for the redball relative to the green ball, but that would be fragile. You can instead use the chainChild method on timeline to chain clip functions. This method takes three arguments: a clip function that already exists on the timeline. Another clip argument that will be chained to the end of the first argument. An offset object that defines time offsets -relative- to the first clip:

myTimeline.appendChild(greenBallClip, redBallClip, {
 offset: 0,
 duration: 10
});

In addition to offset, duration, you should also specify fill mode when appending a clip to a timeline. fill describes what happens when the timeline time is out of bounds beyond the offset and duration. It has 4 values:

  • none - Nothing happens, clip is skipped entirely.
  • backwards - When time is before clip, clip should be updated with time 0
  • forwards - When time is after clip, clip should be updated with time 1
  • both - Default. Clip will always be updated regardless of the time
0.2.1

8 years ago

0.2.0

8 years ago

0.1.2

8 years ago

0.1.1

8 years ago

0.1.0

8 years ago