Анимация

Анимации в CSS безусловно поднимает планку качества нового поколения приложений HTML. В этой статье интересные демонстрации подчеркивающее потенциал анимации в CSS и как обращаться с добавленным резервом JavaScript.

Оглавление:
  1. Анимация CSS3
  2. Вот как работает анимация в CSS
  3. Нелинейная анимация
  4. Остановить анимацию
  5. Еще о анимации
  6. Поддержка браузерами
  7. Анимация с резервом JavaScript

CSS3 Animations это расширение CSS3 Transitions, рекомендую сначала прочитать статью: «Переходы и анимация». Для создания анимации CSS3 пользуйтесь инструментом CSS3 Animations.

Пример анимации называется “StarWars AT-AT”. В примере анимация применяется для разных частей транспорта, для пользователей пользующихся браузерами не поддерживающие анимации CSS3 подключен резервный JavaScript.

этот пример анимации был успешно протестирован в IE10, Chrome 15, Firefox 8, IPad 2 на мобильных Windows Phone и резервный JavaScript для IE9. По неизвестной причине, он ведет себя странно в Опере 11,50 но прекрасно работает в 11,60.

К началу

Анимация CSS3

Сначала посмотрим обзор свойств CSS для создания анимации. CSS3 Animation работает в основном с теми же свойствами что и CSS3 Transition.

Свойства CSS для создания анимации
  • color: интерполированное через красный, зеленый, синий и альфа-компоненты.
  • length: интерполированное как действительные числа.
  • percentage: интерполированное как действительные числа.
  • integer: интерполированное через дискретные шаги (целых чисел). Интерполяции происходят в реальном пространстве и преобразуется в целое число с помощью кода floor().
  • number: интерполированное как реальные числа с плавающей запятой.
  • transform list: см. спецификации: «CSS3 преобразование».
  • rectangle: интерполированное через значения x, y, width и height
  • visibility: интерполированное через дискретный шаг. Интерполяция происходит между 0 и 1, где 1 — visible, а все остальные — hidden.
  • shadow: интерполированное через цвет, x, y и blur компонентов (рассматривая их как цвет). В случае когда имеются тени, короткий список дополняется в конце с тенью, цвет-прозрачный, и вся длина (x, y, размытие) — 0.
  • gradient: интерполированное через позиции и цвета каждой остановки. Они должны иметь одинаковый тип (radial или linear) и то же количество остановок для того, чтобы быть анимацией.
  • paint server (SVG): интерполяция поддерживается только между: градиент в градиенте и цвет в цвете. Затем работы, как указано выше.
  • space-separated list of above: Если эти списки имеют одинаковое количество элементов, для каждого элемента в списке, используя вышеприведенные правила. В противном случае, без интерполяции.
  • a shorthand property: Если все части анимационные, то интерполяция производится так как если бы каждое свойство было указано отдельно.
Значение свойств для анимации CSS3
  • background-color (color)
  • background-image (only gradients)
  • background-position (percentage and length)
  • border-bottom-color (color)
  • border-bottom-width (length)
  • border-color (color)
  • border-left-color (color)
  • border-left-width (length)
  • border-right-color (color)
  • border-right-width (length)
  • border-spacing (length)
  • border-top-color (color)
  • border-top-width (length)
  • border-width (length)
  • bottom (length and percentage)
  • color (color)
  • crop (rectangle)
  • font-size (length and percentage)
  • font-weight (number)
  • grid-* (various)
  • height (length and percentage)
  • left (length and percentage)
  • letter-spacing (length)
  • line-height (number, length and percentage)
  • margin-bottom (length)
  • margin-left (length)
  • margin-right (length)
  • margin-top (length)
  • max-height (length and percentage)
  • max-width (length and percentage)
  • min-height (length and percentage)
  • min-width (length and percentage)
  • opacity (number)
  • outline-color (color)
  • outline-offset (integer)
  • outline-width (length)
  • padding-bottom (length)
  • padding-left (length)
  • padding-right (length)
  • padding-top (length)
  • right (length and percentage)
  • text-indent (length and percentage)
  • text-shadow (shadow)
  • top (length and percentage)
  • vertical-align (keywords, length and percentage)
  • visibility (visibility)
  • width (length and percentage)
  • word-spacing (length and percentage)
  • z-index (integer)
  • zoom (number)
К началу

Вот как работает анимация в CSS

В файле .css пишем свойства:

@keyframes name_of_the_animation {
  from {
   property_to_animate: initial_value;
  }
  50% {
     property_to_animate: intermediate_value;
  }
  to {
    property_to_animate: final_value;
  }
}

или

@keyframes name_of_the_animation {
  0% {
   property_to_animate: initial_value;
  }
  50% {
     property_to_animate: intermediate_value;
  }
  100% {
    property_to_animate: final_value;
  }
}

