Categories

How to make an animated “Wizard” component – WotW

Welcome to the Widget of the Week series, where I take gifs or videos of awesome UI/UX components, and bring them to life with code.

This week is the turn for a progress indicator or “Wizard” component, that can help you with the on-boarding process of your app. The inspiration comes from this uimovement submission and looks like this:

Preparations

For this widget I’ll be using Vue.js for the interactions and Sass for styling.

The basic markup

As usual I like to start with the markup that I’ll be needing for the component. We will need a root div with id="app" so we can later mount our Vue app.

Inside it should be a container with the progress elements (the background, the bar and the ball), and also the cards with the steps to follow.

You’ll notice in the code bellow, that the cards have 3 states: done, active and normal, those classes will help us with the styling in the next step.

Styling

We will start to match the background color and the main container. I used the grid display property to have better control over the layout and the items, if you want to know more about it you can check this guide.
For better understanding I added inline comments clarifying key decisions:

Now we need to style the progress elements, they will be absolute positioned so they don’t get in the way of the cards. Also I will declare a couple of scss variables for the color and height of the progress elements.

Before binding that data to our HTML cards, first we need a way to generate the classes .done and .active. Let’s make a method to compare the currentStep to each card and return the corresponding class:

Notice that when the currentStep is 0 or the last step allStepsDone, we just make the circle disappear by setting its opacity to 0.

The progress bar should be working by now, but our work is not done, if we look close to the original animation it has different colors for each “done” card. Using an array with all the possible shades of color a card can get is not practical, instead I used HSL colors.

HSL stands for Hue, Saturation and Lightness. Colors in this format can be declared like this hsl(0, 100%, 50%) // red.

Let’s declare the base color at the beginning of our js:

const hslColorRed = {
h: 5,
s: 67,
l: 45
}

Now similar to the getCardClass method, we will create a getCardColor one. In there we will check first if the step is done and then depending on how close to the currentStep it is, we will add more lightness to the base color: