I've created an intro animation to a page I'm working on using jQuery and Raphael, a javascript library. The animation works the way I'd like it to, but is oftentimes jumpy. Usually refreshing will cause it to animate much smoother than on its first page load. I'm wondering if this has anything to do with load times or if it's just the efficiency of my code.
You can see the page at: http://developer.crawford.com as well as the animation code below.
Is there any way to increase efficiency when it comes to javascript animations, or specifically with my code? Am I doing anything to cause the script to be very inefficient? Is there any good way to give the code a few seconds to load before executing to maybe make it run smoother other than simply setTimeout()?
function introAnimation() {
// creating the canvas
var paper = new Raphael(document.getElementById('mainCanvas'), '100%', '100%');
var canvasWidth = 500;
var canvasHeight = 500;
var offset = .6;
// speed of circle getting bigger
var speed1 = 1000;
// speed of circles diverging
var speed2 = 1200;
var hide = Raphael.animation({'opacity': 0});
// ellipse variable instantiation
var cRadius = 105;
var diam = cRadius*2;
// centerpoint
var cX = canvasWidth/2;
var cY = canvasHeight/2;
var circ1 = paper.ellipse(cX, cY, 10, 10);
circ1.attr({opacity: 1, stroke: '#777'});
var circRed = paper.ellipse(cX, cY, cRadius, cRadius).attr({opacity: 0, stroke: '#777'});
var circGreen = paper.ellipse(cX, cY, cRadius, cRadius).attr({opacity: 0, stroke: '#777'});
var circBlue = paper.ellipse(cX, cY, cRadius, cRadius).attr({opacity: 0, stroke: '#777'});
//red, green, blue watermarks, and logo
var redWatermark = paper.image('images/circle_red.png', cX-50, cY-50, 100, 100).attr({opacity: 0});
var greenWatermark = paper.image('images/circle_green.png', cX-50, cY, 100, 100).attr({opacity: 0});
var blueWatermark = paper.image('images/circle_blue.png', cX-50, cY, 100, 100).attr({opacity: 0});
var logoWidth = 60;
var logoHeight = 30;
var logo = paper.image('images/CMS_logo_only.png', cX-(logoWidth/2), cY*1.04, logoWidth*.95, logoHeight*.95).attr({opacity: 0});
var letterOffset = cRadius*1.2;
// circle centerpoints xR, yR: center of red; xG, yG: center of green; xB, yB: center of blue
var xR = cX; var yR = cY-cRadius*offset;
var xG = cX-cRadius*offset; var yG = cY+cRadius*offset;
var xB = cX+cRadius*offset; var yB = cY+cRadius*offset;
// insert CMS letter text
var c = paper.text(xR-Math.cos(.8)*letterOffset, yR-Math.sin(.8)*letterOffset, "c.").attr({fill: '#737373', 'font-size': '25px', 'font-family': 'IMFELLDWPicaItalic', opacity: 0});
var m = paper.text(xG+Math.cos(5*Math.PI/4)*letterOffset, yG-Math.sin(5*Math.PI/4)*letterOffset, "m.").attr({fill: '#737373', 'font-size': '25px', 'font-family': 'IMFELLDWPicaItalic', opacity: 0});
var s = paper.text(xB+Math.cos(0)*letterOffset, yB-Math.sin(0)*letterOffset, "s.").attr({fill: '#737373', 'font-size': '25px', 'font-family': 'IMFELLDWPicaItalic', opacity: 0});
// white overlap
// Three points of overlap:
var pointTopX = cX; var pointTopY = cY-(cRadius*.2);
var pointLeftX = cX-(cRadius*.365); var pointLeftY = cY+(cRadius*.33);
var pointRightX = cX+(cRadius*.365); var pointRightY = cY+(cRadius*.33);
var pathString = 'M'+pointTopX+' '+pointTopY+'A'+cRadius+' '+cRadius+' '+xG+' '+yG;
var pathString = "M"+pointTopX+" "+pointTopY+','
+"A"+cRadius+","+cRadius+",0,0,0,"+pointLeftX+","+pointLeftY+','
+"A"+cRadius+","+cRadius+",0,0,0,"+pointRightX+","+pointRightY+','
+"A"+cRadius+","+cRadius+",0,0,0,"+pointTopX+","+pointTopY;
var overlapFill = paper.path(pathString).attr({'stroke-width': 0, fill: '#fff', opacity: 0});
var overlapPath = paper.path(pathString).attr({opacity: 0});
//resize circle
circ1.animate({ 'rx': cRadius, 'ry': cRadius }, speed1, function() {
//hide it once it's done
circ1.animate({opacity: 0}, 0);
//show other circles
circRed.animate({opacity: 1}, 0);
circGreen.animate({opacity: 1}, 0);
circBlue.animate({opacity: 1}, 0);
//move other circles
circRed.animate({cy: cY-cRadius*offset, rx: cRadius, ry: cRadius}, speed2);
circGreen.animate({cx: cX-cRadius*offset, cy: cY+cRadius*offset, rx: cRadius, ry: cRadius}, speed2);
circBlue.animate({cx: cX+cRadius*offset, cy: cY+cRadius*offset, rx: cRadius, ry: cRadius}, speed2);
logo.animate({opacity: 1}, speed2);
//move to center
redWatermark.attr({width: diam, height: diam, x: imgX(cX, diam), y: imgY(cY, diam)});
greenWatermark.attr({width: diam, height: diam, x: imgX(cX, diam), y: imgY(cY, diam)});
blueWatermark.attr({width: diam, height: diam, x: imgX(cX, diam), y: imgY(cY, diam)});
//animate out
redWatermark.animate({y: imgY(cY-cRadius*offset, diam), opacity: .35}, speed2);
greenWatermark.animate({x: imgX(cX-cRadius*offset, diam), y: imgY(cY+cRadius*offset, diam), opacity: .35}, speed2);
blueWatermark.animate({x: imgX(cX+cRadius*offset, diam), y: imgY(cY+cRadius*offset, diam), opacity: .35}, speed2, function() {
logo.toFront();
c.animate({opacity: 1}, 1000); m.animate({opacity: 1}, 1000); s.animate({opacity: 1}, 1000);
overlapFill.animate({opacity: 1}, 1000); overlapPath.animate({opacity: .3}, 1000);
//nav slide in
nav();
});
});
redWatermark.hover(function() {
$('#createSub').slideDown(300);
});
redWatermark.mouseout(function() {
$('#createSub').slideUp(300);
});
greenWatermark.hover(function() {
$('#storeSub').slideDown('fast');
});
greenWatermark.mouseout(function() {
$('#storeSub').slideUp('fast');
});
blueWatermark.hover(function() {
$('#manageSub').slideDown('fast');
});
blueWatermark.mouseout(function() {
$('#manageSub').slideUp('fast');
});
}