Опубликован: 28.02.2016 | Доступ: свободный | Студентов: 1787 / 138 | Длительность: 11:48:00
Лекция 5:

Анимация

< Лекция 4 || Лекция 5: 12 || Лекция 6 >

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;
< Лекция 4 || Лекция 5: 12 || Лекция 6 >
Наталья Маркова
Наталья Маркова
Ярослав Гаевой
Ярослав Гаевой

10 марта 2016 c 20:13 до 22:39 я сдавал экзамен. Однако, за два месяца статус не изменился: "Задание не проверено"

Когда ожидать проверки?

Александр Левченко
Александр Левченко
Украина, Киев
Станислав Мешавкин
Станислав Мешавкин
Россия, г. Заречный