JavaScript-библиотеки для создания потрясающей анимации

В финальной части будут описаны различные обратные вызовы (callback-функции), используемые для выполнения функций в зависимости от прогресса анимации. Почти в каждом примере в предыдущих статьях использовались свойства CSS, чтобы показать, как работают различные методы и параметры. Возможно, у вас могло создаться впечатление, что библиотека Anime.js больше подходит для анимации CSS-свойств. В этом уроке вы узнаете, что её также можно использовать для анимации SVG-файлов.

В трёх предыдущих статьях мы разбирали многие функции библиотеки Anime.js. В можно узнать о том, как выбирать целевые элементы; во - о типах параметров, которые используются для контроля задержки и продолжительности анимации; в - как иметь больший контроль над значениями единичных свойств.

Callback-функции

Обратные вызовы используются для выполнения функций, основанных на прогрессе анимации. В Anime.js существует 4 функции обратного вызова: begin , run , update и comlete . Каждая из них запускается в определённое время и принимает объект анимации в качестве своего аргумента.

Функция begin() вызывается, когда анимация начинается. Это значит, что если у анимации есть параметр delay со значением 800 миллисекунд, то begin() будет вызвана только через 800 миллисекунд. Можно проверить, запустилась анимация или нет, используя функцию animationName.begin , которая возвращает true (запустилась) или false (не запустилась).

Run используется для выполнения функции в каждом кадре после запуска анимации. Если нужно выполнить функцию в каждом кадре с самого начала анимации, независимо от параметра delay , то используйте callback-функцию update .

Callback-функция complete похожа на begin , только вызывается она после окончания. Чтобы проверить, завершилась анимация или нет, используйте animationName.complete , как и в случае с begin .

Callback-функцию update мы использовали ещё в для обновления количества сканированных и заражённых файлов. В этой статье мы дополним пример со сканированием, и вы увидите, как работают все callback-функции.

Var filesScanned = { count: 0, infected: 0 }; var scanCount = document.querySelector(".scan-count"); var infected = document.querySelector(".infected-count"); var scanning = anime({ targets: filesScanned, autoplay: false, count: 100, infected: 8, delay: 1000, duration: 2000, easing: "linear", round: 1, update: function(anim) { if (anim.currentTime < 1000) { document.querySelector(".update-cb").innerHTML = "Creating an Index..."; } }, begin: function() { document.querySelector(".begin-cb").innerHTML = "Starting the Scan..."; }, run: function() { scanCount.innerHTML = filesScanned.count; infected.innerHTML = filesScanned.infected; }, complete: function() { document.querySelector(".complete-cb").innerHTML = "Scan Complete..."; } });

В примере выше намеренно была добавлена задержка анимации, чтобы можно было заметить разницу во времени выполнения разных функций обратного вызова. Callback-функция update начинает выполняться сразу после создания объекта анимации.

Сама анимация начинается с задержкой в 1000 миллисекунд, и именно в этот момент срабатывает функция begin , которая показывает пользователю сообщение «Starting the Scan…». В то же время run начинает выполняться и обновлять числовые значения объекта после каждого кадра. После окончания анимации функция обратного вызова complete отображает сообщение «Scan Complete…».

Функции плавности

Функции плавности используются для контроля перехода начального значения свойства в конечное. Эти функции можно определить с помощью параметра easing , который может принимать значения как в виде строк, так и в виде пользовательских координат кривых Безье (в виде массива).

Существует 31 встроенная функция плавности. Одна из них называется linear , остальные 30 состоят из разных вариаций easeIn , easeOut и easeInOut . Класc elastic определяет три функции плавности: easeInElastic , easeOutElastic и easeInOutElastic . Вы можете управлять ими с помощью параметра elasticity . Значение этого параметра может находиться только в диапазоне от 0 до 1000.

Использование easeIn ускоряет изменение значения, начиная с нуля. Это значит, что изменяться оно будет сначала медленно, а в конце - быстро. Скорость изменения в начале равна нулю, а в конце - 1000.

Функция easeOut замедляет изменение значения, начиная с максимальной скорости.

easeInOut увеличивает скорость смены значений в начале и замедляет в конце. Это значит, что в середине анимации скорость будет самой высокой. Следующая вставка показывает разницу между этими функциями плавности:

С помощью anime.easings можно создавать собственные функции плавности. Ниже приведён пример создания пользовательских функций плавности:

Anime.easings["tanCube"] = function(t) { return Math.pow(Math.tan(t * Math.PI / 4), 3); } anime.easings["tanSqr"] = function(t) { return Math.pow(Math.tan(t * Math.PI / 4), 2); } var tanCubeSequence = anime({ targets: ".tan-cube", translateX: "75vw", duration: 2000, easing: "tanCube", autoplay: false }); var tanSqrSequence = anime({ targets: ".tan-sqr", translateX: "75vw", duration: 2000, easing: "tanSqr", autoplay: false });

Анимации на основе SVG-файлов

Во всех связанных с движением анимациях, которые были созданы до этого момента, целевые элементы перемещались по прямой линии. В Anime.js можно перемещать элементы по сложным SVG-контурам с большим количеством кривых с возможностью контроля положения и угла анимируемых элементов на контуре. Чтобы переместить элемент по оси X на контуре, используйте path("x") . Подобным образом элементы можно перемещать по оси Y, используя path("y") .

Если контур не представлен в виде прямой линии, то он почти всегда будет формировать угол относительно основной горизонтальной линии. При вращении любого некруглого элемента анимации общая картинка будет выглядеть более естественно, если элемент будет перемещаться по углу контура. Это можно сделать, установив значение свойства rotate равным path("angle") . Ниже представлен пример кода, который анимирует четыре элемента с разными значениями плавности по SVG-контуру:

Var path = anime.path("path"); var easings = ["linear", "easeInCubic", "easeOutCubic", "easeInOutCubic"]; var motionPath = anime({ targets: ".square", translateX: path("x"), translateY: path("y"), rotate: path("angle"), easing: function (el, i) { return easings[i]; }, duration: 10000, loop: true });

Во вставке ниже видно, что красный квадрат с функцией плавности easeInCubic двигается медленнее всех в начале, но быстрее всех в конце. Похожая ситуация и в случае с оранжевым квадратом - быстрее всего он двигается в начале, но медленнее всех в конце.

Существует возможность анимирования преобразований разных SVG-форм из одной в другую с помощью Anime.js. Единственным условием для преобразования фигур является наличие равного количества опорных точек. Это значит, что треугольники можно преобразовать только в другие треугольники, четырёхугольники - в четырёхугольники и так далее. Попытка преобразования элементов с неравным количеством опорных точек приведёт к резкому изменению формы. Ниже представлен пример трансформаций треугольника:

Var morphing = anime({ targets: "polygon", points: [ { value: "143 31 21 196 286 223" }, { value: "243 31 21 196 286 223" }, { value: "243 31 121 196 286 223" }, { value: "243 31 121 196 386 223" }, { value: "543 31 121 196 386 223" } ], easing: "linear", duration: 4000, direction: "alternate", loop: true });

Одним из наиболее интересных эффектов Anime.js является возможность создания линейных рисунков. Всё, что нужно сделать - предоставить библиотеке контур, который вы хотите использовать для линейного рисунка; предоставить другие параметры, с помощью которых контролируется продолжительность, задержка и плавность. В примере ниже использовалась функция обратного вызова complete , чтобы сделать заливку рисунка якоря из Font Awesome жёлтым цветом.

Var lineDrawing = anime({ targets: "path", strokeDashoffset: , easing: "easeInOutCubic", duration: 4000, complete: function(anim) { document.querySelector("path").setAttribute("fill", "yellow"); } });

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

