3

I've spent a little time trying to figure this specific bit of Javascript out and why it seems to be so infuriating.

As it stands i currently have two functions. Which are shown as follows.

function startUpProc(id)
{
    var log = window.document.getElementById(id);
    log.style.transform = "rotate(0deg)";
    var i = 10;
    while ( i <= 360)
    {
        setTimeout('changeRotate(' + id + ',' + i + ')', 100);
        i = i + 10;
    }
}
function changeRotate(item, val)
{
    item.style.transform = "rotate(" + val + "deg)";
    item.style.webkitTransform = "rotate(" + val + "deg)";
    item.style.mozTransform = "rotate(" + val + "deg)";
    //alert(item.style.transform);
}

Relatively simple bit of Javascript that rotates a HTML element, in this case it's an image, this code is called with the use of a body onLoad handler as follows :

<body onLoad="startUpProc('logo');">

My intention as it stands is to have the image spin 360 degrees once which is regulated with the use of my while loop.

Where my confusion lies is in the fact that despite the timeout being set for this to take a total of 3.6 seconds to complete, it doesn't seem to even work, and there is no error being thrown, hence the alert that i placed in the function in an attempt to see what was occurring.

The alert was triggered 36 times, and visually i could see the image rotating on the page.

I found the following SO Q&A, but to no avail, the answer just wasn't applicable for the specific event i am trying to create, as the image is being rotated no matter what browser i attempt the code on, the only difference being, it only rotates when there is an alert or something in there to stop the flow of code... Rotating a div element

Unfortunately for me, all other answers i find, seem to reference the use of JQuery, which for the moment i would like to stay away from and learn to proficiently develop in JavaScript without the use of third party extensions and plugins.

Community
  • 1
  • 1
SBeynon
  • 81
  • 1
  • 9

2 Answers2

5

The issue is with the fact that the loop initiates the rotation 36 times, and after 100ms the rotation happens 36 times with i being set to "360".

Try something like this:

var STEP = 10;

function startUpProc(id)
{
    var log = window.document.getElementById(id);
    // initialized to 0 in changeRotate
    makeCircle(log, 0);
}

function makeCircle(item, targetAngle) {
    changeRotate(item, targetAngle);

    if (targetAngle < 360) {
        setTimeout(function (){
            makeCircle(item, targetAngle + STEP);
        }, 100);
    }
}

This ensures that each rotation starts after the last one has finished.

Proof that it works

STT
  • 668
  • 4
  • 12
  • 1
    It should probably also be noted that the initialization of the transform should be done through the "changeRotate" function, so that the prefixed variants are correctly applied. – Pointy Oct 13 '14 at 13:48
  • Sure, changing the answer so that it is reflected. – STT Oct 13 '14 at 13:49
  • That is marvelous! works as expected! I thank you for your time and effort, also appreciate your comments Pointy! – SBeynon Oct 13 '14 at 13:54
1

Your code initiates 36 timeouts that all fire off at once, and end up rotating the element full 360 degrees, so you might not even notice the result.

You can either fire a new timeout when the old one stops:

function changeRotate(item, val)
{
    item.style.transform = "rotate(" + val + "deg)";
    item.style.webkitTransform = "rotate(" + val + "deg)";
    item.style.mozTransform = "rotate(" + val + "deg)";
    val += 10;

    setTimeout(function () {
        changeRotate(item, i);
    }, 100);
}
changeRotate(document.getElementById('foo'), 0);

Or you can use setInterval, which will repeat the same action every specified amount of milliseconds http://www.w3schools.com/jsref/met_win_setinterval.asp

var val = 0;
function changeRotate(item)
{
    item.style.transform = "rotate(" + val + "deg)";
    item.style.webkitTransform = "rotate(" + val + "deg)";
    item.style.mozTransform = "rotate(" + val + "deg)";
    val += 10;
}
setInterval(function () {
    changeRotate(document.getElementById('foo'), 0);
}, 100);
robobot3000
  • 589
  • 2
  • 4
  • Thanks for your time and your various routes for this, unfortunately the other answer is also correct and was here first! I shall however give you a +1 :) – SBeynon Oct 13 '14 at 13:56