Russell Strauss
Russell Strauss

Reputation: 1200

Coding jquery animations efficiently

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');
});

}

Upvotes: 2

Views: 627

Answers (3)

Diodeus - James MacFarlane
Diodeus - James MacFarlane

Reputation: 114437

Replace repeated calculations with the result:

Variations of cY-cRadius*offset appears often, so calculate it ahead of time.

Upvotes: 1

SeanCannon
SeanCannon

Reputation: 78046

Your PNG's are 400+k http://developer.crawford.com/images/circle_blue.png

You're forcing users to download over a meg of image data while trying to animate it at the same time. This will not be smooth for most visitors. I'd recommend either compressing/shrinking your images, or preloading them.

Upvotes: 6

Travis J
Travis J

Reputation: 82337

It looks jumpy to me too. Have you considered pre-caching your images before you call any of the animation?

Upvotes: 0

Related Questions