jQuery для начинающих. Часть 5. Эффекты

Categories: JavaScript

Продолжаем изучать jQuery. Переходим к эффектам…

Хотел было написать огромную статью о эффектах, с примерами той или иной анимации, но получилось скорее заметка, которая поможет вам понять суть эффектов в jQuery

Animate

Запомните – все эффекты анимации в jQuery крутятся вокруг функции animate – данная функция берет один или несколько CSS свойств элемента и изменяет их исходного до конечного за N-ое количество итераций (количество итераций зависит от указанного времени, но не реже одной итерации в 13ms (если я правильно накопал это значение)).

Функция animate понимает следующие параметры:

  • params – описание CSS свойств элемента, до которых будет происходить анимация (т.е. есть у нас div с высотой 100px – говорим animate({height:200}) – и высота плавно изменяется до 200px)
  • duration – скорость анимации – указываем в миллисекундах, или используя ключевые слова “fast” = 200ms, “normal” = 400ms или “slow” = 600ms
  • easing – указываем какую функцию будем использовать для наращивания значений, на выбор “linear” или “swing” (хотите больше см. Easing Plugin)
  • callback – функция, которая будет вызвана после окончания анимации

Альтернативный способ инициализации:

  • params – описание CSS свойств элемента, до которых будет происходить анимация
  • options – объект настроек:
    • duration – см. выше
    • easing – см. выше
    • complete – аналогичен ранее описанному callback-параметру
    • step – еще одна callback функция – отвечает за пошаговое изменение параметров – пример ниже
    • queue – флаг очереди, если выставить в false – то данная анимация будет игнорировать очередь и запустится сразу

Если заглянуть в руководство пользователя – то в разделе эффектов можно найти еще несколько вспомогательных функций:

  • show( ) – отображает выбранные элементы
  • hide( ) – скрывает выбранные элементы
  • toggle( ) – переключатель между show/hide
  • slideDown( speed, callback ) – выдвигает объект(ы) вниз – увеличивает высоту от 0 до 100%
  • slideUp( speed, callback ) – задвигает объект(ы) вверх – уменьшает высоту от 100% до 0
  • slideToggle( speed, callback ) – переключатель между slideDown/slideUp
  • fadeIn( speed, callback ) – отображает выбранные элементы – изменяет прозрачность элементов
  • fadeOut( speed, callback ) – скрывает выбранные элементы – изменяет прозрачность элементов
  • fadeTo( speed, opacity, callback )- изменяет прозрачность элементов до указанного значения

Самые простые методы hide и show обходятся без функции animate, т.к. манипулируют лишь атрибутом display (демо):

// вызов метода
$('#my').hide();

// аналогичен
$('#my').css({display:"none"});

// но если задать скорость анимации либо callback функцию,
// то будут изменятся значения height и width

Как я и говорил ранее – остальные вспомогательные функции лишь обертки над animate, приведу пример (демо):

// вызов метода
$('#my').slideUp();

// аналогичен
$('#my').animate({height:0,padding:0}, function(){
	$(this).css({display:"none"});
});

// вызов метода
$('#my').fadeOut();

// аналогичен
$('#my').animate({opacity:0}, function(){
	$(this).css({display:"none"});
});

В действительности, реализация данных методов чуть более сложная, но сути это не меняет

Стоит так же обратить внимание на способ задания параметров CSS для animate:

// установит прозрачность элемента в ноль, прозрачность изменяется от 0 до 1
$('#my').animate({opacity:0});

// наращиваем высоту элемента на 200px
$('#my').animate({height:'+=200px'});

// уменьшаем ширину элемента на 50px
$('#my').animate({width:'-=50px'});

// наращиваем высоту элемента до 20in
$('#my').animate({height:'20in'});

Step Callback

Не стоит забывать и о step-функции, приведу пример использования (демо):

var customStep = function(now, obj) {
	now; // текущее значение анимированного параметра

	obj.elem;  // объект анимации
	obj.prop;  // параметр который анимируется
	obj.start; // начальное значение
	obj.end;   // конечное значение

	obj.pos;   // коэффициент, изменяется от 0 до 1
	           // значение now вычисляется как now = (obj.end - obj.start) * obj.pos

	obj.options; // опции настроек анимации

	// сделаем вывод текста
	$(this).html('Height: '+now+obj.unit);
}
$("p").animate({height: height}, {step:customStep});

Отключение

Иногда требуется отключить всю анимацию (для дебага к примеру) – воспользуйтесь следующей конструкцией:

jQuery.fx.off = true;

В очередь, … ©

Немного о очередности работы функции animate – большинство моих читателей уже знакомо с организацией последовательной анимации – для этого мы можем использовать цепочку вызовов:

$('.panel').animate({left:'+=100'})
	  .animate({top:'+=100'}); // данная анимация добавляется в очередь на выполнение

Для параллельного запуска анимации, необходимо будет внести следующие изменения:

$('.panel').animate({left:'+=100'})
	  .animate({top:'+=100'}, {queue:false});  // таким образом мы указываем, что очередь можно игнорировать

