Книга: JavaScript. Подробное руководство, 6-е издание

16.3.1. Создание анимационных эффектов средствами CSS

16.3.1. Создание анимационных эффектов средствами CSS

Одной из наиболее типичных областей применения CSS является воспроизведение визуальных анимационных эффектов. Реализовать их можно с помощью метода setTimeout() или setlnterval() (раздел 14.1), используя их для организации многократных вызовов функции, изменяющей встроенный стиль элемента. Пример 16.3 демонстрирует две такие функции, shake() и fadeOut(). Функция shake() перемещает, или «встряхивает» (shakes), элемент из стороны в сторону. Ее можно использовать, например, для привлечения внимания пользователя в случае ввода некорректных данных. Функция fadeOut() уменьшает непрозрачность элемента в течение указанного периода времени (по умолчанию 500 миллисекунд), вызывая эффект его растворения до полного исчезновения.

Пример 16.3. Воспроизведение анимационных эффектов средствами CSS

// Делает элемент е относительно позиционируемым и перемещает его влево и вправо.
// Первым аргументом может быть объект элемента или значение атрибута id требуемого
// элемента. Если во втором аргументе передать функцию, она будет вызвана с элементом е
// в виде аргумента по завершении воспроизведения анимации. Третий аргумент определяет
// величину смещения элемента е. По умолчанию принимает значение 5 пикселов.
// Четвертый аргумент определяет, как долго должен воспроизводиться эффект.
// По умолчанию эффект длится 500 мсек,
function shake(e, oncomplete, distance, time) {
  // Обработка аргументов
  if (typeof e === "string") e = document.getElementByld(e);
  if (!time) time = 500;
  if (!distance) distance = 5;
  var originalStyle = e.style.cssText; // Сохранить оригинальный стиль e
  e.style.position = "relative"; // Сделать относит, позиционируемым
  var start = (new Date()).getTime(); // Запомнить момент начала анимации ;
  animate()  // Запустить анимацию
  // Эта функция проверяет прошедшее время и изменяет координаты е.
  // Если анимацию пора завершать, восстанавливает первоначальное состояние
  // элемента е. Иначе изменяет координаты е и планирует следующий свой вызов,
  function animate() {
    var now = (new Date()).getTime(); // Получить текущее время
    var elapsed = now-start; // Сколько прошло времени с начала?
    var fraction = elapsed/time; // Доля от требуемого времени?
    if (fraction < 1) { // Если рано завершать анимацию
      // Вычислить координату х элемента е как функцию от доли общего
      // времени анимации. Здесь используется синусоидальная функция,
      // а доля общего времени воспроизведения умножается на 4pi,
      // поэтому перемещение взад и вперед выполняется дважды,
      var x = distance * Math.sin(fraction*4*Math.PI);
      e.style.left = x + "px";
      // Попробовать вызвать себя через 25 мсек или в конце запланированного
      // отрезка общего времени воспроизведения. Мы стремимся сделать
      // анимацию гладкой, воспроизводя ее со скоростью 40 кадров/сек.
      setTimeout(animate, Math.min(25, time-elapsed));
    }
    else { // Иначе анимацию пора завершать
      e.style.cssText = originalStyle // Восстановить первонач. стиль
      if (oncomplete) oncomplete(e); // Вызвать ф-цию обратного вызова
    }
  }
}
// Растворяет е от состояния полной непрозрачности до состояния полной прозрачности
// за указанное количество миллисекунд. Предполагается, что, когда вызывается
// эта функция, е полностью непрозрачен, oncomplete - необязательная функция,
// которая будет вызвана с элементом е в виде аргумента по завершении анимации.
// Если аргумент time не задан, устанавливается интервал 500 мсек.
// Эта функция не работает в IE, но ее можно модифицировать так, чтобы
// в дополнение к свойству opacity она использовала нестандартное
// свойство filter, реализованное в IE.
function fadeOut(e, oncomplete, time) {
  if (typeof e === "string") e = document.getElementByld(e);
  if (!time) time = 500;
  // В качестве простой "функции перехода", чтобы сделать анимацию немного
  // нелинейной, используется Math.sqrt: сначала растворение идет быстро,
  // а затем несколько замедляется,
  var ease = Math.sqrt;
  var start = (new Date()).getTime(); // Запомнить момент начала анимации
  animate(); // И запустить анимацию
  function animate() {
    var elapsed = (new Date()).getTime()-start; // Прошедшее время
    var fraction = elapsed/time; // Доля от общего времени
    if (fraction < 1) { // Если не пора завершать
      var opacity = 1 - ease(fraction); // Вычислить непрозрачн.
      e.style.opacity = String(opacity); // Установить ее в e
      setTimeout(animate, // Запланировать очередной
                Math.min(25, time-elapsed)); // кадр
    }
    else { // Иначе завершить
      e.style.opacity = "0"; // Сделать е полностью прозрачным
      if (oncomplete) oncomplete(e); // Вызвать ф-цию обратного вызова
    }
  }
}

Обе функции, shake() и fadeOut(), принимают необязательную функцию обратного вызова во втором аргументе. Если эта функция указана, она будет вызвана по завершении воспроизведения анимационного эффекта. Элемент, к которому применялся анимационный эффект, будет передан функции обратного вызова в виде аргумента. Следующая разметка HTML создает кнопку, для которой после щелчка на ней воспроизводится эффект встряхивания, а затем эффект растворения:

<button>Встряхнуть и pacтворить</button>

Обратите внимание, насколько функции shake() и fade0ut() похожи друг на друга. Они обе могут служить шаблонами для реализации похожих анимационных эффектов с использованием CSS-свойств. Однако клиентские библиотеки, такие как jQuery, обычно поддерживают набор предопределенных визуальных эффектов, поэтому вам вообще может никогда не потребоваться писать собственные функции воспроизведения анимационных эффектов, такие как shake(), если только вам не понадобится создать какой-нибудь сложный визуальный эффект. Одной из первых и наиболее примечательных библиотек визуальных эффектов является библиотека Scriptaculous, которая предназначалась для работы в составе фреймворка Prototype. За дополнительной информацией обращайтесь по адресу http://script.aculo.us/ и http://scripty2.com/.

Модуль «CSS3 Transitions» определяет еще один способ реализации анимационных эффектов с помощью таблиц стилей, полностью устраняющий необходимость писать программный код. Например, вместо функции fadeOut() можно было бы определить правило CSS, как показано ниже:

.fadeable { transition: opacity .5s ease-in }

Это правило говорит, что всякий раз, когда изменяется непрозрачность элемента с классом «fadeable», это изменение должно протекать плавно (от текущего до нового значения) в течение половины секунды с использованием нелинейной функции перехода. Модуль «CSS Transitions» еще не был стандартизован, но его положения уже реализованы в броузерах Safari и Chrome в виде свойства -webkit-transition. На момент написания этих строк в Firefox 4 также была добавлена поддержка свойства -moz-transition.

Оглавление книги


Генерация: 1.636. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз