CSS3 Animation Goodness

Disclaimer: I’m sure that there are more efficient, cross browser ways of doing this, my intent is to simply share what worked for me…

One of the great things about CSS3 is that it allows you to create dynamic transformations like moves, rotations or even 3D flips all via pure CSS (and via Javascript as an extension). This was a real eye-opener for me, as it was a really simple way to add some life to an app that’s basically a series of web pages, and make it feel more like a ‘real’ app.

For detailed information on CSS3 here are a couple of excellent resources, again I’ll just be describing the shortcuts I used to get done what I needed to:

So here’s the way that I explain to myself how it works, there are 2 important parts to animating an element (say a <div>):

  1. First define a transition – you can do this globally by attaching it to a class declaration that all of the elements share, or you can do it individually using the ID selector, the basic syntax is:
    -webkit-transition: all 500ms ease-out;
    This sets the transition for all types of transitions (i.e. opacity, rotation, translations etc) to last 500ms, and they ease out (basically they slow down slightly at the end of the transition). Check the Apple CSS3 Guide for more comprehensive details
  2. With the transition defined you can add a second line to the CSS class which defines the action (the transformation) for example:
    -webkit-transform: translate(-800px,0px);
    In  this example, the element will move 800 pixels to the left of it’s original position.

    You can also combine translations in one line for example:
    -webkit-transform: translate(-800px,0px) rotateZ(15deg);
    The example above will both move the element 800 pixels to the left and rotate it so that it will end up 15 degrees around the Z axis.

So that’s the basic approach, the thing I realized is that the translation is applied as soon as the code is loaded, so if you want the event to happen based on a user event, then you can either use the :hover pseudoclass which will apply the transition when the mouse is over the element, and then revert it when the mouse leaves the element, i.e.:

#moveDiv{
-webkit-transition: all 500ms ease-out;
left:800px;
}

#moveDiv:hover{
-webkit-transform: translate(-800px,0px) rotateZ(15deg);
}

Using the above, when the cursor moves over the div id=”moveDiv”, the element will move and rotate until the cursor is moved off of the space occupied by the element in it’s original position.

All this is great but what about if you want the transition to happen after a specific event, or on a user click? Well the great thing is that you can set those properties via JavaScript, and therefore control when the transition occur. Below is a simple example of animating the div id=”moveDiv” as in the example above, but having it occur when a mouseClick event calls a function moveIT();

function moveIT(){
var theDiv=document.getElementById(‘theMoveCard’);
theDiv.style[‘-webkit-transform’] = ‘translate(0px,-1000px) rotateZ(2deg)’;
}

So you can see by the same basic approach you can programatically vary things like the speed with which the transition happens, or the amount it’s translated, or the amount it’s rotated etc.

In terms of application to the game, I had 2 problems for the main screen: 1) I noticed that the background image to just long enough to load such that once it was loaded the buttons had already completed animating into their final positions and 2) it looked really boring having all 6 buttons come in at the same time, I wanted to stagger their animation but didn’t want it to be the same every time – to give some sense of newness, so what I ended up doing was:

  1. Creating a function that only starts animating the buttons in after the pageLoad() event is complete and
  2. Within the function used javascript to randomly set the speed of the individual buttons, so that every time the screen is shown they appear in a different order

Here’s the code, note that I’ve given each of the buttons a unique ID ( button1, button2 etc) , and that they all share a common CSS class that places them 800 pixels to the right of their final position. Once the page has loaded, the following function is called and the 6 buttons slide into place:

function slideQuestions(){
for(var i=1 ;i<7 ; i++){
var divName=”button”+i;
var theDiv=document.getElementById(divName);
var randomnumber=Math.floor(Math.random()*21);
var randomdecimal = randomnumber/1;
theDiv.style[‘-webkit-transition’] = ‘all .’+randomdecimal+’s ease-in-out’;
theDiv.style[‘-webkit-transform’] = ‘translate(-800px,0px)’;
}
}

Note that in this case the transformation is the same for all the buttons, it’s just the transition that gets manipulated. Basically I took the same approach for the rest of the application any time something animates in any way. Again, I’m sure there are more elegant ways to do the same thing – this is just what makes sense to me.

Next up – questions, more questions, only questions!

This entry was posted in CSS3, Design. Bookmark the permalink.