В этой анимации определено 3 шага: первый 0 второй 50 и последний 100%. Нужно установить как минимум 2-ва значения 0% и 100% для создания правильной анимации. После этого можно добавить ключевые кадры столько сколько нужно, но только между 0 и 100% для обработки именно различных действий вашей анимации.

После того как определение готово, с помощью классического селектора CSS3 вам понадобится также настроить опции анимации.

Пример для общего блока:

#id_of_the_html_element {
animation-name: name_of_the_animation;
animation-duration: number_of_seconds s;
animation-iteration-count: number | infinite;
}

Чтобы лучше понять рассмотрим реальный образец. Прежде всего спецификация анимации CSS3 находится в стадии разработки, вам нужно будет использовать префиксы для браузеров. Для примера используется IE10 поэтому в качестве образца префикс ms. Теперь посмотрим, как башня AT-AT движется.

Вот значения анимации:

@-ms-keyframes rotate-skull {
    0% {
        -ms-transform: rotate(0deg)
    }
    25% {
        -ms-transform: rotate(15deg)
    }
    50% {
        -ms-transform: rotate(-5deg)
    }
    55% {
        -ms-transform: rotate(0deg)
    }
    75% {
        -ms-transform: rotate(-10deg)
    }
    100% {
        -ms-transform: rotate(0deg)
    }
}

У нас есть 6 шагов (0, 25, 50, 55, 75 & 100%) они работают как 2D преобразования для изменения искажения.

Затем анимация имеет три правила:

#skull {
    -ms-animation-name: rotate-skull;
    -ms-animation-duration: 7s;
    -ms-animation-iteration-count: infinite;
}

Элемент div имеет атрибут id="skull" для него мы применили анимацию под названием rotate-skull. Анимация повторяется бесконеяно через каждые 7s.

Вот живой пример, если ваш браузер поддерживает анимации CSS3:

Можно написать это правило покороче, используя сокращение свойст анимации:

#skull {
    -ms-animation: rotate-skull 7s infinite;
}

Анимация будет запускаться при соответствующем правиле. Вы можете остановить анимацию с помощью JavaScript или запустить через CSS3 с классами указанными в теге.

К началу

Нелинейная анимация

Если вы хотите нелинейную анимацию можно использовать свойство animation-timing-function или смешивать типы временных функций в каждом ключевом кадре.

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

