Js анимация движения. CSS3-анимации и новый javascript-метод Animate(). Поворот к вектору движения

Аннотация: Простой пример: метод угасания желтого цвета. Анимация с помощью библиотек JavaScript. Более сложный пример: перемещение и изменение размера. Переходы CSS.

Принцип в основе угасания состоит в том, что задается желтый цвет фона элемента угасания, а затем, за некоторую последовательность шагов его цвет возвращается к исходному. Поэтому, если исходный цвет фона был красный, то затем цвет задается желтым, затем оранжево-желтым, затем оранжевым, затем красно-оранжевым, и затем красным. Число использованных шагов определяет, насколько плавно происходит изменение цвета, а время между шагами определяет, как долго продолжается изменение цвета. При изменении цвета можно использовать полезный факт из CSS : цвет можно определить как тройку обычных чисел или как шестнадцатеричную строку. Поэтому #FF0000 (красный цвет) можно определить также как rgb(255,0,0) . Изменение от желтого цвета до красного за пять шагов означает, поэтому, переход от rgb(255,255,0) (желтый) к rgb(255,0,0) за пять следующих шагов:

rgb(255,255,0) rgb(255,192,0) rgb(255,128,0) rgb(255,64,0) rgb(255,0,0)

Более сложный пример: перемещение и изменение размера