Так же есть функции stop – с помощью данной функции мы можем остановить выполнение текущей либо всех анимаций (демо):

$('.panel').stop();            // останавливаем выполнение текущей анимации
$('.panel').stop(true);        // останавливаем выполнение текущей анимации и всех последующих (чистим очередь)
$('.panel').stop(true, true);  // останавливаем выполнение текущей анимации и всех последующих, но применяем результат текущей
$('.panel').stop(false, true); // останавливаем выполнение только текущей анимации, и применяем её результат

Как очистить очередь мы разобрались, теперь можно чуть-чуть копнуть поглубже, и разобраться как можно управлять очередью. Для этой цели в jQuery служат следующие функции:

  • queue( name ) – возвращает очередь – массив функций
  • queue( name, callback ) – добавляет функцию в очередь
  • queue( name, queue ) – заменяет текущую очередь новой
  • dequeue( name ) – берет первую функцию из очереди и выполняет её

По умолчанию все манипуляции производятся с очередью “fx” – т.е. очередь со всей анимацией

Данные функции могут понадобиться для управления анимации (демо):

$(".panel").queue('fx'); // возвращает очередь эффектов анимации
$(".panel").data('fxqueue'); // аналогично предыдущему вызову

$(".panel").queue(function(){ /*...*/ }); // добавляет новую функцию в очередь анимации

$(".panel").queue("fx", []); // данный вызов очищает очередь анимации - мы устанавливает пустой массив в качестве новой очереди

$(".panel").dequeue(); // запускает первый элемент из очереди

Или вот пример реализации очереди отличной от “fx”:

var queue = $(".panel").queue('custom');
queue.push(function(){
	$(".panel").css({background:'#ffdddd'})
		.dequeue('custom');
});

$(".panel").queue('custom', queue)
	.dequeue('custom');

Пока я вижу одну недоработку – все анимации используют очередь “fx”, и никак изменить это нельзя, т.е. анимация либо идет вместе со всеми в этой очереди, либо сама по себе запускается сразу, назначить анимации другую очередь нельзя

Easing

Возвращаясь к анимации, думаю стоит обратить внимание на способ “наращивания” значений CSS свойств, происходит это следующим образом:

param = (to − from) × delta + from;

// from — начальное значение параметра
// to — конечное значение параметра
// delta — коэффициент, при 0 мы получаем начальное значение параметра, а при 1 — конечное

По умолчанию, для изменение delta используется линейное уравнение, опционально можно указать ’swing’, но используя плагин easing, можно разнообразить этот список (демо) :

  • Quad — квадратичная функция (delta = progress2).
  • Cubic — кубическая функция (delta = progress3).
  • Quart — delta = progress4.
  • Quint — delta = progress5.
  • Expo — экспоненциальная функция (delta = 2(progress − 1) × 8)
  • Circ — четверть окружности (delta = 1 − sin(acos(progress)))
  • Sine — кусок синусоиды (delta = 1 − sin((1 − progress) × π / 2))
  • Back — сначала оттягивает delta в минус, а потом плавно доводит до 1
  • Bounce — прыгающий переход
  • Elastic — эластичный переход (резинка)

Данные функции оперируют следующими параметрами (именование параметров из jquery.js):

  • p – коэффициент прохождения анимации, изменяется от 0 до 1
  • n – коэффициент наложенный на время (p*duration)
  • firstNum – начальное значение = 0
  • diff – изменение значения = 1

При подготовке данного раздела использовались материалы из статьи Анимация в MooTools. Основы и не только

Плагины

Есть несколько плагинов, который расширяют функционал animate (возможно вы используете еще какие – то отпишитесь):

  • easing – дополнительные уравнения для easing (позволит разнообразить анимацию)
  • color – позволяет плавно изменять цвет шрифта/фона/границ
  • backgroundPosition – с его помощью можем анимировать фоновое изображение элементов

Вывод

Вывод напрашивается сам собой – большинство плагинов для анимации – это лишь обертки над animate, и следовательно не всегда стоит подключать сторонние плагины для реализации своей цели.

P.S. Для всех моих читателей – RSS канала доступен по адресу http://anton.shevchuk.name/feed/ (единственный верный).

P.P.S. Еще я постоянно зависаю на твиттере, так что следуйте за мной…

Цикл статей

  1. jQuery для начинающих
  2. jQuery для начинающих. Часть 2. JavaScript Меню
  3. jQuery для начинающих. Часть 3. AJAX
  4. jQuery для начинающих. Часть 4. Селекторы
  5. jQuery для начинающих. Часть 5. Эффекты

This entry was posted on Tuesday, October 6th, 2009 at 10:09 and is filed under JavaScript.
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Другие посты на эту тему

