views:

63

answers:

2

Hey,

I wrote a script with two functions executed by setInterval().

One function rotateTheSun() constantly rotates an object, the other moveSlide() handles moving a sliding div onclick.

Whenever the constant function is running, the div slide very slow.

Is it a JS issue, or did I just wrote a bad script (as usual)?

source:

window.onload = initAll;

function initAll(){
    slideDivs = document.getElementsByClassName("slide");
    slideLinks = document.getElementsByClassName("slide-link");
    isMoving = false;
    curSlideState = 2;
    desSlideState = "";
    transformDeg = 0;

    for(var i=0; i < slideDivs.length; i++){
        slideDivs[i].style.left = i*100 + "px";
    }

    for(var i=0; i < slideLinks.length; i++){
        slideLinks[i].onclick = moveSlide;
    }

    rotatingSun = document.getElementById("rotating-sun");
    rotatingSun.style.MozTransform = "rotate(" + transformDeg + "deg)";
    rotatingSun.style.WebkitTransform = "rotate(" + transformDeg + "deg)";
    rotatingSun.style.OTransform = "rotate(" + transformDeg + "deg)";
    rotatingSun.style.transform = "rotate(" + transformDeg + "deg)";

    sunTimer = setInterval(rotateTheSun, 33);
}
function moveSlide(){
    elementToMove = this.parentNode.parentNode;

    if(elementToMove.tagName == "DIV" && isMoving == false){
        for(var i=0; i < slideDivs.length; i++){
            if(elementToMove == slideDivs[i]){
                desSlideState = i;
            }
        }

        moveAction = (curSlideState - desSlideState);
        if(moveAction == 0){
            return false;
        }
        if(moveAction > 0){
            moveDirection = 1;
        }
        else{
            moveDirection = -1;
        }

        switch (moveAction){
            case 0:
                return false;
                break;
            case +2:
                divToMove1 = slideDivs[1];
                divToMove2 = slideDivs[2];
                break;
            case -2:
                divToMove1 = slideDivs[2];
                divToMove2 = slideDivs[1];
                break;
            case +1:
                if(curSlideState == 2){
                    divToMove1 = slideDivs[2];
                    divToMove2 = "";
                }
                else{
                    divToMove1 = slideDivs[1];
                    divToMove2 = "";
                }
                break;
            case -1:
                if(curSlideState == 1){
                    divToMove1 = slideDivs[2];
                    divToMove2 = "";
                }
                else{
                    divToMove1 = slideDivs[1];
                    divToMove2 = "";
                }
                break;
            }
        }
        else{
            return false;
        }

        moveCounter = 0;
        isMoving = true;
        timeMove();
        return false;
    }

function timeMove(){
    slideTimer = setInterval("executeMove()", 5);
}
function executeMove(){
    curLeft1 = parseFloat(divToMove1.style.left);
    if(divToMove2){
        curLeft2 = parseFloat(divToMove2.style.left);
    }

    divToMove1.style.left = curLeft1 + 10*moveDirection + "px";
    if(divToMove2){
        divToMove2.style.left = curLeft2 + 10*moveDirection + "px";
    }

    moveCounter += 1;

    if(moveCounter == 66){
        clearInterval(slideTimer);
        curSlideState = desSlideState;
        isMoving = false;
    }
}

function rotateTheSun(){
    transformDeg += 0.1;
    if(transformDeg > 360){
        transformDeg = 0;
    }
    rotatingSun.style.MozTransform = "rotate(" + transformDeg + "deg)";
    rotatingSun.style.WebkitTransform = "rotate(" + transformDeg + "deg)";
    rotatingSun.style.OTransform = "rotate(" + transformDeg + "deg)";
    rotatingSun.style.transform = "rotate(" + transformDeg + "deg)";
}
+1  A: 

You should definitely set a higher timeout value for setInterval(). 2.5 means 400 iterations per second! I recommend a value of 16 milliseconds. This will give you ~ 60 steps per second. Even with a step every 33 milliseconds, you will get a constant smooth rate at ~ 30 steps per second. The same applies to your second interval at 5. This is too low as well.

elusive
Thanks, I've done that, but the slide is still buggy.
Dean
you can try to set it even lower, depending on the smoothness needed for your animation. jQuery combines all animations in a single interval, as far as i know. You should consider to do it like that, although it can be quite difficult.
elusive
It combines all animations, even if u wrote them separately?
Dean
Thats right. I do not know exactly how they implemented it, but you need to queue transitions, etc. and apply them all in one go.
elusive
+1  A: 

Javascript only has one thread, so even though both functions might be setup to execute asynchronously, only one can execute at a single time. See How JavaScript Timers Work for more detail.

The time that you are setting is really small as well. Remember, setInterval and setTimeout take a millisecond parameter, 2.5 milliseconds is probably not even recognizable. Perhaps you meant 250.

Also, as a side note, you shouldn't pass strings to setInterval and setTimeout. Instead, pass the function itself

setInterval("rotateTheSun()", 2.5); ---> setInterval(rotateTheSun, 250);

Justin Johnson
I changed the time interval to 33, and passed a function itself istead of a string.
Dean
Uhm, 250 ms ≠ 2.5 s
Marcel Korpel
What the hell.....fixed
Justin Johnson
Implemented the animation with flash instead, simple SWF files take little space. But flash and JavaScript together pretty much kill the browser, it results in the same slow effect. So until i find a solution I gave up on "rotating the sun" ;)
Dean