Add Transition Effects to a Svelte App
Tags: svelte, webdev, programming, javascript
Published: 2021-01-28 21:42:16

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


Svelte is an up and coming front end framework for developing front end web apps.

It’s simple to use and lets us create results fast.

In this article, we’ll look at how to add transition effects to a Svelte app.

### Transitions

Svelte has built-in libraries for adding transitions. We can add the `fade` function to create a fade effect.

To use it, we write the following code:

`App.svelte` :

```
<script>
  import { fade } from "svelte/transition";
  let visible = true;
</script>

<button on:click={() => visible = !visible}>Toggle</button>
{#if visible}
<p transition:fade>foo</p>
{/if}
```

In the code above, we toggle `visible` between `true` and `false` as we click the Toggle button.

Then the p element fades as it’s being toggle on and off.

Transition functions can accept parameters. For instance, we can modify the default options of the `fly` effect as follows:

`App.svelte` :

```
<script>
  import { fly } from "svelte/transition";
  let visible = true;
</script>

<button on:click={() => visible = !visible}>Toggle</button>
{#if visible}
<p transition:fly="{{ y: 200, duration: 3000 }}">foo</p>
{/if}
```

The code above moved the word `foo` up and down as we click the Toggle button. `y` indicates the distance that we move the word `foo` up and down. `duration` is the length of the transition effect.

We should therefore then see the word `foo` move up and down as we click the Toggle button.

With Svelte, we can also only add transition effects when an item is added to the DOM with the `in` directive, and animate when the item is removed from the DOM with the `out` directive.

For instance, we can write the following:

`App.svelte` :

```
<script>
  import { fade } from "svelte/transition";
  let visible = true;
</script>

<button on:click={() => visible = !visible}>Toggle</button>
{#if visible}
<p in:fade="{{ y: 200, duration: 3000 }}">foo</p>
{/if}
```

The code above only applies the `fade` effect when the p element with word `foo` is being inserted into the DOM. We should see a fade effect at that time.

Likewise, we can use the `out` directive to only add transition effect when the p element is removed from the DOM as follows:

```
<script>
  import { fade } from "svelte/transition";
  let visible = true;
</script>

<button on:click={() => visible = !visible}>Toggle</button>
{#if visible}
<p out:fade="{{ y: 200, duration: 3000 }}">foo</p>
{/if}
```

### Creating our own Transition

We can create our own transitions if we don’t want to use the built-in transitions.

For instance, we can write the following code to create an effect that spins the text and change the color as the p element is being removed from the DOM a follows:

```
<script>
  import { fade } from "svelte/transition";
  import { elasticOut } from "svelte/easing";
  let visible = true;

  const spin = (node, { duration }) => {
    return {
      duration,
      css: t => {
        const eased = elasticOut(t);

        return `
            transform: scale(${eased}) rotate(${eased * 1080}deg);
            color: hsl(
              ${~~(t * 360)},
              ${Math.min(100, 2000 - 1000 * t)}%,
              ${Math.min(50, 2000 - 500 * t)}%
            );`;
      }
    };
  };
</script>

<button on:click={() => visible = !visible}>Toggle</button>
{#if visible}
<p out:spin="{{ y: 200, duration: 3000 }}">foo</p>
{/if}
```

Add we did was return the CSS for styling the p element as the time `t` is increasing.

`elasticOut` defines our easing, which is our rate of change over time. We passed it into `transform` to change the size of the text. We also used it to change the rotation angle of the text as it fades out.

### JavaScript Animation

We can also animate text with JavaScript. For instance, we can create a typewriter effect as follows:

```
<script>
  let visible = true;

  const typewriter = (node, { speed = 50 }) => {
    const valid =
      node.childNodes.length === 1 && node.childNodes[0].nodeType === 3;

    if (!valid) {
      return;
    }

    const text = node.textContent;
    const duration = text.length * speed;

    return {
      duration,
      tick: t => {
        const i = Math.ceil(text.length * t);
        node.textContent = text.slice(0, i);
      }
    };
  };
</script>

<button on:click={() => visible = !visible}>Toggle</button>
{#if visible}
<p in:typewriter>Hello Jane. How are you?</p>
{/if}
```

In the code above, we created the typewriter effect by defining a `typewriter` function.

We progressive append the text content into the p element as time goes on, which means `t` is increasing.

Therefore, we’ll get a typewriter when we toggle the text on by clicking the Toggle button since we have:

```
<p in:typewriter>Hello Jane. How are you?</p>
```

in the markup.

### Conclusion

Svelte has built-in libraries for creating transitions and animations. It makes animation effects easy.

We just import the functions for animation and apply them with `in` , `out` , or `transition` directives.

Also, we can make our own custom animations by writing our own animation functions applying them with the same directives.