"3D" Elevating Cubes

Create the cubes with Canvas and see how performance fares.

by Joe Pea

HTML

<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css">
<div id="slider"></div>
<div class="box"></div>

CSS

.hidden {
     display:none;
      visibility: hidden;  
}
 .box {
     overflow: visible;   
}
body
{
    background: black;
}

.cube
{
    position: relative;
    /*USING translate3d(0,0,0) TRIGGERS HARDWARE ACCELERATION 
    FOR CSS3 TRANSFORMATIONS ON THE TARGETTED ELEMENTS*/
    -webkit-transform: translate3d(0,0,0);
    -o-transform: translate3d(0,0,0);
    -moz-transform: translate3d(0,0,0);
}

/*THE TWO NEXT CLASSES AREN'T BEING USED.
INSTEAD I DECIDED TO APPLY THE CSS WITH jQuery
BECAUSE FOR SOME REASON TOGGLING THESE CLASSES CREATES
A WEIRD BUG WHERE THE CLASSES DON"T GET TOGGLED BEFORE
THE ANIMATIONS FIRE*/
.raise {
    /*THE ANIMATIONS ARE NOW CSS3 ANIMATIONS INSTEAD OF JAVASCRIPT*/
    -webkit-transition: all 400ms ease-in-out;
    -o-transition: all 400ms ease-in-out;
    -moz-transition: all 400ms ease-in-out;
}
.lower {
    /*WE CREATE THE BOUNCE EFFECT WHEN THE CUBES LOWER WITH THE
    cubic-bezier() FUNCTION. IN THIS CASE THE cubic-bezier()
    FUNCTION CREATES A SMALL BOUNCE EFFECT WHEN LOWERING
    YOU'D HAVE TO USE A SECOND ANIMATION TO CREATE THE DOUBLE BOUNCE
    EFFECT LIKE YOU HAD WITH THE jQuery easeOutBounce ANIMATION*/
    -webkit-transition: all 400ms cubic-bezier(0, 0.35, .5, 1.6);
    -o-transition: all 400ms cubic-bezier(0, 0.35, .5, 1.6);
    -moz-transition: all 400ms cubic-bezier(0, 0.35, .5, 1.6);
}


.cube .rightFace, .cube .leftFace
{
    height: 25px; width: 10px; padding: 5px;
}

.leftFace
{
    position: absolute;

    -webkit-transform: skew(0deg, 30deg);
    -moz-transform: skew(0deg, 30deg);
    -o-transform: skew(0deg, 30deg);

    -moz-box-shadow: rgba(0, 0, 0, 0.4) 1px 2px 10px;
    -webkit-box-shadow: rgba(0, 0, 0, 0.4) 1px 2px 10px;
    -o-box-shadow: rgba(0, 0, 0, 0.4) 1px 2px 10px;
    box-shadow: rgba(0, 0, 0, 0.4) 1px 2px 10px;

    border: 1px solid black;
}

.rightFace
{
    -webkit-transform: skew(0deg, -30deg);
    -moz-transform: skew(0deg, -30deg);
    -o-transform: skew(0deg, -30deg);

    position:...

JavaScript

jQuery.fx.interval = 50;

/*OPTIMIZE THIS*/
    function animation(cube) {
            if (cube.attr('data-hovering') == 'true'
             && cube.attr('data-lowered') == 'true') {
                    cube.attr('data-animating', 'true');
                    /*cube.animate(
                        {top: cube.attr('data-raisedtop')+'px'},
                        400,
                        'easeInCubic',
                        function() {
                            cube.attr('data-animating', 'false');
                            cube.attr('data-lowered', 'false');
                            cube.clearQueue();
                            animation(cube);
                        }
                    );*/
                /*TODO: use transitionend in firefox
                and OTransitionEnd in Opera*/
                cube.on('webkitTransitionEnd', function() {
                    cube.attr('data-animating', 'false');
                    cube.attr('data-lowered', 'false');
                    cube.clearQueue();
                    animation(cube);
                });
                cube.css({
                    '-webkit-transition': 'all 400ms ease-in-out',
                    '-o-transition': 'all 400ms ease-in-out',
                    '-moz-transition': 'all 400ms ease-in-out',
                    'top':cube.attr('data-raisedtop')+'px'
                });
            }
            else
            if (cube.attr('data-hovering') == 'false'
             && cube.attr('data-lowered') == 'false') {
                    cube.attr('data-animating', 'true');
                    /*cube.animate(
                        {top: cube.attr('data-initialtop')+'px'},
                        400,
                        'easeOutBounce',
                        function() {
                            cube.attr('data-animating', 'false');
                            cube.attr('data-lowered', 'true');
                            cube.clearQueue();
                        }
 ...