Хотя метод угасания желтого цвета демонстрирует анимацию, он несколько скучен. Когда большинство людей представляют себе анимацию, они обычно имеют в виду движение. Интересный прием предупреждения пользователя о том, что что-то произошло, не прерывая его рабочего процесса , состоит в немодальном сообщении. Вместо вывода диалогового окна alert() , которое требует от пользователя щелчка на OK , прежде чем он сможет продолжить, поместите сообщение просто в плавающий div на странице, который ненавязчиво остается там, пока не получит подтверждение. Второй достаточно интересной вещью затем может быть предоставление пользователю возможности вернуться к сообщению, для которого он подтвердил желание прочитать его еще раз. Поэтому давайте реализуем плавающее сообщение, которое, после щелчка на нем, "схлопывается" в угол экрана, и затем по щелчку может быть снова восстановлено. Вы можете посмотреть небольшую демонстрацию такого "схлопывающегося сообщения" (http://dev.opera.com/articles/view/javascript-animation/moving_messages_jq.html), чтобы понять общую идею.

Если вы делаете какую-то серьезную анимационную работу, или какую-то серьезную работу с JavaScript, почти всегда стоит использовать библиотеку JavaScript. Это позволит создать требуемое представление для пользователей, не беспокоясь о математических тонкостях, требуемых для выполнения анимации. (Познакомившись с представленным выше первым примером, вы знаете теперь, как выполнить математические вычисления и как использовать setInterval , но вы сохраните время и собственные силы, используя готовые решения.)

Приведенный выше демонстрационный пример использует для работы библиотеку jQuery (http://jquery.com/), но как упоминалось, большинство библиотек предоставляют достаточно похожую концепцию анимации, и поэтому вы сможете реализовать принципиальную часть, используя предпочитаемую библиотеку. По существу, необходимо сделать следующее:

  • Показать плавающее сообщение в центре экрана
  • Когда на нем производится щелчок:
  • Переместить его горизонтальную позицию в крайнее правое положение
  • Переместить его вертикальную позицию вверх
  • Задать его ширину равной 20px
  • Задать его высоту равной 20px
  • Сделать его плотность равной 20%, так что оно становится почти прозрачно и скрыть в нем текст
  • Когда выполняется щелчок на этой "мини"-версии сообщения, восстановить его в центре экрана (т.е., обратное тому, что мы делали для его сжатия) и чтобы пользователь получил четкую картину того, что произошло с его сообщением, переход от полноразмерного сообщения к мини-сообщению должен быть анимирован (чтобы они видели, что сообщение "сжалось" в угол окна).
  • Выполнить анимацию с помощью jQuery очень легко: используйте просто функцию . animate () и предоставьте желательный конечный результат анимации (и как долго она должна выполняться):

    $(ourObject).animate({ width: "20px", height: "20px", top: "20px", right: "20px", marginRight: "0px", opacity: "0.2" }, 300);

    Функция получает ourObject и, за 300 миллисекунд, заменяет его ширину и высоту на 20px, его верхнюю и правую позиции на 20px, его свойство стиля margin-right на 0px, и его плотность (в браузерах, которые поддерживают плотность изображения) на 20%. Затем это просто вопрос программирования в стиле

    Под термином «анимация» мы чаще всего понимаем мультипликационные фильмы - с детства любимые нами «мультики». Но если заглянуть в толковый словарь, то мы узнаем, что в переводе с французского оно означает «оживление», «одушевление». И вот тут-то оказывается, что это значение удивительно точно подходит не только к киноиндустрии, но и к веб-технологиям.

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

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

    Говоря о технологиях, обеспечивающих использование анимации в веб-страницах , можно выделить несколько но, пожалуй, ни одна из них не является настолько мощной как . Еще несколько лет назад технология Flash-анимации была грозным конкурентом и очень популярной. Но сейчас, похоже, ее лучшие годы позади и она постепенно вытесняется со страниц сайтов более мощными и гибкими Java-скриптами. И если вы решили всерьез использовать анимацию на своем сайте , то ставку следует делать именно на JavaScript. А чтобы сделать разумный выбор библиотеки я и сделал сегодняшний обзор.

    Dynamics.jsНачну я, пожалуй, с Dynamics.js . Это серьезная и мощная библиотека, позволяющая создавать физически достоверную анимацию (как, например, гармонические затухающие колебания точки на главной странице сайта). Библиотека способна управлять и свойствами любого DOM-элемента. Dynamics.js используется для создания меню , кнопок, индикаторов процесса, маркеров. При этом доступны самые разнообразные параметры, такие как частота, декремент затухания, параметры, характеризующие упругость или продолжительность процесса и т.п.

    Cta.jsНебольшая по объему библиотека cta.js предназначена для создания на странице анимационных эффектов типа «действие-эффект», т.е. наведение или нажатие указателем мыши на объект приводит к определенному эффекту. Очень удобно использовать при разработке плиточных интерфейсов, когда нажатие на элемент приводит к его раскрытию в виде модального окна, на всю страницу, или в виде боковой слайд-панели .

    Beep.jsИнтересная библиотека, использующая WebAudio API для создания на странице музыкального синтезатора. Может найти применение при разработке онлайн-учебника по музыке или в качестве забавной игрушки.

    Rainyday.jsНевероятно красивый эффект дождя с каплями разного размера, стекающими вниз. Правда, на мой взгляд, крупным каплям не хватает реалистичности (может той самой физики, которая присутствует в Dynamics.js?). Впрочем, имеющийся API позволяет создать собственные объекты и управлять их поведением, создавая еще более невероятные эффекты.

    Dom-Animator.jsDom-Animator.js - это так называемое «пасхальное яйцо» (easter egg). Производимый ею эффект не виден «невооруженным» глазом, т.е. тем кто просматривает страницу в обычном окне браузера. Но те, кто будет разбирать ваш код, увидят ее в консоли (если вы все еще не поняли о чем речь, то здесь есть видеоролик, из которого все станет понятно).

    FamousFamous - событийно-ориентированная JS-библиотека для создания современной анимации . Имеет мощное геометрическое ядро, позволяющее манипулировать различными 3D объектами - точечными и объемными - прикладывать к ним силы и ускорения, накладывать ограничения и контролировать соударения.

    Bounce.jsНеплохая JavaScript библиотека для создания впечатляющей анимации с использованием CSS. Позволяет применять к объектам различные виды движения, вращения, масштабирования и преобразования.

    Snabbt.jsЛегкая и быстрая библиотека, выдающая, по заверениям разработчиков, 60 fps даже на мобильных устройствах. При помощи матриц трансформирования CSS позволяет перемещать, вращать, масштабировать и производить другие манипуляции с объектами. Позволяет также применять к объектам специальные эффекты, привлекающие внимание, которые можно использовать при заполнении форм.

    RekapiRekapi позволяет использовать как CSS анимацию ключевых кадров (правило @keyframes), так и DOM анимацию при помощи JavaScript. Эта библиотека позволяет создавать довольно сложные динамические объекты, например круговые и линейные диаграммы, временные шкалы и другие элементы пользовательского интерфейса.

    ShiftyShifty - библиотека, содержащая все необходимое для полноценной анимации по ключевым кадрам (так называемый «твиннинг»), причем количество объектов может быть просто огромным. Это низкоуровневая библиотека, которую можно использовать как ядро для более высокоуровневых платформ или библиотек. Собственно, в качестве ядра вышеупомянутой Rekapi, используется как раз Shifty.

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

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

    Animate.CSS – скрипт, который непосредственно отвечает за саму анимацию. По сути wow.js берет анимации именно из этой штуки.

    Как скачать и подключить.

    1 шаг. Для работы нам понадобиться скачать скрипты wow.js и animate.css

    Файл animate.css – библиотека, в которой прописаны стили для анимации элементов на странице. Для того, чтобы визуально оценить и выбрать вид анимации, обычно, я использую страничку ресурса http://daneden.github.io/animate.css/

    2 шаг. Подключаем скрипты

    Тег script необходимо всегда добавлять в конец body. Это делается для быстроты загрузки страницы. Каждый раз, когда браузер доходит до тега script, загрузка и рендеринг всего сайта замораживается, пока скрипт не будет загружен. От этого зачастую мы видим сайты, которые долгое время просто белый лист. А так же, если скрипт размещён в конце body, у вас есть гарантия что body - ready и скрипт точно отработает.

    Шаг 3. Необходимо инициализировать скрипт добавив вот такой код, сразу после его подключения:

    new WOW().init();

    На этом подключение заканчивается, и настает пора второго этапа.

    Использование WOW.js

    Шаг 1. Выбираем элемент, который хотим анимировать и добавляем ему класс class="wow" . В коде ниже, я показал это на примере картинки:

    Шаг 2. Выбираем анимацию, и добавляем её дополнительным классом к нашей картинке:

    Шаг 3 (не обязательно). Добавляем настройки для анимации если надо, при помощи специальных data-атрибутов:

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

    Настройки WOW.js анимации через атрибуты

    data-wow-duration – указываем время проигрывания анимации

    data-wow-delay – ставим задержку перед проигрыванием анимации

    data-wow-offset – включение анимации, когда элемент проходит определнное количество пикселей от низа экрана

    data-wow-iteration – количество повторов анимации

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

    Краткий обзор перспективных библиотек и плагинов 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 математики для достижения своих целей.

    И мы с пути кривого ни разу не свернем, а надо будет снова пойдет кривым путем - х/ф Айболит 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 или .

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