Как работать с анимацией в jQuery: fade, slide и animate

Анимация в jQuery помогает плавно показать блок, раскрыть меню и изменить числовые CSS-свойства. Вы соберете страницу с кнопками, разберете fade, slide и animate, а затем соберете изображение из 12 частей. Отдельно разберем очереди эффектов, повторные клики и способы избежать дерганого интерфейса.

Содержание

Стартовая страница для примеров

Начните с небольшой панели и двух кнопок. Этот каркас подходит для fade, slide и animate, поэтому вы сможете менять только обработчики событий.

Как запустить пример на компьютере

Для запуска понадобятся браузер, текстовый редактор и полная сборка jQuery. Сборка slim не содержит методов анимации из этой статьи. Локальный HTML-файл можно открыть напрямую, без установки сервера.

  1. Введите jquery.com в адресной строке браузера. На официальном сайте jQuery откройте страницу загрузки библиотеки.
  2. Выберите полную браузерную сборку без слова slim в названии. Если браузер открыл текст JavaScript, сохраните эту страницу как файл. Поместите файл в новую папку jquery-animation под именем jquery.js.
  3. В текстовом редакторе создайте файл index.html в той же папке. Скопируйте в него каркас из листинга. Сохраните файл как обычный текст в кодировке UTF-8; расширение должно быть .html, без добавленного .txt.
<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <title>Анимация в jQuery</title>
</head>
<body>
  <!-- Вставьте сюда весь следующий листинг с панелью и обработчиками. -->
</body>
</html>

На месте комментария внутри body вставьте следующий листинг целиком. Строка подключения jquery.js уже включена: библиотека загрузится перед обработчиками кнопок.

Минимальная разметка и обработчики

Панель получает position: relative, потому что обработчик меняет свойство left. Вызов stop(true, true) перед новой анимацией очищает старые действия при быстрых кликах.

<button id="toggle" type="button">Показать панель</button>
<button id="move" type="button">Сдвинуть панель</button>
<div id="panel">Панель готова к анимации.</div>
<p id="notice"></p>

<style>
  #panel {
    display: none;
    position: relative;
    left: 0;
    width: 240px;
    padding: 20px;
    background: #e8f1ff;
  }
</style>

<script src="jquery.js"></script>
<script>
  $(function() {
    $("#toggle").on("click", function() {
      $("#panel").stop(true, true).slideToggle(300);
    });

    $("#move").on("click", function() {
      $("#panel").stop(true, true).animate({
        left: "+=40",
        opacity: 0.7
      }, 500, function() {
        $("#notice").text("Панель переместилась");
      });
    });
  });
</script>
  1. Сохраните index.html после вставки кода.
  2. Перетащите файл index.html из папки на окно браузера. На странице появятся две кнопки; панель пока скрыта.
  3. Нажмите «Показать панель». Под кнопками плавно раскроется голубой блок.
  4. Нажмите «Сдвинуть панель». Блок переместится на 40 пикселей вправо, затем появится сообщение «Панель переместилась».

Если кнопки не реагируют, проверьте имена файлов в папке. Рядом с index.html должен лежать jquery.js, без дополнительного расширения. Если браузер сообщает, что slideToggle или animate отсутствует, замените slim-сборку полной.

Чтобы вернуть начальное положение панели, обновите страницу. Следующие JavaScript-примеры вставляйте вместо содержимого последнего тега script, сохраняя подключение библиотеки. Вызовы для работы с разметкой помещайте внутрь $(function() { ... });. Проверяйте варианты по отдельности, чтобы их обработчики не мешали друг другу.

Плавное появление и исчезновение элемента

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

Методы fade и их длительность

fadeIn() показывает скрытый элемент, а fadeOut() скрывает его. Оба метода принимают длительность и callback, который запускается после завершения эффекта.

$("#panel").fadeIn(500);
$("#panel").fadeOut(300, function() {
  $("#notice").text("Панель скрыта");
});

Ключевое слово slow задает длительность 600 миллисекунд, а fast – 200 миллисекунд. Вызов без длительности использует 400 миллисекунд. Явное число удобно, когда один темп повторяется в нескольких обработчиках.

$("#panel").fadeIn("slow");
$("#panel").fadeOut("fast");
$("#panel").fadeToggle(400);

fadeToggle() смотрит на текущее состояние элемента. Скрытый блок появится, а видимый исчезнет.

Как изменить прозрачность без скрытия