18 Responses to “jQuery для начинающих. Часть 5. Эффекты”

  1. egor

    хехе ) новый пост!_)

  2. А чем этот пост отличается от официальной документации ? Ну, кроме русского языка ?

    • Так можно сказать про большинство технический статей, я бы выделил “усвояемость” предоставленной информации…

  3. Jaska

    Большое спасибо за цикл статей) благодаря им я теперь уверенно использую jquery в своих проектах.

  4. Jaska

    С очередностью анимации все понятно. Но меня интересует другое

       $("#tLeftColumn").animate({opacity:0}, 300)
    				    .html("<div align='center' id='ContentTitle'>"+ titlemsg +"</div>" + data)
    					.animate({opacity:1});
      });

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

    • Попробуйте сформировать очередь вручную:

       $("#tLeftColumn").animate({opacity:0}, 300)
      		  .queue(function() {
                            $(this).html("<div align='center' id='ContentTitle' >"+ titlemsg +"</div>" + data);
                            $(this).dequeue();
                        }).animate({opacity:1});
      });
      

      Или так как описано в примере реализации очереди отличной от “fx”.

  5. спасибо, как всегда понятно информативно и полезно!
    так держать!

  6. Sorry to bother you on these comments but I didn’t find where to contact you.
    I’m using QR Code for Wordpress and that’s a wonderful app. Thks a lot.
    Just have a tiny suggestion : generated barcodes are very big on the blog and mobile phones in Europe don’t have a powerful macro on the camera. Why not a dynamic service like a bit.ly or tinyurl to generate smaller QR Code/URL ? Well, that’s just an idea. Thanks again for this application
    Jack

  7. Zmiuko

    Спасиб автору. Несколько месяцев уже читаю ваши статьи. :)

    Сейчас вот пишу слайдер, дабы убрать громоздкий баннер на флеше с главной страницы моего сайта.

    http://leeas.ru сайт галереи граффити вконтакте. На сайте около 9 миллионов картинок. Вернее записей. Хочу попробывать опустить php и напрямую брать из файла информацию посредством js. Как полагаете, возможно ли наладить прямое подключение к базе, либо скажем к тестовому файлу?

  8. Vik

    Помогите исправить ошибку в javascript
    CMS Drupal вставил javascript в header в файлы page.tpl, page-front.tpl, page-node.tpl:

    $(document).ready(function() {
          $('#s1').cycle({
        fx:      'fade',
        speed:    5000,
        timeout:  2000
    });
    });
    

    При первой загрузке страницы собщение IE о ошибке и javascript не запускается но если кликнуть на любую ссылку
    то дальше работает нормально, кроме того при переходе по ссылкам скрипт на каждой странице загружатся заново.
    Как зделать так чтобы скрипт в header не перегружался при переходе? Сайт:http://www.viatm.com/bruk.org.ua

  9. Garik

    Спасибо за статьи!!
    Решил сделать анимированное меню и столкнулся с такой проблемой, которую ранее замечал на многих сайтах: когда по кнопкам быстро-быстро водишь, потом останавливаешься, кнопки продолжают колбаситься. Полагаю нужно копать в сторону функции stop. Но при странно срабатывает эфект прозрачности. Т.е. когда я навожу курсор, подсказка начинает появляться, не дождавшись пока она появится, я отвожу курсор и снова навожу. Прозрачность подсказки доходит до того уровня, до которого она дошла в прошлый раз и выше не становиться. Т.е. если я отвел курсор когда opacyty был 0.5, то и в следующий раз он будет 0.5, хотя в коде указано что он должен быть 1.0
    Вот пример кода:

    $(document).ready(function() {
    
    	$("a").hover(function() {
    		$("#hide").stop().animate({opacity: "show"});
    	}, function() {
    		$("#hide").stop().animate({opacity: "hide"});
    	});
    
    });
    
    #hide { width:50px; height:50px; position:absolute; top:20px; left:100px; background:#0099FF; display:none}
    

    Спасибо за любую подсказку!)

  10. Garik

    Все, не надо) нашел решение: .stop(true, true)

  11. Столкнулся с проблемой.

    	$("body").mousemove(function(e){
    		$("div#block").animate({/* передвигаем вслед за мышкой */});
    	});

    В моем случае dib#block имеет вид красного квадрата. Так вот при передвижении мыши квадрат сильно тормозит. Насколько я понимаю при каждом событии mousemove в стек помещается функция которая двигает до определенной координаты, поскольку передвижение совершается медленнее чем двигается мышка (даже если скорость равна) в стеке в скором времени насчитывается огромное количество функций. Вот хотелось бы поинтересоваться как преодолеть эту проблему?

    • Надо останавливать анимацию, и да – еще бы лучше селекторы чутка оптимизировать…

      var $block = $("#block");
      $("body").mousemove(function(e){
          $block.stop(true);
          $block.animate({/* передвигаем вслед за мышкой */});
      });
      
  12. Jaska

    Отлично!! Спасибо большое! :)

  13. Alex

    Добрый день!
    Помогите решить проблему.
    В сайте использую библиотеку jQuery.
    Во всех браузерах скрипты работают нормально за исключением IE, который выдаёт ошибку “Исключение брошено и не поймано” и ссылается при этом на jquery.js
    Заранее очень благодарен!!!

Leave a Reply

Copyright © 2007-2010, Anton Shevchuk. Powered by WordPress

MAXCACHE: 0.25MB/0.00039 sec