Meet Animatable, a tiny Web Component to use WAAPI as a Component 💫
Tags: stencil, webcomponents, stenciljs, html
Published: 2019-11-27 05:43:55

[Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API) is the other way to animate any HTML element using JS instead of CSS, if [Animate.css](https://daneden.github.io/animate.css/) is familiar for you, [Animatable](https://proyecto26.github.io/animatable-component) is the sequence of the animation series you’re looking for! 🌟

```html
<animatable-component
  autoplay
  easing="ease-in-out"
  duration="800"
  delay="300"
  animation="zoomIn"
  iterations="Infinity"
  direction="alternate"
>
  <h1>Hello World</h1>
</animatable-component>
```

As you can see we’re using **Web Animations API** in a *declarative* way (Using an HTML element like any other), we can say that **Animate.css** is to CSS as **Animatable** is to JS 💅

{% codepen https://codepen.io/jdnichollsc/pen/rNNYBbe %}

If you are using [VanillaJS](http://vanilla-js.com) (No Framework Integration), you only need to import the scripts before:

{% gist https://gist.github.com/jdnichollsc/a8fc14daa04c7bd7a167afa5bbf26bdd %}

{% codepen https://codepen.io/jdnichollsc/pen/JjjgPzv %}

As we can see it’s like **Animate.css** but with superpowers because we can keep the last state (opacity, transform, etc) of a previous animation before to create another one, without adding and removing classes to the elements.

There’re default animations instead of using **keyFrames** directly [here](https://github.com/proyecto26/animatable-component/wiki/Animation-property) 👋

{% gist https://gist.github.com/jdnichollsc/404640e5550a1b46dee024d9cc5e06e3 %}

And if you want to include other amazing animations you can submit a [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) from the [repository](https://github.com/proyecto26/animatable-component/issues) or create an issue with the keyFrames of the new animation, we're always happy to be more animated! 🆒

We can set the **animation** property to `none` to clear the keyFrames of a previous animation.

Also there is a list of the most common easing functions [here](https://github.com/proyecto26/animatable-component/wiki/Easing-property) 📈

{% gist https://gist.github.com/jdnichollsc/143455723168947b7821ef7ee7466a05 %}

We can set the **easing** property to a custom function like `cubic-bezier(0.25, 0.1, 0.25, 1)`, that value is equal to `ease`.

> The Magic here is you can customize the duration, delay, number of iterations and any other configuration of Web Animations API of each animation of your elements by using attributes/properties, and we’re opened to add new cool animations because is so easy and sexy, thanks to TypeScript!

## Framework Integration

Ok, It looks great working with HTML elements, but… How can I use it [<animatable/>](https://proyecto26.github.io/animatable-component) from [Angular](https://angular.io), [React](https://reactjs.org), [Vue](https://vuejs.org), etc as another component? 🤔

This Web component was created with [StencilJS](https://stenciljs.com/), therefore integrating the component is very easy:

### Angular

- Enable Web Components from your Modules, check [here](https://github.com/proyecto26/animatable-component#including-the-custom-elements-schema).
- Import Web Components globally, check [here](https://github.com/proyecto26/animatable-component#calling-definecustomelements).
- Using the component


```html
<animatable-component autoplay [animation]="myAnimation" [duration]="300">
  <h1>Animate it</h1>
</animatable-component>
```

### React
- Import Web Components globally, check [here](https://github.com/proyecto26/animatable-component#react).
- Using the component

```html
<animatable-component autoplay animation={myAnimation} duration={300}>
  <h1>Animate it</h1>
</animatable-component>
```

### Vue
- Import Web Components globally, check [here](https://github.com/proyecto26/animatable-component#vue).
- Using the component

```html
<animatable-component autoplay v-bind:animation.prop="myAnimation" duration="300">
  <h1>Animate it</h1>
</animatable-component>
```

As you can see we have Universal Components here, yay! 👏


# Bonus: Using Higher-Order Components (HOC) from StencilJS


One of the best strategies to reuse logic from React is by using [HOCs](https://reactjs.org/docs/higher-order-components.html), in this way we can extend behaviors, reuse components and improve the maintenance of our code ✍️.

With StencilJS is also possible to use this concept working with [Functional Components](https://stenciljs.com/docs/functional-components)! 🙌

```jsx
function createAnimatableComponent (
  WrappedComponent: FunctionalComponent
) {
  return (props) => {
    const { keyFrames, options, onFinish, ...rest } = props
    return (
      <animatable-component
        keyFrames={keyFrames}
        options={options}
        onFinish={onFinish}
      >
        <WrappedComponent {...rest} />
      </animatable-component>
    )
  }
};
```

Do you want to see an example using Types? Check the utility function we have in **Animatable** [here](https://github.com/proyecto26/animatable-component/blob/master/src/hocs/index.tsx)! By using **createAnimatableComponent** HOC you can create your own components and simply wrap them with **Animatable** to share your common logic and animate multiple components! 👽

{% gist https://gist.github.com/jdnichollsc/55327c8f7ac06ee1cc28fedbd23c4eb8 %}

Check other good example [here](https://gist.github.com/jdnichollsc/cecb152ecdd41e2a3733a3dfe03f0ce3).

I hope you find this component useful for your projects, and let’s continue improving our Universal Components with StencilJS, check more resources [here](https://stenciljs.com/resources)! 😊

## Supporting 🍻

I believe in Unicorns 🦄 Support [me](http://www.paypal.me/jdnichollsc/2), if you do too.


Made with ❤️

Juan D. Nicholls