fadeTo() меняет opacity до заданного значения, но оставляет элемент в документе. Второй аргумент задает число от 0 до 1.

$("#notice").text("Полупрозрачное сообщение").fadeTo(500, 0.35);

Значение 0 делает элемент полностью прозрачным, а значение 1 возвращает полную непрозрачность. Берите fadeTo(), если элемент должен сохранить место в документе.

Скольжение и переключение состояния

Slide-методы меняют высоту элемента и создают эффект раскрытия. Они подходят для меню, аккордеонов и дополнительных блоков.

Открытие и закрытие блока

slideDown() показывает скрытый блок, а slideUp() скрывает его. Методы принимают длительность и callback так же, как fade-вызовы.

$("#panel").slideDown("slow");
$("#panel").slideUp("fast");
$("#panel").slideToggle(400);

slideToggle() переключает состояние одним вызовом. Callback пригодится, когда сообщение должно появиться после раскрытия или сворачивания.

$("#panel").slideToggle(300, function() {
  $("#notice").text("Состояние панели изменилось");
});

В jQuery Effects API эти методы собраны в одной группе. Таблица помогает сопоставить вызов с задачей.

МетодЧто меняетПараметры простого вызова
fadeIn()Показывает элемент через opacityдлительность, callback
fadeOut()Скрывает элемент через opacityдлительность, callback
fadeToggle()Переключает видимость через opacityдлительность, callback
fadeTo()Задает конечную прозрачностьдлительность, opacity, callback
slideDown()Раскрывает элемент по высотедлительность, callback
slideUp()Сворачивает элемент по высотедлительность, callback
slideToggle()Переключает состояние по высотедлительность, callback

Анимация CSS-свойств через animate

Метод animate() изменяет числовые CSS-свойства за заданное время. Он подходит для движения, размеров, opacity и координат.

Базовый вызов и callback

Первый аргумент содержит свойства и конечные значения. Следующие аргументы задают длительность, easing и функцию после завершения.

$("#panel").show().animate({
  opacity: 1,
  left: "200px"
}, 800, "swing", function() {
  $("#notice").text("Анимация завершена");
});

Встроенные easing – linear и swing. Другие варианты добавляют jQuery UI или отдельный плагин. Относительная запись left: "+=150" прибавляет 150 пикселей к текущей координате.

Свойства left и top требуют позиционированного элемента. Задайте ему position: relative, absolute или fixed.

$("#panel").show().animate({
  left: "+=150",
  opacity: 0.7
}, 500);

Без плагина animate() работает с числовыми свойствами. Цвета этим методом не меняются, поэтому для них используйте CSS transitions, CSS animations или Web Animations API в документации MDN.

Когда выбрать CSS или Web Animations API

CSS transitions подходят для перехода между двумя состояниями, а CSS animations – для повторяющихся сцен с ключевыми кадрами. Web Animations API дает JavaScript контроль над временем, отменой и последовательностью.

Для движения попробуйте анимировать transform средствами CSS или Web Animations API. Изменения left, ширины и высоты могут вызывать перерасчет раскладки страницы, поэтому один API сам по себе не гарантирует плавность.

Анимация частей изображения

Для демонстрации подготовьте 12 квадратов по 150 на 150 пикселей. Разместите 6 частей в верхнем ряду и 6 частей в нижнем.

Как получить части и разметку

Откройте исходную картинку в редакторе изображений и подготовьте область 900 на 300 пикселей. Разделите ее сеткой с шагом 150 пикселей, затем сохраните 12 квадратов по рядам.

Готовая разметка использует общий класс img_item. Такой вариант подходит и для отдельных файлов, и для фоновых фрагментов. Поместите файлы 1.jpg–12.jpg в папку рядом с index.html.

<div id="img_panel">
  <div class="img_item"><img src="1.jpg" alt="Часть изображения 1"></div>
  <div class="img_item"><img src="2.jpg" alt="Часть изображения 2"></div>
  <div class="img_item"><img src="3.jpg" alt="Часть изображения 3"></div>
  <div class="img_item"><img src="4.jpg" alt="Часть изображения 4"></div>
  <div class="img_item"><img src="5.jpg" alt="Часть изображения 5"></div>
  <div class="img_item"><img src="6.jpg" alt="Часть изображения 6"></div>
  <div class="img_item"><img src="7.jpg" alt="Часть изображения 7"></div>
  <div class="img_item"><img src="8.jpg" alt="Часть изображения 8"></div>
  <div class="img_item"><img src="9.jpg" alt="Часть изображения 9"></div>
  <div class="img_item"><img src="10.jpg" alt="Часть изображения 10"></div>
  <div class="img_item"><img src="11.jpg" alt="Часть изображения 11"></div>
  <div class="img_item"><img src="12.jpg" alt="Часть изображения 12"></div>
