Анимация вращения Javascript

Я застрял в точке. Есть 10 прямых линий (изображение в формате png). Я хочу, чтобы после того, как первая линия повернулась на 40 градусов, вторая линия должна начать вращаться, а затем третья, четвертая, пятая и т. Д.!!!

код:

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

4 ответа

Решение

Есть несколько шагов, чтобы решить вашу проблему:

Идентификатор в HTML не может начинаться с цифры, поэтому переименуйте их в "hair1", "hair2" и т. Д.

Основная проблема заключается в том, что из-за setInterval к ​​моменту запуска функции i не будет i что ты ожидал. Это из-за переменной области. Вы можете обойти это с помощью анонимной функции.

Объединение обоих вышеперечисленных дает этот код:

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

Я также рекомендовал бы поместить стили в таблицу стилей, а затем применить их с помощью класса:

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

Наконец, чтобы элементы вращались подряд, а не все вместе, необходимо умножить интервал на значение i, Я думаю, что вы, вероятно, хотите использовать setTimeout, а не setInterval (setInterval будет продолжать работать снова и снова).

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

Я собрал демо здесь

Вы сталкиваетесь с классической проблемой объема / закрытия / ссылки, с которой сталкиваются большинство людей при использовании анонимных функций. Я ответил на этот вопрос некоторое время назад и предоставил тонны информации о том, что на самом деле происходит (необращайте внимания на первый абзац моего ответа, хотя остальная часть ответа применима). Между тем, ответ на вашу проблему:

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

Имейте в виду, что вы устанавливаете интервалы: обратный вызов будет вызываться каждые 100 мс, пока окно браузера остается открытым.
Вы нигде не храните идентификатор интервала, поэтому я бы либо использовал setTimeout или создать (предпочтительно неглобальный) массив идентификаторов, чтобы вы могли сделать clearInterval(intervalID[x]); когда вам нужно.

Я бы сделал это так в современных браузерах, разделяя CSS и JS с помощью класса. Это мой собственный пример, основанный на ваших требованиях, с использованием общего класса box и современные инструменты и шаблоны:

Вот HMTL, я использую div только потому, что вы можете использовать изображения или любой другой элемент:

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

Держите CSS отдельно, вам просто нужно согласовать скорость перехода с задержкой:

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

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

И 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);

Вот небольшая демонстрация: http://jsbin.com/ofiral/1/edit

Не идеальное решение, но то, с чего можно начать.

Определите анимацию CSS3 и назначьте ее с помощью 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();

настроить setInterval Дили и animation-duration чтобы получить желаемый результат.

демоверсия webkit: http://jsfiddle.net/NQJJp/5/

Другие вопросы по тегам