14.08.2013, 14:11
|
Интересующийся
|
|
Регистрация: 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? А как можно его заставить работать с методами подключенного плагина?
|
|
14.08.2013, 23:10
|
|
Кандидат Javascript-наук
|
|
Регистрация: 09.04.2013
Сообщений: 149
|
|
попробуй bus.animate({'right':'150px','top':'135px'}, 1500, function () {
some_function();
});
|
|
15.08.2013, 16:09
|
Интересующийся
|
|
Регистрация: 08.04.2013
Сообщений: 16
|
|
Сообщение от jsru_
|
попробуй bus.animate({'right':'150px','top':'135px'}, 1500, function () {
some_function();
});
|
так то оно работает, но мне такой вариант не подходит. Для пары-тройки последовательных функций применить можно. но когда анимация состоит из нескольких десятков функций, альтернативы деферредам не вижу...
|
|
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>
|
|
18.08.2013, 14:07
|
Интересующийся
|
|
Регистрация: 08.04.2013
Сообщений: 16
|
|
Пока сидел читал литературу несколько дней, даже не заметил что тут сообщение!
Блин я даже не ожидал такого, прям на блюдечке! Спасибо огромное что уделили столько времени и расписали так подробно, сижу вот теперь "распарсиваю" Ваш код и мотаю на ус, буду теперь все как нужно у себя анимировать
Низкий Вам поклон, добрый человек
жаль конечно что не с deferred объектами...
Потому что для анимации одного объекта применить можно. а для синхронизации анимации нескольких объектов опять проблема...
Последний раз редактировалось weber, 18.08.2013 в 15:58.
|
|
23.08.2013, 13:27
|
Интересующийся
|
|
Регистрация: 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)
ну в общем много повторяющихся действий с разными значениями, такой прием уже не работает. Как это можно сделать правильней?
|
|
24.08.2013, 09:17
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
weber,
если нужно сразу то css()
|
|
24.08.2013, 15:26
|
Интересующийся
|
|
Регистрация: 08.04.2013
Сообщений: 16
|
|
Сообщение от рони
|
weber,
если нужно сразу то css()
|
нет, я наверное не верно выразился, мне нужно не чтобы что-то менялось сразу, а чтобы между двумя вызовами .animate() не было задержки.
Но кажется обойти эту проблему удалось, уверен что это не совсем то что нужно, но почитал в документации про step() и переписал код с его использованием, теперь хотя бы чисто визуально стало ближе к тому что я хотел.
|
|
24.08.2013, 16:41
|
Интересующийся
|
|
Регистрация: 08.04.2013
Сообщений: 16
|
|
Накидал некоторые наброски анимации, но есть моменты с которыми не могу разобраться и был бы весьма благодарен за подсказки от опытных разработчиков.
Чтобы было нагляднее и понятнее о чем речь залил свой небольшой проектик в песочницу:
http://learn.javascript.ru/play/ikLlE
Никак не могу побороть некоторые проблемы:
1) Как можете видеть, при движении по диагонали машины как будто трясутся, можно ли с этим что-то сделать?
2) Хочу привязать движение пешехода к движению автобуса, для этого навесил колбек функцию вызова движения пешехода к анимации подъезжающего к остановке автобуса, но почему-то после первого цикла пешеход начинает сам по себе бегать, не обращая внимания на остальных. Как можно это обойти?
Вообще изначально тему созхдавал про деферреды, потому что как я понял из документации они как раз для таких ситуаций, но так и не удалось заставить их работать по человечески.
Вы уж извините за г***код, я только постигаю JS))
|
|
24.08.2013, 18:22
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
weber,на каждом шаге анимации вы дополнительно ещё анимируите - данный приём мне непонятен - естественно на каждом шаге запускается новый "пешеход" а так как всё зациклено через setInterval -- лучше через таймер -- то анимация пешехода повторяется и повторяется. -- закончилась последняя анимация запустили анимации на повтор
|
|
|
|