</div>

Добавьте эту разметку перед подключением jquery.js. Правила CSS вставьте внутрь существующего тега style.

#img_panel {
  position: relative;
  width: 900px;
  height: 300px;
}

.img_item {
  position: absolute;
  width: 150px;
  height: 150px;
  left: 750px;
  top: 0;
  opacity: 0;
}

#img_panel img {
  display: block;
  width: 150px;
  height: 150px;
}

Начальная координата left: 750px равна ширине контейнера минус ширина части: 900 − 150. Каждый квадрат начинает движение у правого края.

Исходное изображение для нарезки на 12 частей

Фоновые фрагменты без тегов img

Чтобы обойтись без ручной нарезки, замените содержимое каждого контейнера. Внутри #img_panel должны остаться только 12 пустых элементов с классом img_item, без тегов img.

<div id="img_panel">
  <div class="img_item"></div>
  <div class="img_item"></div>
  <div class="img_item"></div>
  <div class="img_item"></div>
  <div class="img_item"></div>
  <div class="img_item"></div>
  <div class="img_item"></div>
  <div class="img_item"></div>
  <div class="img_item"></div>
  <div class="img_item"></div>
  <div class="img_item"></div>
  <div class="img_item"></div>
</div>

Добавьте фоновое изображение в CSS. Этот вариант загружает картинку с сайта, поэтому при запуске понадобится интернет.

#img_panel > div {
  background-image: url("https://www.internet-technologies.ru/wp-content/uploads/articles/201311/izobrazhenie-dlja-animaci-150532.png");
  background-size: 900px 300px;
}

Внутри $(function() { ... }); задайте фоновые позиции перед запуском анимации.

$("#img_panel > div").each(function(index) {
  $(this).css("background-position",
    -((index % 6) * 150) + "px " +
    -(Math.floor(index / 6) * 150) + "px"
  );
});

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

Одновременное появление двух рядов

Каждая часть получает конечные координаты left и top. Все вызовы стартуют в одном обработчике, поэтому два ряда собираются одновременно.

$(function() {
  $(".img_item").each(function(index) {
    $(this).animate({
      left: (index % 6) * 150,
      top: Math.floor(index / 6) * 150,
      opacity: 1
    }, 1500);
  });
});

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

Результат одновременной анимации двух рядов изображения

Последовательная анимация нескольких элементов

Одновременная сборка подходит для короткого эффекта. Для появления частей по одной запускайте следующий элемент из callback предыдущего.

Рекурсивная функция сборки

Селектор $(".img_item") выбирает оба ряда, а функция рассчитывает координаты по индексу. Условие останавливает вызов до обращения к несуществующей части. Замените этим кодом одновременную сборку, сохранив разметку и CSS.

$(function() {
  var items = $(".img_item");
  animateImg(items, 0, 0, 0);
});

function animateImg(items, left, top, indexNum) {
  if (indexNum < items.length) {
    var item = items.get(indexNum);

    $(item).animate({
      left: left,
      top: top,
      opacity: 1
    }, 1500, function() {
      var nextLeft = left + 150;
      var nextTop = top;
      var nextIndex = indexNum + 1;

      if (nextIndex % 6 === 0) {
        nextLeft = 0;
        nextTop += 150;
      }

      animateImg(items, nextLeft, nextTop, nextIndex);
    });
  }
}

Индекс начинается с нуля, поэтому функция берет первый элемент. После 6-й части следующий элемент получает left: 0 и top: 150. Callback запускает следующий шаг после завершения текущего эффекта.

Условие indexNum < items.length останавливает перебор на последнем элементе. Проверка с <= допустила бы обращение за пределы коллекции.

Последовательная сборка изображения функцией animateImg

Цепочка эффектов для одного элемента

jQuery ставит анимационные вызовы в очередь конкретного элемента. Один элемент может сначала появиться, затем подождать и выполнить отдельный финальный эффект без изменения координат.

Появление, пауза и изменение прозрачности

Этот код ставит эффекты в очередь каждого элемента. После сборки часть ждет 300 миллисекунд, затем ненадолго становится полупрозрачной и возвращает исходную непрозрачность. Запустите его внутри обработчика готовности страницы вместо предыдущего варианта сборки.