Var letterTime = 2000; var lineDrawing = anime({ targets: "path", strokeDashoffset: , easing: "easeInOutCubic", duration: letterTime, delay: function(el, i) { return letterTime * i; }, begin: function(anim) { var letters = document.querySelectorAll("path"), i; for (i = 0; i < letters.length; ++i) { letters[i].setAttribute("stroke", "black"); letters[i].setAttribute("fill", "none"); } }, update: function(anim) { if (anim.currentTime >= letterTime) { document.querySelector(".letter-m").setAttribute("fill", "#e91e63"); } if (anim.currentTime >= 2 * letterTime) { document.querySelector(".letter-o").setAttribute("fill", "#3F51B5"); } if (anim.currentTime >= 3 * letterTime) { document.querySelector(".letter-n").setAttribute("fill", "#8BC34A"); } if (anim.currentTime >= 4 * letterTime) { document.querySelector(".letter-t").setAttribute("fill", "#FF5722"); } if (anim.currentTime >= 5 * letterTime) { document.querySelector(".letter-y").setAttribute("fill", "#795548"); } }, autoplay: false });

И мы с пути кривого ни разу не свернем, а надо будет снова пойдет кривым путем - х/ф Айболит 66.

Существует великое множество готовы решений, позволяющих работать с перемещением по Кривыми Безье. В большинстве случаев практического применения готовых решений будет предостаточно. Но самостоятельная имплементация очень полезна для саморазвития, поэтому когда мне понадобилось в одном из проектов создать такую анимацию, я пошел в обход.

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

Итак

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

Кривая Безье названа в честь французского инженера Пьера Безье, который является одним из ее авторов. Кубическая кривая Безье - параметрическая кривая, задаваемая выражением (), состоит из 4 пар значений, где каждая пара - это x и y координаты точек, по которым образуется кривая.

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

Как и в случае рисования кривой, так и в случае движения по кривой участвует одна и та же формула, которую можно найти на Википедии :

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

Делаем имплементацию

Предположим, мы планируем дойти от точки до точки двухсегметной кривой за четыре секунды с частотой кадров 12 fps. Тогда д елим секунду на 12 и получаем отрезок времени, которую принимаем за единицу анимации (фрейм).

Var frameDuration = 1000/12;

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

// Общее_время_в_мс / (1000_миллисекунд/количество_кадров)
var framesCount = 4000/frameDuration;

Зная общее количество кадров, мы, используя курсор текущего кадра, можем получить значение прогресса анимации t, просто поделив текущий кадр на общее количество кадров анимации;

Var t = currentFrame/framesCount;

Таким образом, у нас е сть значение начальной точки - P0x, P0y; первой контрольной точки - P1x, P1y; второй контрольной точки - P2x, P2y; и завершающей точки - P3x,P3y, и значение прогресса анимации t . Остается подставить всё это в формулу

и мы получаем нужные нам координаты объекта в любой момент времени (t).

X = (Math.pow((1 - t), 3) * P0x) +
(3 * Math.pow((1 - t), 2) * t * P1x) +
(3* (1 - t) * Math.pow(t, 2) * P2x) +
(Math.pow(t, 3) * P3x) y = (Math.pow((1 - t), 3) * P0y) +
(3 * Math.pow((1 - t), 2) * t * P1y) +
(3* (1 - t) * Math.pow(t, 2) * P2y) +
(Math.pow(t, 3) * P3y)

Поворот к вектору движения

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

Что бы узнать угол вектора, нам нужно найти угол, который образуют две ближайших точки на кривой, по отношении к друг другу. Т.е. мы берем координаты текущего положения объекта, и координаты положения объекта в предыдущем фрейме. Назовем их x0,y0 и x,y .

Фактически x0-x, y0-y -  это две стороны треугольника, зная которые мы можем найти угол по формуле решения треугольника по двум сторонам и прямому углу между ними.

c=sqrt(a2 + b2) A=arccos((b2+c2-a2)/2bc)

