Animated loading indicator with isometric cubes

In general people don't like to wait. And no matter how fast we make our application there will always be something that takes time to process. But in many cases, if the user is informed, they will be more patient.
Fortunately LearningSpaces is pretty fast and there is little waiting time. But sometimes transitioning between pages can take a brief moment, ie. due to slow internet or a large request to the server.

So we can't prevent loading time but we can make it less boring. Show something awesome instead of a simple spinner or loading message. At least tickle the user's senses a bit while waiting. The first thing that came to mind was the isometric shape in our logo, consisting of a cube within a cube (or three times the letter "L" surrounding a cube). Perfect for our loading indicator:

LearningSpaces logo

In this post I will explain and demonstrate how we recreated and animated our logo, and how to use it as a loading indicator in Ember.js.

Isometric cubes

The biggest challenge is recreating our logo using HTML and CSS. There are several ways to accomplish this but we are using the CSS transform property to create the isometric faux-3D effect (sometimes refered to as 2.5D).

We need two cubes, but lets start with the first one. Create a container with three child elements for the visible cube faces (top, left and right):

<div class="cube">
  <span class="face top"></span>
  <span class="face left"></span>
  <span class="face right"></span>
</div>

Now we add the styling. Give the faces a background color and make sure they are square. Next we apply the math to create the isometric effect using the transform property. This property can take a list of transform functions but in the examples below we will only be using rotate, skew, scale and translate. Also note we use transform-origin which gives us control over the origin for the transformations. The CSS looks like this:

.cube {
  position: absolute;
  top: 100px;
  left: 100px;
}

.face {
  transform-origin: 0 0;
  position: absolute;
  height: 100px;
  width: 100px;
}

.top {
  background: #f5f5f5;
  transform:
    rotate(210deg)
      skewX(-30deg)
      scaleY(0.864));
}

.left {
  background: #ccc;
  transform:
    rotate(90deg)
      skewX(-30deg)
      scaleY(0.864));
}

.right {
  background: #e0e0e0;
  transform:
    rotate(-30deg)
      skewX(-30deg)
      scaleY(0.864));
}

Note: Don't forget to add vendor prefixes for the transform* properties if you want cross-browser support. In the demos I use SCSS and the bourbon mixin library so I don't have to worry about these prefixes.

Check out the demo. I also created a demo of an alternative technique.
Both techniques are shown in the demo below.

Now we need a second cube so we can recreate our logo. Duplicate the cube and wrap them in a container:

<div class="logo">
  <div class="cube">
    <span></span>
    <span></span>
    <span></span>
  </div>
  <div class="cube">
    <span></span>
    <span></span>
    <span></span>
  </div>
</div>

Rotate the second cube 180 degrees and scale it to half its size:

.cube:nth-child(2) {
  transform: rotate(180deg) scale(0.5);
}

Thats about it, see the result below. I also added some extra styling to render the cube as a wireframe like we have in our logo.

Animation please

To make the loading indicator complete we will add some animation. This can be done fairly easily with CSS by using @keyframes and animation. The @keyframes rule gives us control over the intermediate steps in an animation by defining keyframes (or waypoints). Each keyframe describes how the animated element should render at a given time during the animation sequence. The animation property lets you configure the timing and duration of the animation, as well as other details of how the animation sequence should progress.

For our loading indicator we want the cubes faces to shift between 3 colors by animating the background color. To do this we create an animation named "color-shift" and add 4 keyframes: start, finish and 2 in between:

@keyframes color-shift {
  0%, 100% {
    background: #ccc;
  }
  33% {
    background: #e0e0e0;
  }
  66% {
    background: #f5f5f5;
  }
}

Now we can apply the animation to the cubes' faces. We configure the animation by setting its name (color-shift), duration (1.2s) and iteration count (infinite). But we don't want the cube's faces to get the same color on each keyframe. So we use animation-delay on the 2nd and 3rd face to delay the animation for these elements:

.cube span {
  animation: color-shift 1.2s infinite;
}
.cube span:nth-child(2) {
  animation-delay: -0.8s;
}
.cube span:nth-child(3) {
  animation-delay: -0.4s;
}

Note: Don't forget to add vendor prefixes for @keyframes and animation* if you want cross-browser support.

Like the animations but think all the isometric projection math is too much fuzz? Don't worry, you can create the same effect with inline SVG. In fact, we are now using SVG for our loading indicator in LearningSpaces.

The demo below shows the HTML and the SVG aproach, both powered by the same CSS animation! The only difference with SVG is we have to animate the path's "fill" attribute instead of background color.

Loading template in Ember.js

The only thing left to do was getting our loading indicator to show up between page transitions in Ember.js. Fortunately Ember provides loading substates that allows you to do just that. Basicly the only thing we had to do is create a top-level template called loading and Ember takes care of the rest:

<script type="text/x-handlebars" data-template-name="loading">
  <h1>Loading ...</h1>
</script>

It's as simple as that!

But like I said as the beginning of this post LearningSpaces is pretty fast, so we hardly get to see our loading indicator. Hugo wrote in his post:

we find ourselves in the awkward position of complaining that our application isn't slow enough…

If you have any questions, contact us on twitter!

Meer artikelen

  1. De video van ons 30-jarig jubileumfeest

    De video van ons 30-jarig jubileumfeest

    Ons 30-jarig jubileumfeestje was een groot succes. Gelukkig kunnen we daar nog even van nagenieten. BEMedia heeft de avond vastgelegd op foto en video. Een mooie herinnering aan een bijzonder feest. En dat wilden we natuurlijk graag met jullie delen... Lees verder
  2. Sociaal leren tijdens de lunchpauze

    Sociaal leren tijdens de lunchpauze

    De lunchpauze is het moment om je werk te onderbreken zodat je er ’s middags weer vol tegenaan kunt. Maar als je stopt met werken, betekent dat dan ook dat je stopt met het genereren van ideeën? Natuurlijk niet! Koffie- en lunchpauzes zorgen voor... Lees verder
  3. Leren op microniveau: de toekomst

    Leren op microniveau: de toekomst

    Notendop-kennis. Ooit van gehoord? Heel kort gezegd is het het microdoseren van dagelijkse kennis. Hoewel microleren geen nieuw begrip is, vinden steeds meer mensen (waaronder ikzelf) het erg belangrijk. Informatiestroom Zie je wat er gebeurt? ... Lees verder
  4. De geschiedenis van onze stadsvilla

    De geschiedenis van onze stadsvilla

    Dit jaar bestaat Defacto dertig jaar. Daarom maakte Beno Hofman, het geheugen van Groningen, ​een filmpje over de geschiedenis van ons pand. De stadsvilla werd gebouwd in 1882 en is sinds 1999 in het bezit van Defacto directeur Hans Veeger. Over de... Lees verder
  5. Ken je potentie: de kenniswerker

    Ken je potentie: de kenniswerker

    Heb je ooit een kenniswerker ontmoet? Ze zijn meestal te vinden in het hart van je organisatie. Kijk maar om je heen, al je collega's zijn kenniswerkers. Het neemt vele vormen aan. Je ziet het terug in hun bereidheid en motivatie, ideeën, ervaringen... Lees verder