Анимация
Step-by-step
Хотелось бы отдельно остановиться на функции "step", и для наглядности приведу пример реализации подобной функции, которая отображает текущее значение анимированного параметра:
var customStep = function(now, obj) {
obj.elem; // объект анимации
obj.prop; // параметр, который анимируется
obj.start; // начальное значение
obj.end; // конечное значение
obj.pos; // коэффициент, изменяется от 0 до 1
obj.options; // опции настроек анимации
now; // текущее значение анимированного параметра, вычисляется как
// now = (obj.end - obj.start) * obj.pos
$(this).html(obj.prop +': '+now+obj.unit); // вывод текста
}
$("#box").animate({height: "+=10px"}, {step: customStep});Мне ни разу не приходилось использовать step-функции, лишь только для примера
В очередь…©
Немного об очередности работы функции "animate()" – большинство читателей, наверное, уже знакомо с организацией последовательной анимации – для этого мы можем использовать цепочку вызовов:
$('#box ')
// говорим что меняем
.animate({left:'+=100'})
// следующий вызов добавляется в очередь на выполнение
.animate({top:'+=100'})Для параллельного запуска анимации, необходимо будет внести следующие изменения:
$('#box')
// говорим что меняем
.animate({left:'+=100'})
// следующий вызов будет игнорировать очередь
.animate({top:'+=100'}, {queue:false})Есть ещё чудесная функция "stop()", которая позволяет остановить текущую анимацию на полпути, а так же почистить очередь при необходимости. Для обеспечения различного поведения функции, она принимает три параметра:
queue – имя очереди; для работы с очередью анимации "fx" данный параметр опускаем ("fx" – очередь по умолчанию)
clearQueue – флаг очистки очереди
jumpToEnd – применить результат анимации али нет
// останавливаем выполнение текущей анимации
$('#box').stop();
// останавливаем выполнение текущей анимации
// и всех последующих (чистим очередь)
$('#box').stop(true);
// останавливаем выполнение текущей анимации и всех последующих
// но применяем результат текущей
$('#box').stop(true, true);
// останавливаем выполнение только текущей анимации
// и применяем её результат
$('#box').stop(false, true);Пример есть, и требует ваших проб и ошибок:
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Пример работы очередей анимации</title>
<link rel="profile" href="http://gmpg.org/xfn/11"/>
<link rel="shortcut icon" href="http://anton.shevchuk.name/favicon.ico"/>
<link rel="stylesheet" href="css/styles.css"/>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/code.js"></script>
<style>
article {
position: relative;
height: 600px;
}
#box {
background: #55f;
position: relative;
margin: 10px;
width: 80px;
height: 80px;
}
#box span {
display: inline-block;
background: #fff;
font-size: 22px;
line-height: 22px;
text-align: center;
width: 16px;
margin: 6px 8px;
padding: 2px;
border: 1px solid #000;
border-radius: 2px;
}
.red {
color:red;
}
</style>
</head>
<body>
<div id="content" class="wrapper box">
<menu label="Try...">
<a href="animate.html" title="go prev" class="button alignleft" rel="prev">? Prev </a>
<a href="index.html" title="back to Index" class="button alignleft" rel="index">Index §</a>
<a href="#" title="reload" class="button alignleft" onclick="window.location.reload();return false">Reload ¤</a>
<a href="animate.game.html" title="go next" class="button alignright" rel="next">Next ?</a>
<hr/>
<pre><code contenteditable="true"><em>// with queue</em>
$(<span>'#box'</span>).animate({
<span>'left'</span>:<span>'+=100'</span>
}, 2000).animate({
<span>'top'</span>:<span>'+=100'</span>
}, 2000)</code></pre>
<button type="button" class="code">Run Code</button>
<pre><code contenteditable="true"><em>// without queue</em>
$(<span>'#box'</span>).animate({
<span>'left'</span>:<span>'-=100'</span>
}, 2000).animate({
<span>'top'</span>:<span>'-=100'</span>
}, {queue:false, duration:2000})</code></pre>
<button type="button" class="code">Run Code</button>
<pre><code contenteditable="true"><em>// stop current</em>
$(<span>'#box'</span>).stop()</code></pre>
<button type="button" class="code">Run Code</button>
<pre><code contenteditable="true"><em>// stop all animation</em>
$(<span>'#box'</span>).stop(true)</code></pre>
<button type="button" class="code">Run Code</button>
<pre><code contenteditable="true"><em>// stop current animation, goto end, clear queue</em>
$(<span>'#box'</span>).stop(true, true)</code></pre>
<button type="button" class="code">Run Code</button>
<pre><code contenteditable="true"><em>// stop current animation</em>
$(<span>'#box'</span>).stop(false, true)</code></pre>
<button type="button" class="code">Run Code</button>
</menu>
<header>
<h1>Очередь</h1>
<h2>Пример работы с очередью и без анимировании элементов</h2>
</header>
<article>
<div id="box">
<span>?</span>
<span>?</span>
<span class="red">?</span>
<span class="red">?</span>
</div>
</article>
<footer>
©copyright 2014 Anton Shevchuk — <a href="http://anton.shevchuk.name/jquery-book/">jQuery Book</a>
</footer>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1669896-2']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</div>
</body>
</html>Заметка на будущее: если вы сделали выпадающее меню, и поигравшись с мышкой оно продолжает выпадать и исчезать, то значит надо вставить "stop()" в обработчик события
По умолчанию вся анимация над объектом складывается в очередь "fx", но с версии 1.7 можно указывать произвольную очередь:
$('#box')
.animate({'left':'-=100'}, {queue:'x'}) // составляем очередь X
.dequeue('x') // запускаем очередь X
$('#box').stop('x') // останавливаем анимацию в очереди XДля чего нам может понадобиться произвольная очередь? Да для распараллеливания анимации, чтобы мы могли запустить одну очередь анимации, и в любой другой момент запустить другую очередь, возможно, это заклад под игры? Но чего гадать, давайте пример посмотрим
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Работа с произвольными очередями</title>
<link rel="profile" href="http://gmpg.org/xfn/11"/>
<link rel="shortcut icon" href="http://anton.shevchuk.name/favicon.ico"/>
<link rel="stylesheet" href="css/styles.css"/>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/code.js"></script>
<script>
$(function(){
var logX = $("#log-x");
var logY = $("#log-y");
var $box = $("#box");
logX.text($box.css('left'));
logY.text($box.css('top'));
var stepX = function(now, obj) {
logX.text(Math.floor(now)+obj.unit)
};
var stepY = function(now, obj) {
logY.text(Math.floor(now)+obj.unit)
};
$(document).keydown(function(e){
// 37 - left
// 38 - up
// 39 - right
// 40 - down
switch (e.keyCode) {
case 37:
$box.stop('x', true);
$box.animate({'left':'-=100'}, {queue:'x', step:stepX}).dequeue('x');
break;
case 38:
$box.stop('y', true);
$box.animate({'top':'-=100'}, {queue:'y', step:stepY}).dequeue('y');
break;
case 39:
$box.stop('x', true);
$box.animate({'left':'+=100'}, {queue:'x', step:stepX}).dequeue('x');
break;
case 40:
$box.stop('y', true);
$box.animate({'top':'+=100'}, {queue:'y', step:stepY}).dequeue('y');
break;
}
})
});
</script>
<style>
article {
position: relative;
}
article.withbox {
height: 600px;
}
#box {
background: #55f;
position: relative;
margin: 10px;
width: 80px;
height: 80px;
left:270px;
top:0;
}
#box span {
display: inline-block;
background: #fff;
font-size: 22px;
line-height: 22px;
text-align: center;
width: 16px;
margin: 6px 8px;
padding: 2px;
border: 1px solid #000;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
.red {
color:red;
}
</style>
</head>
<body>
<div id="content" class="wrapper box">
<menu label="Try...">
<a href="animate.queue.html" title="go prev" class="button alignleft" rel="prev">? Prev </a>
<a href="index.html" title="back to Index" class="button alignleft" rel="index">Index §</a>
<a href="#" title="reload" class="button alignleft" onclick="window.location.reload();return false">Reload ¤</a>
<a href="menu.drop-down.html" title="go next" class="button alignright" rel="next">Next ?</a>
<hr/>
<pre><code contenteditable="true">$(<span>'#box'</span>).animate({
<span>'left'</span>:<span>'-=100'</span>
}, {queue:'x', duration:2000}).dequeue('x')</code></pre>
<button type="button" class="code">Left</button>
<pre><code contenteditable="true">$(<span>'#box'</span>).animate({
<span>'left'</span>:<span>'+=100'</span>
}, {queue:'x', duration:2000}).dequeue('x')</code></pre>
<button type="button" class="code">Right</button>
<pre><code contenteditable="true">$(<span>'#box'</span>).animate({
<span>'top'</span>:<span>'-=250'</span>
}, {queue:'y', duration:2000}).dequeue('y')</code></pre>
<button type="button" class="code">Up</button>
<pre><code contenteditable="true">$(<span>'#box'</span>).animate({
<span>'top'</span>:<span>'+=250'</span>
}, {queue:'y', duration:2000}).dequeue('y')</code></pre>
<button type="button" class="code">Down</button>
<pre><code contenteditable="true">$(<span>'#box'</span>).stop(<span>'x'</span>, true);
$(<span>'#box'</span>).stop(<span>'y'</span>, true);</code></pre>
<button type="button" class="code">Stop</button>
</menu>
<header>
<h1>Произвольная очередь анимации</h1>
<h2>Своя очередь, попробуйте использовать стрелочки на клавиатуре (? и ?, ? и ?)</h2>
</header>
<article>
<p>
X: <span id="log-x">0px</span>
Y: <span id="log-y">0px</span>
</p>
</article>
<article class="withbox">
<div id="box">
<span>?</span>
<span>?</span>
<span class="red">?</span>
<span class="red">?</span>
</div>
</article>
<footer>
©copyright 2014 Anton Shevchuk — <a href="http://anton.shevchuk.name/jquery-book/">jQuery Book</a>
</footer>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1669896-2']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</div>
</body>
</html>
Отключение
Иногда требуется отключить всю анимацию (к примеру, для отладки) воспользуйтесь следующей конструкцией:
jQuery.fx.off = true;