Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 14.08.2013, 14:11
Интересующийся
Отправить личное сообщение для weber Посмотреть профиль Найти все сообщения от weber
 
Регистрация: 08.04.2013
Сообщений: 16

использование $.deferred со сторонними плагинами jQuery
Здравствуйте, разбираюсь тут со сложной анимацией и возникли некоторые вопросы.

Хочу сделать сложную анимацию движения автобуса с поворотами. изменением масштаба и т.д.
Саму анимацию движения реализовываю через .animate().
Для наклонов и изменения масштаба автобуса использую сторонний плагин для jQuery вот такой

Учитывая что анимация состоит из множества небольших отрезков движения, нужно как-то управлять очередью анимации, для этого решил использовать $.deferred.

Если пишу что-то типа такого:
var bus = $('.bus');
    var a1 = bus.animate({'right':'50px','top':'120px'}, 1500);
    var a2 = bus.animate({'right':'150px','top':'135px'}, 1500);

    $.when(a1, a2).done(function () {
          $('.bus').animate({'right':'200px','top':'150px'}, 1500);
    });


то все отлично, порядок эффектов ожидаемый. сначала срабатывает первая анимация, потом вторая и по завершению этих событий идет последняя анимация.

Но если если пытаюсь использовать эффекты .rotate() или .scale() то они живут своей жизнью. Где бы я их не вызывал они срабатывают сразу не дожидаясь очереди.
Получается что deferred может работать только с родными методами jquery? А как можно его заставить работать с методами подключенного плагина?
Ответить с цитированием
  #2 (permalink)  
Старый 14.08.2013, 23:10
Аватар для jsru_
Кандидат Javascript-наук
Отправить личное сообщение для jsru_ Посмотреть профиль Найти все сообщения от jsru_
 
Регистрация: 09.04.2013
Сообщений: 149

попробуй bus.animate({'right':'150px','top':'135px'}, 1500, function () {
some_function();
});
Ответить с цитированием
  #3 (permalink)  
Старый 15.08.2013, 16:09
Интересующийся
Отправить личное сообщение для weber Посмотреть профиль Найти все сообщения от weber
 
Регистрация: 08.04.2013
Сообщений: 16

Сообщение от jsru_ Посмотреть сообщение
попробуй bus.animate({'right':'150px','top':'135px'}, 1500, function () {
some_function();
});
так то оно работает, но мне такой вариант не подходит. Для пары-тройки последовательных функций применить можно. но когда анимация состоит из нескольких десятков функций, альтернативы деферредам не вижу...
Ответить с цитированием
  #4 (permalink)  
Старый 15.08.2013, 19:43
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,109

weber,
кликните что бы испытать незабываемую поездку по золотому кольцу...
<!DOCTYPE html>

<html>

<head>

  <style>

    div{
      margin:3px; width:100px; height:40px;
      position:absolute; left:0px; top:30px;
      background:green;
      color: #FFFFFF;
    }



  </style>

  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>(function (c) {
    var b = null,
        f = c.fn.css;
    c.fn.css = function (a, g) {
        null === b && (b = "undefined" != typeof c.cssProps ? c.cssProps : "undefined" != typeof c.props ? c.props : {});
        if ("undefined" == typeof b.transform && ("transform" == a || "object" == typeof a && "undefined" != typeof a.transform)) {
            var h = b,
                d;
            a: {
                d = this.get(0);
                for (var k = ["transform", "WebkitTransform", "msTransform", "MozTransform", "OTransform"], e; e = k.shift();)
                    if ("undefined" != typeof d.style[e]) {
                        d = e;
                        break a
                    }
                d = "transform"
            }
            h.transform = d
        }
        if ("transform" != b.transform)
            if ("transform" == a) {
                if (a = b.transform, "undefined" == typeof g && jQuery.style) return jQuery.style(this.get(0), a)
            } else "object" == typeof a && "undefined" != typeof a.transform && (a[b.transform] = a.transform, delete a.transform);
        return f.apply(this, arguments)
    }
})(jQuery);</script>
  <script>(function (c) {
    function e(a) {
        var b = a.data("_ARS_data");
        b || (b = {
            rotateUnits: "deg",
            scale: 1,
            rotate: 0
        }, a.data("_ARS_data", b));
        return b
    }

    function f(a, b) {
        a.css("transform", "rotate(" + b.rotate + b.rotateUnits + ") scale(" + b.scale + "," + b.scale + ")")
    }
    c.fn.rotate = function (a) {
        var b = c(this),
            d = e(b);
        if ("undefined" == typeof a) return d.rotate + d.rotateUnits;
        if (a = a.toString()
            .match(/^(-?\d+(\.\d+)?)(.+)?$/)) a[3] && (d.rotateUnits = a[3]), d.rotate = a[1], f(b, d);
        return this
    };
    c.fn.scale = function (a) {
        var b = c(this),
            d = e(b);
        if ("undefined" == typeof a) return d.scale;
        d.scale = a;
        f(b, d);
        return this
    };
    var g = c.fx.prototype.cur;
    c.fx.prototype.cur = function () {
        return "rotate" == this.prop ? parseFloat(c(this.elem)
            .rotate()) : "scale" == this.prop ? parseFloat(c(this.elem)
            .scale()) : g.apply(this, arguments)
    };
    c.fx.step.rotate = function (a) {
        var b = e(c(a.elem));
        c(a.elem)
            .rotate(a.now + b.rotateUnits)
    };
    c.fx.step.scale = function (a) {
        c(a.elem)
            .scale(a.now)
    };
    var h = c.fn.animate;
    c.fn.animate = function (a) {
        if ("undefined" != typeof a.rotate) {
            var b, d = a.rotate.toString()
                    .match(/^(([+-]=)?(-?\d+(\.\d+)?))(.+)?$/);
            d && d[5] && (b = c(this), b = e(b), b.rotateUnits = d[5]);
            a.rotate = d[1]
        }
        return h.apply(this, arguments)
    }
})(jQuery);</script>