Поддерживаются следующие функции:

  • linear: Постоянная скорость
  • cubic-bezier : скорость будет рассчитываться в соответствии с кривой Безье третьего порядка определяется двумя контрольными точками: P0 и P1 (так что вам придется определить 4 значения здесь: p0x, P0y и P1x, P1y.
  • ease: скорость будет рассчитываться с кубическим Безье (0,25, 0,1, 0,25, 1)
  • ease-in: скорость будет рассчитываться с кубическим Безье (0.42, 0, 1, 1)
  • ease-inout: скорость будет рассчитываться с кубическим Безье (0.42, 0, 0,58, 1)
  • пease-out: скорость будет рассчитываться с кубическим Безье (0, 0, 0.58, 1)

Инструмент моделирования на чистом JavaScript написан программистом David Catuhe чтобы показать влияние каждой функции времени. С помощью мыши вы можете редактировать кривую.

Этот инструмент SVG поддерживается Firefox, Chrome, Opera и 11,60 IE9/10. Он не будет работать должным образом в опере 11,50 и Safari на IPad.

Если ваш браузер поддерживает анимации CSS3, давайте теперь посмотрим простой пример использования easing functions to animate a canvas tag (функции замедления анимации тегом canvas) содержащие спрайты.

Вот код анимации который будет использоваться для демонстрации:

@-ms-keyframes demo {
    from {
    -ms-animation-timing-function: ease;
    -ms-transform: translateX(0px);
    }
    50% {
    -ms-animation-timing-function: ease-in;
    -ms-transform: translateX(300px);
    }
    to {
    -ms-animation-timing-function: ease-inout;
    -ms-transform: translateX(900px);
    }
}

#testCanvas
{
    -ms-animation-delay: 0s;
    -ms-animation-duration: 6s;
    -ms-animation-iteration-count: infinite;
    -ms-animation-name: demo;
}

С префиксами для браузеров будет работает в Google Chrome и Mozilla Firefox:

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

Если вы хотите узнать больше о анимации canvas, смотрите запись «Анимация фона»

К началу

Остановить анимацию

Свойство animation-delay просто запускает анимации до начала выполнения через некоторое время после его применения.
События JavaScript
Событие events может быть запущено во время анимации в браузере, название зависит от браузера:

  • Chrome: webkitAnimationEnd
  • Firefox: mozAnimationEnd
  • Internet Explorer: MSAnimationEnd

Действия выводят следующую информацию:

  • animationName: название анимации вызывающее событие
  • ElapsedTime: время запуска анимация (в секундах)

Пример для IE10:

elementToAnimate.addEventListener("MSAnimationEnd", function () {
    alert("анимация завершилась!");
}, false);
К началу

Еще о анимации

CSS3 анимация действительно полезна по 2-вум основным причинам:

  • Аппаратное ускорение: анимация большую часть времени непосредственно обрабатывается GPU и может производить плавный результат. Это очень интересный подход для мобильных устройств.
  • Разделение кода и дизайна: Я знаю что есть некоторые дебаты по этому вопросу, но есть мнение что веб-разработчики не должны знать всё о анимации. Так же дизайнер или художник не должен знать всё о JavaScript. CSS3 предоставляет возможность дизайнерам создавать анимации с их классическими инструментами.
К началу

Поддержка браузерами

Таблица поддержки браузерами: “Анимация”

Для анимации в CSS3 необходимо использовать префиксы для браузеров.

что делать с браузерами, которые не поддерживают эту новую функцию?

Первый вариант ничего не делать. Пользователь будет видеть только статическое изображение. Второй вариант, применить библиотеку JavaScript Modernizr или другую подобную. Это то что мы обычно называем запасной механизм.

Для образца AT-AT специально написана библиотека JavaScript предназначена именно для этого примера.

К началу

Анимация с резервом JavaScript

Анимация — это серия переходов кадров.

Вот основная часть библиотеки:

// Анимация объектов
// Это нужно, HTML целевой элемент, имя анимации, ее продолжительность & iteration  и
// кадры, содержащихся объектов в массиве
// Просмотреть анимацию просто как последовательность переходов сыграл определенное количество раз
ANIMATIONSHELPER.animation = function (target, name, duration, iterationcount, keyframes) {
    // сохранение значений свойств объектов
    this.name = name;
    this.duration = duration;
    this.iterationcount = iterationcount;
    this.target = target;

    var elapsedtime = 0;
    var keyframeduration = 0;
    var elapsedtime = 0;

    // Трансформация доля каждого ключевого кадра в Duration (продолжительность)
    for (var i = 0; i < keyframes.length; i++) {
        keyframeduration = ((keyframes[i].percentage * duration) / 100) - elapsedtime;
        keyframes[i].duration = keyframeduration;
        elapsedtime += keyframeduration;
    }

    this.currentTransition = { isPlaying: false };
    this.keyframes = keyframes;
    this.keyframesCount = keyframes.length;
    this.currentKeyFrameIndex = 0;

    // NextTransition () функция возвращает следующий переход к бежать
    // на основе текущего кадра, чтобы играть
    this.nextTransition = function (keyframe, ease, customEaseP1X, customEaseP1Y, customEaseP2X, customEaseP2Y) {
        var properties = [];
        var finalValues = [];
        var transition;

        // По сравнению с первоначальным TRANSITIONSHELPER Давида Catuhe
        // Нам нужен специальный код, чтобы играть с CSS3 2D свойства Преобразования значения
        if (keyframe.propertyToAnimate === "transform") {
            for (var i = 0; i < keyframe.transformType.length; i++) { 
                 properties.push(keyframe.transformType[i].type); 
            if (keyframe.transformType[i].type == "rotate") { 
                finalValues.push({ deg: keyframe.transformType[i].value1 }); 
            } else { 
                finalValues.push({ 
                x: keyframe.transformType[i].value1, 
                y: keyframe.transformType[i].value2 }); 
            } 
        } 
       // Create a new transition 
        transition = { 
           name: this.name + this.currentKeyFrameIndex, 
           target: this.target, 
           properties: properties, 
           finalValues: finalValues, originalValues: 
           ANIMATIONSHELPER.extractValues(target.style[ANIMATIONSHELPER.currentTransformProperty], this.name), 
           duration: keyframe.duration, 
           startDate: (new Date).getTime(), 
           currentDate: (new Date).getTime(), 
           ease: 
             ease, 
             customEaseP1X: customEaseP1X, 
             customEaseP2X: customEaseP2X, 
             customEaseP1Y: customEaseP1Y, 
             customEaseP2Y: customEaseP2Y, 
             isPlaying: true, 
          type: "transform" 
        }; 
        return transition; 
        } 
        
        // Если это классический собственности на животный, мы используем более или менее TRANSITIONSHELPER как есть 
        else { return TRANSITIONSHELPER.transition(
            this.target, 
            keyframe.propertyToAnimate, 
            keyframe.value, 
            keyframe.duration, 
            TRANSITIONSHELPER.easingFunctions.linear); 
        } }; 

       // каждый анимации объект имеет отметьте функцию 
       // которые будут вызываться каждые 17 мс (к целевой 60 кадров / с) 
       // Этот Тикер является мониторинг текущего состояния, переход и 
       // создать новый переход, как только догорит старая/dead 
       this.tick = function () { if (this.iterationcount > 0) {
            if (!this.currentTransition.isPlaying) {
                this.currentTransition = this.nextTransition(this.keyframes[this.currentKeyFrameIndex], ANIMATIONSHELPER.easingFunctions.linear);
                // Мы, используя наши собственные глобальные Тикер только для 2D преобразований
                // В противном случае, мы используем один из библиотеки TRANSITIONSHELPER
                if (this.currentTransition.type === "transform") {
                    ANIMATIONSHELPER.currentTransitions.push(this.currentTransition);
                }
                this.currentKeyFrameIndex++;

                // Мы до последнего ключевого кадра (100%). Мы снова начинать с начала
                if (this.currentKeyFrameIndex >= this.keyframesCount) {
                    this.currentKeyFrameIndex = 0;
                    this.iterationcount--;
                }
            }
        }
    };
};

Первая часть кода итерации каждого кадра, чтобы вычислить точный срок указанный на каждый процент. Определим nextTransition(), который будет динамически создавать следующий переход, чтобы двигаться на основе текущего индекса в коллекции ключевых кадров. В конце концов, у нас есть tick() который будет следить за текущим состоянием перехода. После перехода он запрашивает следующий переход, нажмите его в стек переходов для воспроизведения и перемещения индексов.

Этот tick() вызывается благодаря такому коду:

ANIMATIONSHELPER.launchAnimation = function (animation) {
    // Launching the tick service if required
    if (ANIMATIONSHELPER.tickIntervalID == 0) {
        ANIMATIONSHELPER.tickIntervalID = setInterval(ANIMATIONSHELPER.tick, 17);
    }

    // Little closure to launch the tick method on the appropriate animation instance
    setInterval(function () { animation.tick(); }, 17);
};

В конце концов у нас есть код, который помогает нам создать ключевые кадры:

// Object to build a new generic keyframe (not working on the CSS3 2D Transform properties thus)
ANIMATIONSHELPER.keyframe = function (percentage, propertyToAnimate, value) {
    this.percentage = percentage;
    this.propertyToAnimate = propertyToAnimate;
    this.value = value;
};

//Objects to build specific rotation keyframes
ANIMATIONSHELPER.rotationkeyframe = function (percentage, value) {
    this.percentage = percentage;
    this.propertyToAnimate = "transform";
    this.transformType = [];
    this.transformType.push(new ANIMATIONSHELPER.transformType("rotate", value));
};

Теперь свяжем простой пример CSS3 анимации башни АТ-АТ с этим скриптом:

// number of times you'd like the animations to be run
var iterationsNumber = 100;

var skullElement = document.getElementById("skull");
var keyframes = [];
keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(25, 15));
keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(50, -5));
keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(55, 0));
keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(75, -10));
keyframes.push(new ANIMATIONSHELPER.rotationkeyframe(100, 0));

var animation1 = new ANIMATIONSHELPER.animation(skullElement, "rotate-skull", 7000,
iterationsNumber, keyframes);

ANIMATIONSHELPER.launchAnimation(animation1, ANIMATIONSHELPER.easingFunctions.linear);

И вот результат, который теперь будет работать в любом браузере:

Самый первый образец продемонстрирован в начале этой статьи использует Modernizr для проверки поддержки анимации CSS3. Если нет поддержки, то он подключается код который будет имитировать ключевые кадры определенных в файле master.css, moz master.css и ms-master.css:

// Checking if CSS3 animations is supported
if (!Modernizr.cssanimations) {
    // if so, we can use our JS fallback library
    supportElement.innerHTML = "CSS3 Animations are not supported";
    LoadJSAnimationsFallback();
}
else {
    // if CSS3 animation is supported, we have nothing to do.
    // The *master.css stylesheets will be automatically applied & used.
    supportElement.innerHTML = "CSS3 Animations are supported";
}

Функция LoadJSAnimationsFallback() определена в jsfallback-master.js и содержит все ключевые кадры. При таком подходе дизайнеру нужно переписать все правила используя библиотеку. Другой подход может быть для разбора одного из файла CSS с помощью вызова XHR и динамично вызывать в библиотеку JavaScript. Это требует больше работы чем переопределить спецификацию CSS3 анимации.

Теперь у вас есть идеи для создания резервного механизма и поддержки браузерами новейшие спецификации CSS3.

Вы можете скачать файлы основного образца, содержащий версии unminified animationsHelper.js, transitionsHelper.js, jsfallback-master.js JavaScript файлов, а также различные CSS3 declinaison файлы для основных поставщиков префиксов.