Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Создание анимации (https://javascript.ru/forum/dom-window/35301-sozdanie-animacii.html)

Tit6ka 06.02.2013 19:44

Создание анимации
 
Как через JS создать анимацию движений объектом , допустим картинкой , и чтобы анимация длилась 5 секунд?

vadim5june 06.02.2013 20:26

JQuery animation посмотрите

Deff 06.02.2013 22:47

http://jquery-docs.ru/Effects/animat...easingcallback

DjDiablo 07.02.2013 00:28

Грубый пример на коленке, это если без jquery.
Тестировал в хром, opera, ie9

Ссылка на песочницу
или запустите пример ниже.

<!DOCTYPE HTML>
<html>
  <head> </head>
  <body>

    <div id="test" style="position:absolute;left:100px;background-color:yellow;width:70px;height:70px;opacity:0.1;">привет</div>

    <div id="test2" style="position:absolute;left:500px;background-color:red;width:70px;height:70px;opacity:0.1;">привет</div>
    
    <script>      

      //для начала обьявим функцию которая будет выполнять анимацию
      function animate(style){                 
        var el=style["el"],
            easing=style["easing"]||"line",
            duration=style["duration"]||1000,

            //получим расчитанный стиль
            // currentStyle используется в старых ie, для поддержки старых IE этого конечно мало :)
            сomputedStyle=window.getComputedStyle?window.getComputedStyle(el, null):el.currentStyle,

            //время до которого анимацию нужно успеть выполнить
            finalTime=new Date().getTime()+duration,
            //список анимируемых свойств
            prop={},
            // единицы измерения
            ob={
               left:"px",
               right:"px",
               top:"px",
               bottom:"px",
               width:"px",
               height:"px"
            },
              
            // закон изменения параметра в зависимости от положения анимации
            // 3 штучки дя примера
            delta={
               
              'line':function(progress){
                     return progress;
               },
              
              'circ':function(progress){
                     return 1 - Math.sin(Math.acos(progress))
               },
              
               'sine':function (progress) {
                 return 1 - Math.sin((1 - progress) * Math.PI/2);
               }
            
            },

            //счётчик для циклов
            i=0;
            
        //так как время и ссылку на анимируемы обьект передали в style, то нужно эти поля удалить
        delete style["time"];
        delete style["el"];
        delete style["easing"];
        
        
        //запомним начальные значения всех свойств
        //вообще можно было бы использвать сomputedStyle напрямую, но мне стрёмно парсить числа на каждой итерации
        // поэтому значения я подгатавливаю в этом цикле заранее
        for (i in style){        
           prop[i]= parseFloat( сomputedStyle[i] )||0;         
        }
        
        //Цикл анимации
        function f(){
          //рассчитаем время прошедшее с начала анимации
          var now=duration-(finalTime- (new Date().getTime()) ),
               progress=now/duration,
               s=0;
          
          // защитимся от случае когда прогресс>100% , в этом случае просто установим 100% то есть  1.
          if (progress>1) progress=1;
          
          // анимируем каждое свойство
          for (i in style){
            s=((style[i]-prop[i]) * delta[easing](progress) )+prop[i];
            el.style[i]= s+ ( ob[i] || "" );
          }
                    
          if (progress<1) setTimeout(f,16);	        
        }

        //запуск первой итераци цикла
        f();
      }  


      // Пример использования получившейся   функции    
      animate({
        el:document.getElementById("test"),
        left:500,
        top:50,
        opacity:1,
        duration:5000,
        //easing:"circ"
      });      
      
      
      // Пример использования получившейся   функции    
      animate({
        el:document.getElementById("test2"),
        left:100,
        top:50,
        opacity:1,
        duration:5000,
        //easing:"circ"
      });      

    </script>

  </body>
</html>

melky 07.02.2013 02:59

Цитата:

Сообщение от DjDiablo
setTimeout(f,30);

setInterval ( f, 1e3 / 60);

интервал - т.к. время между кадрами (тонкая разница между интервалом и таймаутом)

время - ~16мс, время между кадрами при ФПС = 60

DjDiablo 07.02.2013 03:21

раньше при переходе на другую вкладку setInterval продолжал работать, при возвращении на вкладку срабатывали все накопившееся события. Выглядило это как ускорившаяся анимация.

Я не вкурсе просто, сейчас что-то изменилось ?

Можно ещё RequestAnimationFrame использовать, а в случае его отсутствия делать через setTimeout
но пример и без того перегружен по моему.
Я сам непонял нафиг я эту анимацию писать начал, просто чото написать хотелось наверно ))))
В баню всё, я спать :)


// кроссбраузерны requestAnimationFrame с поддержкой старого говна
(function() {
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];

    //если  requestAnimationFrame отсутствует то поищим requestAnimationFrame с префиксами.
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = 
          window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    //если  requestAnimationFrame отсутствует то с имитируем его при помощи timeout
    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };

    // если cancelAnimationFrame отсутствует то будем отменять setTimeout
    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());


Часовой пояс GMT +3, время: 05:09.