$(".img_item").each(function(index) {
  var left = (index % 6) * 150;
  var top = Math.floor(index / 6) * 150;

  $(this)
    .animate({
      left: left,
      top: top,
      opacity: 1
    }, 800)
    .delay(300)
    .animate({ opacity: 0.7 }, 250)
    .animate({ opacity: 1 }, 250);
});

delay() добавляет паузу в ту же очередь. Каждый элемент получает собственную цепочку, поэтому один ряд не блокирует другой. Финальные вызовы меняют только прозрачность и не раздвигают собранную картинку.

Очередь эффектов и повторные клики

Новый вызов анимации обычно встает в очередь элемента. При быстрых кликах очередь растет, и панель начинает отрабатывать старые команды с заметной задержкой.

Как остановить лишние эффекты

stop(true, true) удаляет ожидающие эффекты и доводит текущий эффект до конечного состояния. После этого обработчик запускает новый эффект.

$("#toggle").on("click", function() {
  $("#panel")
    .stop(true, true)
    .slideToggle(300);
});

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

$("#panel").finish().fadeOut(200);

Ручное управление queue и dequeue

queue() добавляет функцию в очередь. В стандартной очереди fx jQuery передает функции next, а вызов next() запускает следующее действие.

$("#panel").show().queue(function(next) {
  $(this).addClass("active");
  next();
}).delay(300).fadeOut(400);

Именованную очередь запускайте вручную. Вызов dequeue("steps") запускает первую функцию, а next() передает управление следующей.

$("#panel")
  .queue("steps", function(next) {
    $(this).addClass("active");
    next();
  })
  .queue("steps", function(next) {
    $(this).removeClass("active");
    next();
  });

$("#panel").dequeue("steps");

Как дождаться окончания группы

promise().done() сообщает о завершении очередей всех выбранных элементов. Это удобно для сообщения после одновременного появления 12 частей.

$(".img_item")
  .animate({ opacity: 1 }, 800)
  .promise()
  .done(function() {
    $("#notice").text("Все части появились");
  });

Callback внутри animate() сообщает о завершении одного элемента. promise().done() ждет завершения очередей всей выбранной коллекции.

Как выбрать способ анимации

Выбирайте метод по свойству, которое меняете, и по способу запуска эффекта.

  • fade. Меняет прозрачность и показывает или скрывает элемент.
  • slide. Раскрывает и сворачивает блок по высоте.
  • animate. Меняет числовые свойства и запускает callback.
  • queue. Собирает последовательность действий.
  • stop. Останавливает текущий эффект и при первом аргументе true очищает ожидающие действия.

Для перехода между двумя состояниями берите CSS transitions. CSS animations удобны для сцены с ключевыми кадрами, а Web Animations API подходит для сложного JavaScript-контроля времени, отмены и последовательности.

jQuery сохраняет смысл в существующем проекте, где уже подключены его селекторы и обработчики. Для новой сцены сравните стоимость перерасчета раскладки и попробуйте transform вместо изменения left.

Что проверить перед запуском анимации

Перед отладкой согласуйте разметку, CSS и очередь. Большинство ошибок появляется из-за отсутствующего элемента или неверного селектора.

  • Проверьте, что #panel, #toggle и #notice есть на странице.
  • Убедитесь, что полная сборка jQuery подключена до собственного скрипта.
  • Задайте position элементу, который меняет left или top.
  • Задайте частям числовую начальную координату left: 750px.
  • Сверьте число частей: для двух рядов нужны 12 изображений или 12 фоновых контейнеров.
  • Если кнопка допускает повторные клики, начинайте анимацию с stop(true, true).

Если панель застыла, откройте консоль браузера и прочитайте ошибку. Сообщение об отсутствии $ указывает на проблему подключения jQuery.

Если части не видны, временно задайте им opacity: 1. Так вы отделите ошибку загрузки изображений от ошибки анимации.

Заключение

Методы fade и slide плавно меняют видимость, а animate работает с числовыми CSS-свойствами. Callback запускает следующий шаг после завершения текущего эффекта.

Для последовательной сборки используйте рекурсию с условием indexNum < items.length. Для цепочки одного элемента объединяйте animate() и delay(), а повторные клики обрабатывайте через stop(true, true).

queue() и dequeue() управляют именованными действиями, finish() завершает очередь, а promise().done() сообщает об окончании анимации группы элементов.

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

Комментарии

Оставьте свой комментарий
Пока никто не оставил комментариев