# Optimo Animator

Optimo animator is a lightweight Javascript animation library. The main goal of this project is to provide a set of classes to implement temporal animations in the browser. This library tries to be as low-level as possible in the sense that it provides the bare minimum to animate any kind of objects.

## Animator class

The `Animator` class is responsible for running the animation loop and tracking time. The `Animator` class takes an array of `Timelines` as arguments for the constructor. In general, a project only needs one instance of `Animator` that can handle multiple `Timelines`.

```ts
const timeline = new Timeline([
  {
    duration: 3000,
    handler: (progress) => {
      // Do something here
    },
  },
]);

const animator = new Animator([timeline]);
animator.start();
```

The animator can be `started` and `stopped` as below:

```ts
const animator = new Animator([]);

animator.start();
animator.stop();
```

Additionally it can be used to evaluate a specific frame with `computeFrameAt`:

```ts
const animator = new Animator([]);

const time = 14325; // Milliseconds
animator.computeFrameAt(time);
```

## Timeline class

The `Timeline` class is responsible for managing the steps. A timeline is basically a set of instructions that the animation should perform sequentially. The `Timeline` class takes an array of `Steps` as arguments for the constructor.

```ts
const circle = document.querySelector('.circle') as HTMLDivElement;

let sizeX = 100;
let sizeY = 100;

const sizeTimeline = new Timeline([
  {
    duration: 3000,
    onStart: () => {
      sizeX = 100;
      sizeY = 100;
      circle.style.width = `${sizeX}px`;
      circle.style.height = `${sizeY}px`;
    },
    handler: (progress) => {
      sizeX = 100 + progress * 300;
      circle.style.width = `${sizeX}px`;
    },
  },
  {
    duration: 4000,
    handler: (progress) => {
      sizeY = 100 + progress * 300;
      circle.style.height = `${sizeY}px`;
    },
  },
  {
    duration: 2000,
    handler: (progress) => {
      sizeX = 400 - progress * 300;
      sizeY = 400 - progress * 300;
      circle.style.width = `${sizeX}px`;
      circle.style.height = `${sizeY}px`;
    },
  },
]);
```

## Step class

The `Step` class encapsulates the logic to be evaluated during an animation step. A step has a `duration` and a `handler` method which receives the current progress (number from 0 to 1) used to retrieve the stage the step is in. Each step is evaluated after the other and the `handler` method is evaluated for the duration of the step.

Additional methods can be defined in a step such as `onStart` and `onEnd`. `onStart` is executed each time the step is evaluated for the first time in a loop and `onEnd` when the step is evaluated for the last time in a loop.

```ts
{
  duration: 4000,
  onStart: () => {
    // Do something when the step is evaluated for the first time in the loop
  },
  onEnd: () => {
    // Do something when the step is evaluated for the last time in the loop
  },
  handler: (progress) => {
    // Do something during the whole step duration
    // `progress` goes from 0 to 1.
  },
},
```