Categories
Svelte

Animating Value Changes with Svelte

Spread the love

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 create tweens to animate values in a Svelte component.

Creating Animation for Value Changes with tween

We can use the tweened function to create a value that’s animated when we change it.

For instance, we can use it to create an animated progress bar which has an easing effect as follows:

<script>
  import { tweened } from "svelte/motion";
  import { cubicOut } from "svelte/easing";

  const progress = tweened(0, {
    duration: 400,
    easing: cubicOut
  });

  const moveProgress = () => {
    $progress = 0;
    const interval = setInterval(() => {
      $progress += 0.1;
      if ($progress === 1) {
        clearInterval(interval);
      }
    }, 1500);
  };
</script>

<style>
  progress {
    display: block;
    width: 100%;
  }
</style>

<progress value={$progress}></progress>
<br>
<button on:click="{moveProgress}">
  Start
</button>

In the code above, we have the moveProgress function, which sets the $progress store’s value.

Then we update it until it gets to 1. Once it’s 1, then we clear the timer object to stop it from running.

The $progress store is created from the tweened function, which enables us to animate as the value is being changed. It has the initial value of 0 as we passed 0 into the tweened function as the first argument.

The 2nd argument has the object to specify how the animation is done. We set the duration of the animation to 400ms. Then we set the easing function to cubic out.

Cubic out means that the animation moves fast and then slowly.

All options that are available in the object we pass into the 2nd argument are:

  • delay — milliseconds before the tween starts
  • duration — either the duration of the tween in milliseconds or a (from, to) => milliseconds function allowing us to specify the tween
  • easing — a p => t function
  • interpolate — a custom (from, to) => t => value function for interpolating between arbitrary values. Svelte interpolates between numbers, dates, and identically shaped arrays and objects by default

We can pass the options to the progress.set and progress.update as the second argument to override the defaults.

The set and update methods both return a promise that resolves when the tween completes.

spring Function

We can use the spring function to create a store that has values that’s animated as they’re changed.

For instance, we can write the following code to add a spring effect to our square as we move it by hover the mouse on different location:

App.svelte :

<script>
  import { spring } from "svelte/motion";

  let coords = spring({ x: 50, y: 50 });
  let square;

  const setCoords = e => {
    coords.set({ x: e.clientX, y: e.clientY });
    square.style.top = `${$coords.y}px`;
    square.style.left = `${$coords.x}px`;
  };
</script>

<style>
  .screen {
    width: 100vw;
    height: 100vh;
  }

  .square {
    width: 20px;
    height: 20px;
    background-color: red;
    position: absolute;
  }
</style>

<div class="screen" on:mousemove="{setCoords}">
  <div class="square" bind:this={square}>
  </div>
</div>

In the code above, we bind the div with class square to the square variable.

Then we added a setCoords function to set the coords store with the x and y values of the mouse hover position.

We then used that to set the top and left values of the div with class square, which when combined with the existing styles, will move the square.

The spring function gives the square a springy effect as we move the red square around with the mouse.

If we switch between spring and writable , we’ll notice a difference in how the square moves.

Conclusion

We can create animation from store states with the tween and spring functions.

Then tween function is good for values that change less frequently and spring is good for animations of values that change more frequently.

Leave a Reply

Your email address will not be published. Required fields are marked *