Nefe James Nefe is a frontend developer who enjoys learning new things and sharing his knowledge with others.

Essential transitions and animations in Svelte

5 min read 1422

Introduction

An awesome thing about working with animations in Svelte is that you don’t need to download extra packages. Animations and transitions come built in with Svelte. This means you can add powerful and delightful interactions to applications without increasing their size. This also goes a long way to boost the speed and performance of your application.

In this article, I will explain how transitions and animations work in Svelte. I also provide some demos where we apply the knowledge we gain in practice.

Getting started

We start by installing the sveltejs package with the following code:

npx degit sveltejs/template my-svelte-project

Transitions in Svelte

Svelte provides seven transition functions: fade, blur, fly, slide, scale, draw, and crossfade. To use any of these functions, you have to import them from the svelte/transition module.

Below is a demo of the transition we will be making to an image carousel:

Gif of an image carousel in action

Let’s see how to add transitions to an image carousel. Add the code snippet below to your App.svelte file:

<script>
  import { fade, blur, fly, slide, scale } from "svelte/transition";
  import { quintOut } from "svelte/easing";

  let books = [
    //array of links to books
  ];

  setInterval(() => {
   //logic goes here
  }, 1000);
</script>
<section style="display:flex;justify-content:center">
  {#each books as book, i}
    {#if activeIndex === i}
      <img
        transition:scale={{ delay: 250, duration: 300, easing: quintOut }}
        style="position:absolute"
        src={book}
        width="500"
        height="300"
        alt=""
      />
    {/if}
  {/each}
</section>

In the code snippet above, we import the transition functions we’ll be using. We also import the quintOut easing function. Svelte provides several easing functions out of the box.

To add transitions to Svelte, we make use of the transition directive. We pass in the transition directive to the img element.

Transition functions can accept parameters. We define the delay, duration, and easing for the transition by passing in a configuration object.

We made a custom demo for .
No really. Click here to check it out.

In and out transitions

When working with transitions in Svelte, we can define separate transition functions for the in and out transitions of the elements. The gif below is the demo of in and out transitions we will be making:

Gif of transition function toggled by a checkbox

Let’s implement in and out transitions in another demo. Copy the code below into your App.svelte file:

<script>
  import { fade, scale } from "svelte/transition";
  let show = false;
</script>

<label>
  Toggle
  <input type="checkbox" bind:checked={show} />
</label>
<hr />
{#if show}
  <h1 in:scale out:fade>My name is Nefe James</h1>
{/if}

We switch out the transition directive for in and out. Like the transition directive, parameters can also be passed into in and out.

Custom transitions

You may want to define custom transitions, and you can do that in Svelte. Under the hood, each transition is a function that gets a node and a parameter.

The gif below shows the custom transition we will create:

Gif of custom transition of a box shrinking and growing at a button press

Let’s see how to create custom transitions in Svelte. Copy the code below into your App.svelte file:

<script>
  import { elasticInOut } from "svelte/easing";
  let isActive = true;
  const customTransition = () => {
    return {
      css: (t) => {
        return `
        transform: scale(${t});
        `;
      },
      easing: elasticInOut,
      duration: 2000,
    };
  };
</script>

<main>
  <button on:click={() => (isActive = !isActive)}>
    {#if isActive} Hide Box {:else} Show Box{/if}
  </button>
  {#if isActive}
    <div class="box" transition:customTransition />
  {/if}
</main>

We defined a function called customTransition. This function returns a css property, easing, and duration. The css property is a function with t as its parameter.

t represents the transition frames available from 0 to 1. We use the value of t to set the scale of the object. Then we pass customTransition to the box.

Animations in Svelte

Svelte provides a flip animation function that can be accessed from the svelte/animate module. The animate directive is used when you want to add animations to a list of items that are being reordered. The gif below shows how flip animations work in animating a list of items:

Gif of flip animation in which numbers are rearranged at button press

Let’s see how to make flip animations. Copy the code below into your App.svelte file to follow along:

<script>
  import { flip } from "svelte/animate";

  let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];

  const shuffle = () => {
    numbers = numbers.sort(() => 0.5 - Math.random());
  };
</script>
<main>
  <button on:click={shuffle}>shuffle numbers</button>
  <div>
    {#each numbers as number (number)}
      <p animate:flip>{number}</p>
    {/each}
  </div>
</main>

In the snippet above, we are shuffling an array of numbers from 1-9. To animate the shuffling, we start by importing flip from svelte/animate.

We pass flip to the p tag through the animate directive. Svelte tracks and animates the change in position of the numbers whenever the button is clicked.

Controlling element motions in Svelte

The svelte/motion module exports two functions, tweened and spring, for creating writable stores whose values change over time after set and update, rather than immediately.

The demo below shows how the tweened animation looks in action:

Gif of tweened animation in which an image grows larger at button press

Let’s set up a demo to see how motions work. To follow along, copy the code below into your App.svelte file:

<script>
  import { tweened } from "svelte/motion";
  import { quartInOut } from "svelte/easing";
  let src = "./pear.jpg";
  const width = tweened(100, {
    duration: 2000,
    easing: quartInOut
  });
  function handleClick() {
    width.set(150);
  }
</script>

<button on:click={handleClick}>Animate</button>
<br />
<img {src} width={$width} alt="" />

We import the tweened motion function from svelte/motion, along with quartInOut easing function from svelte/easing.

Tweened allows us to generate intermediate frames in an animated sequence to give the appearance of smooth movement. Tweened accepts an initial value as its first argument and a configuration object as the second. We define the duration and easing for the tweened motion.

We set the initial width of the image to be 100px. In the handleClick function, we update the width to 150px.

Then, we pass handleClick to the button using Svelte’s on directive.

Now that we know how tweened motions work, what about spring motions?

The demo below shows how the spring animation looks when applied to an element:

Gif of spring animation of a beating heart

Copy the code below into your App.svelte file:

<script>
  import { spring } from "svelte/motion";
  let src = "./heart.jpg";
  const width = spring(100, {
    stiffness: 0.01,
    damping: 0.1
  });
  const zoomIn = setInterval(() => {
    width.set(200);
  }, 300);
  const zoomOut = setInterval(() => {
    width.set(100);
  }, 600);
</script>

<img {src} alt="" width={$width} />

Spring works similarly to tweened, although its configuration object accepts stiffness and damping properties. Instead of running this animation when a button is clicked, we use the setInterval function to change the width of the image at different intervals. This gives us the appearance of a beating heart.

Transitions and animations in SvelteKit

Transitions and animations work the same way in SvelteKit as in Svelte. Let’s set up an animation in SvelteKit.

The demo below shows how tweened transition looks in Sveltekit. Note that there is no difference in implementation or appearance:

Gif of tweened animation in sveltekit, in which a button press changes the percentage of a loading bar

Copy the code below into your App.svelte file to follow along:

<script>
  import { tweened } from "svelte/motion";
 import { cubicOut } from "svelte/easing";
 const progress = tweened(0, {
   duration: 4000,
   easing: cubicOut,
 });
</script>

  <h1>Click a button and watch the SvelteKit transition magic happen 🌟</h1>

<progress value={$progress} />
<div class="buttons">
  <button on:click={() => progress.set(0)}> 0% </button>
  <button on:click={() => progress.set(0.25)}> 25% </button>
  <button on:click={() => progress.set(0.5)}> 50% </button>
  <button on:click={() => progress.set(0.75)}> 75% </button>    
  <button on:click={() => progress.set(1)}> 100% </button>
</div>

Like we did in Svelte, we import tweened from svelte/motion along with an easing function. We define a progress variable and set the value of the progress bar to that variable.

Whenever any of the buttons are clicked, the value of the progress bar updates, and we see a beautiful transition take place from one value to the other.

Conclusion

Adding subtle animations and transition effects is a great way to keep visitors engaged with your content. When done correctly, animations make your website or app more compelling, and they can help drive user engagement.

Transitions and animations in Svelte are awesome. The Svelte team did a great job in packaging built-in animations, transitions, motions, and easings into the library.

: Full visibility into your web apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

.
Nefe James Nefe is a frontend developer who enjoys learning new things and sharing his knowledge with others.

Leave a Reply