Question

I am stuck at a point.There are 10 straight lines(png image).What I want is after the first line rotates by 40 deg,then the second line should start its rotaion and then the third,fourth,fifth and so on!!!

code:

<div class="hair" onclick="rotate()">
    <img src="single.png" id="1" width="10" height="40">
    <img src="single.png" id="2" width="10" height="40">
    <img src="single.png" id="3" width="10" height="40">
    <img src="single.png" id="4" width="10" height="40">
    <img src="single.png" id="5" width="10" height="40">
    <img src="single.png" id="6" width="10" height="40">
    <img src="single.png" id="7" width="10" height="40">
    <img src="single.png" id="8" width="10" height="40">
    <img src="single.png" id="9" width="10" height="40">
    <img src="single.png" id="10" width="10" height="40">
</div>

Javascript:

function rotate(){
    for(var i=1;i<11;i++)
    {
        setInterval(function(){
            document.getElementById(i).style.WebkitTransitionDuration="1s";
            document.getElementById(i).style.webkitTransform = 'rotate(40deg)';
        },100)
    }
}
Was it helpful?

Solution 2

There are a couple of steps to solve your problem:

An ID in HTML cannot start with a number, so rename them to something like 'hair1', 'hair2', etc.

The main problem is that because of the setInterval, by the time the function runs, i will not be the i that you were expecting. This is because of variable scope. You can get around this with an anonymous function.

Combining both of the above gives this code:

<div class="hair" onclick="rotate()">
  <img src="single.png" id="hair1" width="10" height="40">
  <img src="single.png" id="hair2" width="10" height="40">
  <!-- etc -->
</div>

// NOTE: This is not the final code listing, see below for a final answer. 
for (var i = i; i < 11; i++) {
  (function(local_i) {
    setInterval(function () {
      // use local_i instead of i inside this function for the results you expect
      document.getElementById('hair' + local_i).style.WebkitTransitionDuration='1s';
      document.getElementById('hair' + local_i).style.webkitTransform = 'rotate(40deg)';
    }, 100);
  })(i);
}

I would also recommend putting the styles into a stylesheet, then apply them using a class:

.rotate
{
  -webkit-transform: rotate(40deg);
  -webkit-transition: -webkit-transform 1s;
}

Finally, to get the elements to rotate in a row rather than all together, you need to multiply the interval by the value of i. I think that you probably mean to use setTimeout rather than setInterval (setInterval will keep running over and over again).

function rotate(){
  for(var i=1;i<11;i++) {
    (function (local_i) {
      setTimeout(function(){
        document.getElementById('hair' + local_i).classList.add('rotate');
      }, 100 * local_i);
    })(i);
  }
}

I've put together a demo here

OTHER TIPS

You're encountering the classic scope/closure/reference problem most people run into when using anonymous functions. I've answered this question a while back, and provided tons of info on what is actually happening (Ignore the first paragraph of my answer, the rest of the answer is applicable, though). Meanwhile, the answer to your problem is:

for(var i=1;i<11;i++)
{
    setInterval((function(myI)
    {
        return function()
        {
            document.getElementById(myI).style.WebkitTransitionDuration='1s';
            document.getElementById(myI).style.webkitTransform = 'rotate(40deg)';
        };
    }(i)),100);
}

Be aware that you're setting intervals: the callback will be called every 100ms as long as the browser window remains open.
You're not storing the interval id anywhere, so I'd either use setTimeout or create a (preferably non-global) array of id's so you can do clearInterval(intervalID[x]); when you need to.

I would do it like this on modern browsers, separating CSS and JS by using a class. This is my own example based on your requirements, using a common class box and modern tools and patterns:

Here's the HMTL, I'm using divs just because, but you can use images or any other element:

<div class="container">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>

Keep the CSS separate, you just need to match the transition speed with the delay:

.box {
  width: 100px;
  height: 100px;
  margin: 40px;
  background: grey;
  -webkit-transition: -webkit-transform .3s linear;
}

.box.rotate {
  -webkit-transform: rotate(45deg);
}

And the JS:

function rotate() {
  var elements = document.querySelectorAll('.box');
  [].forEach.call(elements, function(element, i) {
    setTimeout(function(){ element.classList.add('rotate'); },i*300);
  });
}

document.querySelector('.container')
        .addEventListener('click',rotate);

Here's little demo: http://jsbin.com/ofiral/1/edit

Not a perfect solution, but something you can start with.

Define a css3 animation and assign it using javascript.

@-webkit-keyframes rotation {
    from {
        -webkit-transform: rotate(0deg);
    }
    to {
        -webkit-transform: rotate(360deg);
    }
}
.hair {
    position:relative;
}
.hair div {
    width:40px;
    height:40px;
    border-bottom: 1px solid #000;
    position:absolute;
    -webkit-animation-duration:         1s; 
    -webkit-animation-iteration-count:  infinite;
    -webkit-animation-timing-function: linear;
}

.

function rotate() {
    for (var i = 1; i < 11; i++) {
        (function (x) {
            setInterval(function () {
                document.getElementById("d" + x).style.WebkitAnimationName = "rotation";
            }, 200 * i);
        })(i);
    }
}

rotate();

adjust the setInterval dealy and animation-duration to get the desired result.

webkit demo: http://jsfiddle.net/NQJJp/5/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top