Animating the New Parse About Page

Parse

One of our last projects of 2012 was to give our About page a fresh new look. The day we started working on its redesign, we knew we wanted it to really express what Parse is about, and that we wanted it to be beautiful and enjoyable to go through.

Because we received such great feedback on our previous Cloud Modules animated icon tutorial, today I’m offering you some insight on how we built the new about page top animation using some of the newest CSS3 features. We’ll be using SASS/Compass for more clarity in the code.

Let’s start by creating the HTML for this animation.

<div class="container">
  <div class="background">
    <div class="devices_gray"><div class="bg"></div></div>
    <div class="devices_colorful"><div class="bg"></div></div>
  </div>
  <div class="cloud">Parse</div>
</div>

Here we have a container div, that will essentially be used to create the dark background and position it correctly in the page. Its SCSS code is pretty simple. We just add a radial gradient that starts at the top center of the div, and a background color as a backup for non-compatible browsers. The clearfix mixin is provided by Compass and basically adds an overflow: hidden to the class.

.container{
    width: 1080px;
    height: 1080px;
    background-color: #1d1d1d;
    @include background-image(radial-gradient(center top, circle, color-stops(rgba(#686868, 0.8), rgba(#1d1d1d, 0.6) 500px)));
    @include clearfix;
}


Our container div has 2 children:

  • background is the div that will contain the moving devices. background also has 2 children that we’ll use to create 2 layers of devices: one for the gray ones, and one for the colored ones.
  • cloud will contain a transparent PNG with the shape of the cloud, a white stroke, an inner dark shadow, some glare and our Parse logo.

Now let’s dive into the interesting part: the moving devices. To prevent our page from taking very long to load, and to be able to only show the colored devices inside the Cloud shape, we’re using one of the lastest WebKit features called -webkit-mask. Unfortunately, this feature is not supported by IE or Firefox, but since we’re lucky enough to have more than 90% of our users using a WebKit browser, we’ve decided to offer them the best experience possible, while we still have a fallback image for incompatible browsers.

First of all, let’s give .devices_gray, .devices_gray .bg and .devices_colorful .bg the right positioning and size.

.devices_gray, .devices_gray .bg, .devices_colorful .bg {
    width: 2600px;
    height: 1200px;
    position: absolute;
    top: 0px;
    left: 0px;
}

Now let’s work on making our devices_gray do what we want: show gray devices. To do that, we will give the inner bg div a gray color, and use -webkit-mask-image to use our devices.png file as a mask.

.devices_gray {
    -webkit-mask-image: -webkit-gradient(linear, left 80%, left bottom, from(rgba(0,0,0,1)), to(rgba(0,0,0,0)));
    z-index: 1;

    .bg {
        left: -1500px;
        top: 0px;
        background: #252525;
        opacity: 0.4;
        -webkit-mask-image: url(/images/about/devices.png);
    }
}

Notice that we’ve used z-index to make sure devices_gray and its gray devices will end up behind the colored ones, but most importantly, that we used a -webkit-gradient that goes from dark to transparent as a mask to this div, so that our devices_gray div smoothly disappears at the bottom. This is a great trick to know about if you want to play with opacity and gradients in WebKit.

Now let’s work on the devices_colorful div.

.devices_colorful {
    -webkit-mask-image: url(/images/about/cloud_mask.png);
    width: 473px;
    height: 308px;
    position: absolute;
    left: 270px;
    top: 170px;
    z-index: 2;

    .bg {
        left: - 270px - 1500px;
        top: - 170px;
        @include background-image(linear-gradient(left, #FECC62 0%, #FECC62 5%, #FEA862 10%, #FE4762 15%, #FE47D8 20%, #E069FB 25%, #B285FB 30%, #65C1FB 35%, #FECC62 40%, #FECC62 45%, #FEA862 50%, #FE4762 55%, #FE47D8 60%, #E069FB 65%, #B285FB 70%, #65C1FB 75%, #FECC62 80%, #FECC62 85%, #FEA862 90%, #FE4762 95%, #FECC62 100%)); 
        -webkit-mask-image: url(/images/about/devices.png); 
        -webkit-mask-position: 0px 110px;
    }
}

Here we’re re-using our devices.png file as a mask on top of a rainbow gradient for the bg inner div.

For devices_colorful, we’re again using -webkit-mask-image and a transparent PNG that has exactly the shape of the Parse cloud. By doing this, and applying it to devices_colorful, we’re making sure that only the part that is contained in that cloud shape will be visible. This is how we get the effect where the colored devices are only visible inside the cloud.

What we need to do now is to animate our devices. To do that, we basically have two options:

  • Animate the masks, which is great if, for example, we want the colored devices to move on top of a fixed gradient or image, or if we want them to infinitely move in the same direction. Unfortunately, this operation is very expensive in terms of CPU usage, and will make our animation very slow.
  • Animate the two bg divs themselves horizontally. This is the method we’re going to use, since translating a div is something WebKit can easily handle.
.devices_colorful .bg, .devices_gray .bg {
    @include animation(devicesBackground, 30s, 0s, ease-in-out, infinite, alternate);
}

Here, we add to both our bg divs an animation called devicesBackground, with a 30s duration, that will start immediately, with an ease-in-out easing function, that will run infinitely and in both directions (left to right and right to left).

Since Compass doesn’t offer a good animation mixin, I’m happy to share ours with you.

@mixin animation($name: fadeIn, $duration: 1s, $delay: 0s, $function: ease, $iterations: infinite, $mode: both) {
  @each $prefix in webkit, moz, ms {
    #{""}-#{$prefix}-animation: $name $duration $delay $function $iterations $mode;
  }
  animation: $name $duration $delay $function $iterations $mode;
}

Now all we need to do is to declare this devicesBackground animation to make it do what we want.

// We only declare the WebKit keyframes here since our animation is only WebKit-compatible
@-webkit-keyframes devicesBackground {
  0% { -webkit-transform: translate3d(0px, 0px, 0); }
  100% { -webkit-transform: translate3d(1300px, 0, 0); }
}

Perfect. We now have the gray and colored devices gracefully moving together. The last thing we need to do now is to add our Cloud transparent PNG on top of it and we’ll be done.

.cloud {
    background: url(/images/about/cloud.png) no-repeat;
    width: 473px;
    height: 308px;
    position: absolute;
    left: 270px;
    top: 170px;
    z-index: 3;
    font-family: 'Raleway', 'Helvetica Neue', Helvetica, arial, sans-serif;
    font-size: 65px;
    text-align: center;
    line-height: 350px;
    color: white;
    text-shadow: rgba(black, 0.7) 0px 2px 7px;
    font-weight: 400;
}

That’s it! We now have a gorgeous CSS3 animation for the new Parse About page.

And here’s our final SCSS code.

@-webkit-keyframes devicesBackground {
  0% { -webkit-transform: translate3d(0px, 0px, 0); }
  100% { -webkit-transform: translate3d(1300px, 0, 0); }
}

$container_width: 1080px;
$container_height: 1080px;
$left_positionning : -1500px;
$cloud_left: 270px;
$cloud_top: 170px;

.container{
    width: $container_width;
    height: $container_height;
    background-color: #1d1d1d;
    @include background-image(radial-gradient(center top, circle, color-stops(rgba(#686868, 0.8), rgba(#1d1d1d, 0.6) 500px)));
    @include clearfix;

    .devices_gray, .devices_gray .bg, .devices_colorful .bg {
        width: 2600px;
        height: 1200px;
        position: absolute;
        top: 0px;
        left: 0px;
    }
    .devices_gray {
        -webkit-mask-image: -webkit-gradient(linear, left 80%, left bottom, from(rgba(0,0,0,1)), to(rgba(0,0,0,0)));
        z-index: 1;

        .bg {
            left: $left_positionning;
            top: 0px;
            background: #252525;
            opacity: 0.4;
            -webkit-mask-image: url(/images/about/devices.png);
        }
    }

    .devices_colorful {
        -webkit-mask-image: url(/images/about/cloud_mask.png);
        width: 473px;
        height: 308px;
        position: absolute;
        left: $cloud_left;
        top: $cloud_top;
        z-index: 2;

        .bg {
            left: - $cloud_left + $left_positionning;
            top: - $cloud_top;
            @include background-image(linear-gradient(left, #FECC62 0%, #FECC62 5%, #FEA862 10%, #FE4762 15%, #FE47D8 20%, #E069FB 25%, #B285FB 30%, #65C1FB 35%, #FECC62 40%, #FECC62 45%, #FEA862 50%, #FE4762 55%, #FE47D8 60%, #E069FB 65%, #B285FB 70%, #65C1FB 75%, #FECC62 80%, #FECC62 85%, #FEA862 90%, #FE4762 95%, #FECC62 100%)); 
            -webkit-mask-image: url(/images/about/devices.png);
        }
    }

    .devices_colorful .bg, .devices_gray .bg {
        @include animation(devicesBackground, 30s, 0s, ease-in-out, infinite, alternate);
    }

    .cloud {
        background: url(/images/about/cloud.png) no-repeat;
        width: 473px;
        height: 308px;
        position: absolute;
        left: $cloud_left;
        top: $cloud_top;
        z-index: 3;
        font-family: 'Raleway', 'Helvetica Neue', Helvetica, arial, sans-serif;
        font-size: 65px;
        text-align: center;
        line-height: 350px;
        color: white;
        text-shadow: rgba(black, 0.7) 0px 2px 7px;
        font-weight: 400;
    }
}
Christophe Tauziet
January 10, 2013
blog comments powered by Disqus

Comments are closed.

Archives

Categories

RSS Feed Follow us Like us