Why oh why is this so slow? I have made an isometric grid of cubes with css3 that bobs up and down on mouseover. It works great on Firefox with a grid size less than about 12 and with Chrome works pretty good under about 18. I have a decent video card and CPU and the thing that is bugging me is why it is so slow to animate just one cube's animations if I make sure I only mouseover one cube. Does my JavaScript need optimisation or is this just to be expected from the current implementation of browser CSS3 and JavaScript engines? Full test case below includes slider to change grid size on the fly, can either download for yourself or visit this jsfiddle version graciously provided by Doug.
<html>
<head>
<style type="text/css">
body
{
background: black;
}
.cube
{
position: relative;
}
.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: absolute;
left: 19.5px;
border: 1px solid black;
}
.topFace div
{
width: 19px;
height: 19px;
border: 1px solid black;
-webkit-transform: skew(0deg, -30deg) scale(1, 1.16);
-moz-transform: skew(0deg, -30deg) scale(1, 1.16);
-o-transform: skew(0deg, -30deg) scale(1, 1.16);
}
.topFace
{
position: absolute;
left: 10.25px;
top: -16.5px;
-webkit-transform: rotate(60deg);
-moz-transform: rotate(60deg);
-o-transform: rotate(60deg);
}
#slider
{
width: 200px;
margin: 0 auto;
}
</style>
<link type="text/css" rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script type="text/javascript">
function refreshCubes()
{
$('.box').empty();
var x = $("#slider").slider("value");
var initialTop = 50;
var initialLeft = 450;
for(var i = 1; i < x; i++)
{
for(var j = 1; j < x; j++)
{
var cube = $('<div class="cube"><div class="topFace"><div></div></div><div class="leftFace"></div><div class="rightFace"></div></div>');
cube.css(
{
left : initialLeft + (20 * i) + (-19 * j) + 'px',
top : initialTop + (11 * i) + (11 * j) + 'px'
});
cube.find('.topFace div').css('background', 'rgb(100,' + Math.ceil(255 - 16 * i) + ',' + Math.ceil(255 - 16 * j) + ')');
cube.find('.rightFace').css('background', 'rgb(35,' + Math.ceil(190 - 16 * i) + ',' + Math.ceil(190 - 16 * j) + ')');
cube.find('.leftFace').css('background', 'rgb(35,' + Math.ceil(190 - 16 * i) + ',' + Math.ceil(190 - 16 * j) + ')');
cube.children('div').css('opacity', '.9');
cube.hover(function()
{
$(this).animate({top: '-=25px'}, 400, 'easeInCubic');
}, function()
{
$(this).animate({top: '+=25px'}, 400, 'easeOutBounce');
});
$('.box').append(cube);
}
}
}
$(document).ready(function()
{
$('#slider').slider(
{
value: 9,
max: 30,
min: 2,
slide: refreshCubes,
change: refreshCubes
});
refreshCubes();
});
</script>
</head>
<body>
<div id="slider"></div>
<div class="box"></div>
</body>
</html>