Но только вот какая незадача: угол вектора может варьироваться от 0 до 360, а угол в треугольнике у нас от 0 до 179,9. Нам нужно найти угол между двумя векторами:

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

    Когда направляющая смотрит снизу вверх, слева направо, искомый угол нашего воображаемого треугольника находит внизу слева. В таком случае стороной a становится разница между x и x0 , а b разница между y и y0 . Результативный угол мы получаем через сумму квадратов всех сторон, деленных на двойную сумму катета и гипотенузы.

    A=arccos((b2+c2-a2)/2bc)

    Но когда вектор смотрит слева на право, сверху вниз, наши стороны треугольника меняются местами. В этом случае стороной a становится разница между y и y0 , а b x и x0 соответственно. Т.е. всё наоборот от предыдущего случая. Но решение остается таким же.

    Всё бы ничего, но когда направляющая начинает движение сверху вниз, слева на право, предыдущая схема перестает работать. Во-первых мы снова меняем стороны местами, а искомый угол становится противоположным. И находим его уже по вспомогательной формуле 90-$A, кроме того прибавляем 90, что бы наш объект смотрел в правильном направлении.

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

    Плюс ко всему нужно не забывать, что существует варианты нулевой длинны сторон, что приведет к ошибке расчетов. Поэтому важно не забыть проводить проверку одного из 4-х направлений движений, и кроме того проверку на нулевую длину сторон, при значениях угла 0, 90, 180 и 270.

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

    Парсинг Svg

    Осталось сделать так, что бы скрипт, создающий анимацию, мог принимать в качестве траектории сразу SVG путь . Мне не удалось найти ни одного качественного конвертера SVG-PATH в CUBIC-BEZIER POINTS, поэтому написал собственную реализацию парсинга SVG пути в javascript-читабельный формат.

    В этот процесс я не стану углубляться, скажу лишь, что английская литера M в устанавливает начало линии, далее команды s/S (smooth curveto) или c/C (curvet) позволяют создавать контрольные точки, причем значения могут быть как абсолютными, так и относительными. И хотя в SVG PATH типов команд достаточно много (M, L, H, V, C, S, Q, T, A, Z), я изучил и создал парсер только для 3-х из них. Результатом 6 часовых стараний стала функция svgPathToCubicBezierPoints , которая конвертит путь SVG в в массив точек в процентном эквиваленте.

    Заключение

    Вот, пожалуй и все. Если вам просто необходимо создать анимацию, основанную на движениях на кривым Безье, то не стоит изобретать велосипед, а стоит воспользоваться существующими библиотеками, такими как Raphael или .

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

    Краткий обзор перспективных библиотек и плагинов JavaScript для анимации.

    1. Scripty2

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

    Пример использования

    Включите строку в ваш код HTML:

    Следующие строки используются на демо странице scripty2.

    //Для эффекта змеи на картах в демонстрации document.observe("cards:snake", function(){ var d = 20; names.sortBy(Math.random).each(function(card, index){ $(card).morph("margin-left:"+[-300,300,-150,150]+"px;margin-top:"+ (272+(index-names.length/2)*d)+"px;left:371px;z-index:"+index, { propertyTransitions: { marginLeft: "mirror", marginTop: "bouncePast", left: "swingFromTo", zIndex: zIndexTransition }, duration:2 }).morph("margin-top:272px;left:"+(371+(index-names.length/2)*d)+"px", { propertyTransitions: { marginTop: "easeInCirc", left: "linear" }, duration:1, delay:index/15 }).morph("margin-top:"+(272-(index-names.length/2)*d)+"px;left:371px", { propertyTransitions: { marginTop: "easeOutCirc", left: "linear" }, duration:1 }); }); }); (function(){ document.fire("cards:snake"); }).delay(2); })();

    Это мощная, но лёгкая в использовании библиотека, которая даёт возможность добавлять впечатляющие анимации веб сайтам без ущерба для стандартов или совместимости. При размере около 25 Кб, пакет jsAnim представляет собой серьёзный инструмент для такого маленького приложения.

    Пример использования

    Включите следующие строки в ваш код:

    Создайте файл main.js и скопируйте в него следующий код.

    Var manager = new jsAnimManager(); aniMe = document.getElementById("animateMe"); aniMe.style.position = "relative"; var anim = manager.createAnimObject("animateMe"); anim.add({property: Prop.left, to: 500, duration: 2000});

    Простой плагин, в котором есть только два ключевых метода, sprite() и pan() . Оба метода предназначены для простой анимации свойства CSS фонового изображения элемента. Разница, между данными двумя методами заключается в том, что изображение ‘sprite’ содержит два или более ‘кадра’ анимации, а изобюражение ‘pan’ является одним непрерывным изображением, которое повторяет переходы слева на право. Обычно, в самом простом случае, можно использовать png файлы для этого (с или без прозрачности). Вы можете использовать прозрачный gif для Internet Explorer 6, хотя это и будет выглядеть не очень хорошо. Ваш HTML элемент должен иметь нужный размер, но фоновое изображение обычно бывает больше HTML элемента и метод sprite() изменяет положение фонового изображения в соответствии с HTML элементом.

    Пример использования

    Здесь приведён простой пример. Следующий метод анимирует одни из спрайтов птиц, которые летают по странице. Метод ‘sprite’ собирает три кадра в png изображение с прозрачностью, в котором каждый кадр располагается сторона к стороне:

    Теперь нужно просто создать div с именем ‘bird’, задать ему правильный размер (180×180 px в данном случае), и анимировать его методом sprite() . Две опции, которые надо установить — это ‘fps’ (кадров в секунду) и ‘no_of_frames’, то есть три кадра для нашего изображения:

    $("#bird").sprite({fps: 12, no_of_frames: 3});

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

    $("#bird").sprite({fps: 12, no_of_frames: 3}).activeOnClick().active(); $("body").flyToTap();

    Метод active() делает данный спрайт активным спрайтом при загрузке страницы, иначе спрайт с activeOnClick() станет активным только после того как на него нажмут.

    Метод $("body").flyToTap() отслеживает нажатие на странице, после чего текущее движение завершается, спрайт перемещается в месту нажатия. Через несколько секунд начинает использоваться метод случайных перемещений.

    4. $fx()

    $fx() - это маленькая самодостаточная библиотека Javascript для анимирования элементов HTML. Она не требует никаких других библиотек для работы и должна хорошо работать вместе с другими библиотеками (Prototype, JQuery, Moo tools, и так далее)

    $fx() позволяет изменять любое свойство CSS на протяжении всего времени анимирования, что позволяет проигрывать анимационные эффекты последовательно, то есть так, как нужно вам. Также $fx() обрабатывает управление таймером и делает процесс анимации простым и изящным.

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

    Пример применения

    Как добавить и анимировать один простой эффект

    Первое, нам нужен элемент. Подойдет любой элемент (допустим, : ). Затем можно вызвать $fx() и передать ссылку на элемент.

    $fx("myDiv")

    Затем, добавляем эффекты, вызывая $fxAdd(...) .

    $fx("myDiv").fxAdd({type: "fontSize", from: 12, to: 72, step: 1, delay: 20});

    Теперь запускаем!

    $fx("myDiv").fxAdd({type: "fontSize", from: 12, to: 72, step: 1, delay: 20}).fxRun(null,-1);

    5. moo.fx

    moo.fx - эти суперлёгкая и ультрамаленькая библиотека эффектов JavaScript, которая используется в рабочей среде prototype.js или mootools .

    Она очень проста в использовании, молниеносно быстра, кросс-браузерна, совместима со стандартами, обеспечивает контроль модификации любого свойства CSS любого элемента HTML, включая цвета, в неё встроена проверка, которая не даёт пользователю возможности оборвать выполнение эффекта многочисленными, сумасшедшими нажатиями кнопки мыши. Оптимизированная для создания как можно меньшего размера кода, новая moo.fx предоставляет возможность создать любой вид эффектов.

    Пример использования

    Приведённый ниже код используется для создания перетаскиваемого шарика на домашней странице moo.fx .

    Var ball = $("header").getElement("h1"); var ballfx = new Fx.Styles(ball, {duration: 1000, "transition": Fx.Transitions.Elastic.easeOut}); new Drag.Base(ball, { onComplete: function(){ ballfx.start({"top": 13, "left": 358}); } });

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

    Raphael использует SVG и VML в качестве основы для создания графики. Таким образом, каждый графический объект, который будет создан, также является DOM объектом, и к нему можно привязать обработчик события JavaScript или модифицировать при дальнейшей работе. Основная задача Raphael — сделать работу с векторной графикой кросс-браузерной и лёгкой в использовании.

    Пример использования

    Демонстрация анимации , сделанной с помощью этой чудесной библиотеки.

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

    // Эллипс (function () { r.circle(40, 90, 20).attr(dashed); r.ellipse(140, 90, 20, 10).attr({fill: "none", stroke: "#666", "stroke-dasharray": "- ", rotation: 45}); var el = r.ellipse(40, 90, 20, 20).attr({fill: "none", stroke: "#fff", "stroke-width": 2}), elattrs = [{ry: 10, cx: 140, rotation: 45}, {ry: 20, cx: 40, rotation: 0}], now = 0; r.arrow(90, 90).node.onclick = function () { el.animate(elattrs, 1000); if (now == 2) { now = 0; } }; })();

    На домашней странице библиотеки можно найти демонстрацию других эффектов анимации.

    Это векторный OpenSource движок для анимации в графических элементах HTML5. Burst обеспечивает подобную FLASH функциональность веб приложений и основанную на слоях, как в After Effects, систему анимации. Burst использует очень компактное ядро на JavaScript, что позволяет анимациям быстро загружаться, а процесс может быть под контролем с помощью простых методов JavaScript.

    Пример использования

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

    Burst.timeline("party", 0, 800, 1, false) .shape("balloon", "balloon3.svg", "svg", 0, 0, .5, 0) .shape("cake", "cake2.svg", "svg", 0, 0, 1, 0) .track("left") .key(1, -320, "easeInOutQuad") .key(200, 0) .shape("balloon") .track("top") .key(0,320) .key(100,320) .key(800, -320) .track("left") .key(0,0) .key(100, 0, "easeOutBounce") .key(800,120); Burst.start("party;", function(){ alert("Time for bed!"); }); Burst.play();

    8. Canvas 3d JS Library (C3DL)

    Canvas 3D JS Libary (C3DL) — библиотека JavaScript, которая облегчает создание 3D приложений, использующих WebGL. Она обеспечивает набор классов для 3D математики, объектов и сцен, который делает WebGL более доступным для разработчиков, встраивающих 3D контент в свои приложения, но которые не хотят глубоко погружаться в изучение 3D математики для достижения своих целей.

    Этот материал посвящён анимации на HTML страницах, о производительности анимации, перспективности использования, а так же анимации в HTML5 мобильных приложениях и играх.

    Javascript анимация

    Первым делом начнём с рассмотрения JS анимации на HTML странице. Анимация на яваскрипте может проводиться либо с setInterval, с помощью которой можно задать статично кадры в секунду, либо с помощью обычной функции которая в конце вызывает саму себя ну или с window.requestAnimationFrame.

    Вот простейшая логика работы анимации в JS:

    var el=document.getElementById("elem");
    mar=10; //статичные начальные данные
    //цикл начинается
    mar=mar+1;
    el.style.marginLeft=mar+"px";
    //цикл заканчивается

    Прелесть JS в том что можно удобным способом расширить нативный инструментарий и использовать например анимацию на jQuery или использовать Velocity . Это существенно ускоряет производительность. Однако в частности Velocity использует JS не совсем для анимации, так ака само анимирование производиться там в CSS о котором речь пойдёт ниже.

    SVG анимация

    Нельзя не упомянуть о SVG анимации. Сама она очень хороша, но в мобильных браузерах она не работает. Вернее работает только SMIL на Андроид 3.0-выше. Как бы неприятно было это говорить сам SVG работает в методе WebView, но всё что связано с анимацией в этом тэге увы...

    Везде где она работает - она показывает хорошую производительность. Убедитесь сами.

    • Сергей Савенков

      какой то “куцый” обзор… как будто спешили куда то