</head>

<body>

  Click here...

  <div class="bus">bus</div>
  <script>
    $(document.body).click(function () {
              var bus = $('.bus');
    bus.animate({'left':'150px'}, 1500)
       .animate({rotate: '+=90deg', scale: '1.25'}, 1000)
       .animate({'top':'120px'}, 1500)
       .animate({rotate: '+=90deg', scale: '.5'}, 1000)
       .animate({'left':'0px'}, 1500)
       .animate({rotate: '+=90deg','top':'30px' }, 1000)
       .animate({rotate: '+=90deg', scale: '1'}, 1000)
    });

  </script>

</body>

</html>
Ответить с цитированием
  #5 (permalink)  
Старый 18.08.2013, 14:07
Интересующийся
Отправить личное сообщение для weber Посмотреть профиль Найти все сообщения от weber
 
Регистрация: 08.04.2013
Сообщений: 16

Пока сидел читал литературу несколько дней, даже не заметил что тут сообщение!
Блин я даже не ожидал такого, прям на блюдечке! Спасибо огромное что уделили столько времени и расписали так подробно, сижу вот теперь "распарсиваю" Ваш код и мотаю на ус, буду теперь все как нужно у себя анимировать

Низкий Вам поклон, добрый человек

жаль конечно что не с deferred объектами...
Потому что для анимации одного объекта применить можно. а для синхронизации анимации нескольких объектов опять проблема...

Последний раз редактировалось weber, 18.08.2013 в 15:58.
Ответить с цитированием
  #6 (permalink)  
Старый 23.08.2013, 13:27
Интересующийся
Отправить личное сообщение для weber Посмотреть профиль Найти все сообщения от weber
 
Регистрация: 08.04.2013
Сообщений: 16

у меня назрел еще один вопрос, как можно сгладить или вообще убрать паузу между срабатыванием .animate()? То есть, скажем здесь:

.animate({rotate: '+=90deg', scale: '1.25'}, 1000)
.animate({'top':'120px'}, 1500)


поворачивается на 90 градусов, увеличивается на 25% и застывает на примерно секунду и только после этого перемещается к позиции top: 120px

для не очень большой цепочки срабатывает вот такой прием:

.animate({rotate: '+=90deg', scale: '1.25', 'top':'120px'}, 1000)


и это логично. Но если скажем мне нужно сделать что-то типа такого

.animate({rotate: '5deg', scale: '1.25', 'top':'120px', rotate: '0deg', scale: '1', 'top':'100px', 'left': '150px', rotate: '-5deg'}, 5000)


ну в общем много повторяющихся действий с разными значениями, такой прием уже не работает. Как это можно сделать правильней?
Ответить с цитированием
  #7 (permalink)  
Старый 24.08.2013, 09:17
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,109

weber,
если нужно сразу то css()
Ответить с цитированием
  #8 (permalink)  
Старый 24.08.2013, 15:26
Интересующийся
Отправить личное сообщение для weber Посмотреть профиль Найти все сообщения от weber
 
Регистрация: 08.04.2013
Сообщений: 16

Сообщение от рони Посмотреть сообщение
weber,
если нужно сразу то css()
нет, я наверное не верно выразился, мне нужно не чтобы что-то менялось сразу, а чтобы между двумя вызовами .animate() не было задержки.
Но кажется обойти эту проблему удалось, уверен что это не совсем то что нужно, но почитал в документации про step() и переписал код с его использованием, теперь хотя бы чисто визуально стало ближе к тому что я хотел.
Ответить с цитированием
  #9 (permalink)  
Старый 24.08.2013, 16:41
Интересующийся
Отправить личное сообщение для weber Посмотреть профиль Найти все сообщения от weber
 
Регистрация: 08.04.2013
Сообщений: 16

Накидал некоторые наброски анимации, но есть моменты с которыми не могу разобраться и был бы весьма благодарен за подсказки от опытных разработчиков.

Чтобы было нагляднее и понятнее о чем речь залил свой небольшой проектик в песочницу:
http://learn.javascript.ru/play/ikLlE

Никак не могу побороть некоторые проблемы:
1) Как можете видеть, при движении по диагонали машины как будто трясутся, можно ли с этим что-то сделать?
2) Хочу привязать движение пешехода к движению автобуса, для этого навесил колбек функцию вызова движения пешехода к анимации подъезжающего к остановке автобуса, но почему-то после первого цикла пешеход начинает сам по себе бегать, не обращая внимания на остальных. Как можно это обойти?

Вообще изначально тему созхдавал про деферреды, потому что как я понял из документации они как раз для таких ситуаций, но так и не удалось заставить их работать по человечески.

Вы уж извините за г***код, я только постигаю JS))
Ответить с цитированием
  #10 (permalink)  
Старый 24.08.2013, 18:22
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,109

weber,на каждом шаге анимации вы дополнительно ещё анимируите - данный приём мне непонятен - естественно на каждом шаге запускается новый "пешеход" а так как всё зациклено через setInterval -- лучше через таймер -- то анимация пешехода повторяется и повторяется. -- закончилась последняя анимация запустили анимации на повтор
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
хочу инвайт на хабр macdack Оффтопик 45 28.07.2013 23:18
Вопрос поддержки старых методов jQuery antonM jQuery 1 04.10.2012 00:08
jQuery Использование textIndent при анимации slim-v Opera, Safari и др. 26 19.12.2010 18:16