HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Animating Coloured Cogs

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
cogsanimatingcoloured

Problem

The script is for rotating 5 different coloured gears (tandwiel) on my site.

I think the code can be improved and improved performance. 5x var paper isn't that smart for speed?

Getting the current code working faster in the normal state is the primary concern, but there are two smaller issues I know of that I would appreciate help with:

  • The code works most of the time, but when changing the browser size I have a problem with the rotating left and right: 1 gear will rotate the other direction, but starts to rotate very fast and finally slows down to normal speed. The longer you let it rotate at normal speed and then change browser, the longer the gear rotates too fast. It seems to me it rotates backwards all the missing angles til it will be normal again??



  • How to stop the JavaScript when the browser size is mobile. So it won't overload for mobile. The animation should start again when changing to bigger browser size.



Those two issues are not the primary concern.

```
var w = window.innerWidth;

if (w>=960) {window.direction = -1; }
else {window.direction = 1; }

window.onresize=function(){
var w = window.innerWidth;
if (w>=960) {window.direction = -1; }
else if (w=715){window.direction = 1; }
};

window.onload = function() {
var paper = new Raphael(document.getElementById('canvas_container'), 730, 750);

var paper = new Raphael(document.getElementById('tandwiel-1'), 240, 240);
var tandwiel1 = paper.image( "tandwiel-1.png",0,0,240,240);

var paper = new Raphael(document.getElementById('tandwiel-2'), 240, 240);
var tandwiel2 = paper.image( "tandwiel-2.png",0,0,240,240);

var paper = new Raphael(document.getElementById('tandwiel-3'), 240, 240);
var tandwiel3 = paper.image( "tandwiel-3.png",0,0,240,240);

var paper = new Raphael(document.getElementById('tandwiel-4'), 240, 240);
var tandwiel4 = paper.image( "tandwiel-4.png",0,0,240,240);

var paper = new Raphael(document.getElementById('tandwiel-5'), 240, 240);
var tandwiel5 = paper.image( "tandwiel-5.png",0,

Solution

Ok, now that I have a firm grasp on what you're doing, I think I have what you're looking for. The below still applies in terms of optimizing what you posted, but I think what you want is more along the lines of the following:

fiddle

var paper = Raphael("canvas", 500, 500);

var rectangles = {
   1 : paper.rect(100,100,90,40).attr({fill: "#44ddff"}) ,
   2 : paper.rect(200,100,90,40).attr({fill: "#4488ff"}) ,
   3 : paper.rect(100,200,90,40).attr({fill: "#44ddff"}) ,
   4 : paper.rect(200,200,90,40).attr({fill: "#4488ff"})
};

function repeat() {

    var runOnce = 0;

    for (var i in rectangles) {
        rectangles[i].animate(
            {transform:'...R' + (i%2===0?'':'-') + '360'} ,
            2000 ,
            function() {

                runOnce++;

                if (runOnce==4)
                    repeat();

            });
    }
};
repeat();


It still needs some tweaks for your cogs, but I think this is a more adept to the capabilities of the Raphael framework.

Kudos on tackling Raphael at an early stage of learning. It's quite advanced, but definitely fun.

The first recommendation I will make is that you shouldn't repeatedly call "setInterval". It is a large waste of resources. Also, you are not creating multiple papers, you are overwriting the existing variable. Honestly, between that and the reuse of angle I'm somewhat confused this code is working for you at all... I certainly cant get it to run on fiddle.

var w = window.innerWidth;

if (w>=960) {window.direction = -1; }
else {window.direction = 1; }

window.onresize=function(){
var w = window.innerWidth;
if (w>=960) {window.direction = -1; }
else if (w=715){window.direction = 1; }
};

window.onload = function() {  

    var paper = new Raphael(document.getElementById('canvas_container'), 730, 750); 

    var tandwiel1 = paper.image( "tandwiel-1.png",0,0,480,240); 

    var tandwiel2 = paper.image( "tandwiel-2.png",0,0,720,240);

    var tandwiel3 = paper.image( "tandwiel-3.png",0,0,960,240);

    var tandwiel4 = paper.image( "tandwiel-4.png",0,0,1200,240);

    var tandwiel5 = paper.image( "tandwiel-5.png",0,0,1440,240);

    var angle = 0;

    setInterval( function() {

        angle += 2;        

        tandwiel1.stop().animate( { "transform": "R" + angle }, 1000, "<>" );

        tandwiel2.stop().animate( { "transform": "R" + -angle }, 1000, "<>" );

        tandwiel3.stop().animate( { "transform": "R" + angle }, 1000, "<>" );

        tandwiel4.stop().animate( { "transform": "R" + -angle }, 1000, "<>" );

        tandwiel5.stop().animate( { "transform": "R" + direction*angle }, 1000, "<>" );

    }, 150 );
}


Next I would swap out the unreliable setInterval for a recursive setTimeout. But that is not necessary for this experiment. I use setInterval plenty when whipping up little tests such as this, it's a bit easier to set up.

Additionally, have you tried using a Raphael set to perform your animation with only one animate directive? It might speed it up a bit.

UPDATE:

Upon reconsideration, I realize why it would work. Even though you are overwriting the paper variable, the object has already been added to the DOM. This is not undone when the variable is modified/removed within JavaScript. Ether way, you would want to encapsulate all of your elements on one paper if they are related/displayed-near-each-other

UPDATE:

A further consideration. What I like to do is first create the Raphael objects so that I can access them by themselves

var myObjects = {

    tandwiel1 : paper.image( "tandwiel-1.png",0,0,480,240, 

    tandwiel2 : paper.image( "tandwiel-2.png",0,0,720,240),

    tandwiel3 : paper.image( "tandwiel-3.png",0,0,960,240),

    tandwiel4 : paper.image( "tandwiel-4.png",0,0,1200,240),

    tandwiel5 : paper.image( "tandwiel-5.png",0,0,1440,240)
};


And then, if I need to animate them as a group, I create a set for easy manipulation.

var allTanwiels = paper.set(myObjects.tandwiel1 , myObjects.tandwiel2 , myObjects.tandwiel3 , myObjects.tandwiel4 , myObjects.tandwiel5)

allTanwiels.forEach(function(tanwiel) {
    tanwiel.stop().animate( { "transform": "R" + angle }, 1000, "<>" );
});

Code Snippets

var paper = Raphael("canvas", 500, 500);

var rectangles = {
   1 : paper.rect(100,100,90,40).attr({fill: "#44ddff"}) ,
   2 : paper.rect(200,100,90,40).attr({fill: "#4488ff"}) ,
   3 : paper.rect(100,200,90,40).attr({fill: "#44ddff"}) ,
   4 : paper.rect(200,200,90,40).attr({fill: "#4488ff"})
};

function repeat() {

    var runOnce = 0;

    for (var i in rectangles) {
        rectangles[i].animate(
            {transform:'...R' + (i%2===0?'':'-') + '360'} ,
            2000 ,
            function() {

                runOnce++;

                if (runOnce==4)
                    repeat();

            });
    }
};
repeat();
var w = window.innerWidth;

if (w>=960) {window.direction = -1; }
else {window.direction = 1; }

window.onresize=function(){
var w = window.innerWidth;
if (w>=960) {window.direction = -1; }
else if (w<960 && w>=715){window.direction = 1; }
};

window.onload = function() {  

    var paper = new Raphael(document.getElementById('canvas_container'), 730, 750); 

    var tandwiel1 = paper.image( "tandwiel-1.png",0,0,480,240); 

    var tandwiel2 = paper.image( "tandwiel-2.png",0,0,720,240);

    var tandwiel3 = paper.image( "tandwiel-3.png",0,0,960,240);

    var tandwiel4 = paper.image( "tandwiel-4.png",0,0,1200,240);

    var tandwiel5 = paper.image( "tandwiel-5.png",0,0,1440,240);

    var angle = 0;

    setInterval( function() {

        angle += 2;        

        tandwiel1.stop().animate( { "transform": "R" + angle }, 1000, "<>" );

        tandwiel2.stop().animate( { "transform": "R" + -angle }, 1000, "<>" );

        tandwiel3.stop().animate( { "transform": "R" + angle }, 1000, "<>" );

        tandwiel4.stop().animate( { "transform": "R" + -angle }, 1000, "<>" );

        tandwiel5.stop().animate( { "transform": "R" + direction*angle }, 1000, "<>" );

    }, 150 );
}
var myObjects = {

    tandwiel1 : paper.image( "tandwiel-1.png",0,0,480,240, 

    tandwiel2 : paper.image( "tandwiel-2.png",0,0,720,240),

    tandwiel3 : paper.image( "tandwiel-3.png",0,0,960,240),

    tandwiel4 : paper.image( "tandwiel-4.png",0,0,1200,240),

    tandwiel5 : paper.image( "tandwiel-5.png",0,0,1440,240)
};
var allTanwiels = paper.set(myObjects.tandwiel1 , myObjects.tandwiel2 , myObjects.tandwiel3 , myObjects.tandwiel4 , myObjects.tandwiel5)

allTanwiels.forEach(function(tanwiel) {
    tanwiel.stop().animate( { "transform": "R" + angle }, 1000, "<>" );
});

Context

StackExchange Code Review Q#52473, answer score: 5

Revisions (0)

No revisions yet.