среда, 8 апреля 2015 г.

Покадровая анимация в raphael js

Покадровая анимация (frame animation) в javascript библиотеке raphael js.
Пытаясь сделать один из своих проектов (анимация графики, он в процессе), подбирал подходящую среду разработки, посмотрел на аналоги, чем люди такое делают, люди по прежнему делают такое на Flash. Несколько лет назад пробовал программировать в этой замечательной среде,тогда предрекали его скорую гибель и переход на различные аналоги. Но Flash живее всех живых, я все же решил попробовать подобрать альтернативу для своего проекта и наткнулся на библиотеку Raphaёl js.

Те, кто когда либо работал в Adobe Flash, знают, с какой простотой там делается анимация. Среда разработки в Flash представляет собой линейку с кадрами и все, что нужно сделать разработчику для анимации, это разместить изображения в кадрах, потом дать команду go to play, и вуаля. В javascript все это реализовать несколько сложнее, а сделать простенькую анимацию схожую по параметрам с flash иногда нужно.

Создание аналога анимации Flash.



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

Будем считать, что страница настроена для работы, мой блок head выглядит
так:
<head>
<meta charset="UTF-8">
<title>frame animation</title>
<link rel="stylesheet" href="css/style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.2/raphael-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>

Для наглядности реализуем анимацию, имитирующую движение маркера в
среде разработки flash средствами raphael js.
Берем фото той самой среды:
flash_marker
Рисуем свой маркер, код:
var line = p.rect(204, 60, 1, 60);//примитив линия
var marker = p.rect(200, 50, 9, 20);//примитив прямоугольник
var mark = p.set();//обьединяем объекты в группу
mark.push(line);
mark.push(marker);
mark.attr({fill: 'red',stroke:'red'});

Сделаем для начала простую анимацию, сдвинем маркер в право на 30 кадров, для этого линейкой замеряем ширину кадра и перемещаем на соответствующее количество пикселов по оси x. Этого можно добиться, рисуя на canvas и без фрэймворка. Единственное, что из коробки в raphael js можно сразу прикрутить изинги (easing), т.е. сделать анимацию не линейной. Вначале будет небольшое ускорение, пример:


Теперь код выглядит так:
var line = p.rect(204, 60, 1, 60);//примитив линия
var marker = p.rect(200, 50, 9, 20);//примитив прямоугольник
var mark = p.set();//обьединяем объекты в группу
mark.push(line);
mark.push(marker);
mark.attr({fill: 'red',stroke:'red'});
mark.animate({"transform" : 'T232,0'},5000,">");

Суть последней строки подробнее. mark.animate применяем к объекту mark метод animate со следующими параметрами - "transform" : 'T232,0', перемещаем (трансформируем) на заданное количество пикселов по оси х, в нашем случае 232, цифра 5000 - анимация будет длиться 5 секунд, '>' - easing, вначале ускорение, потом замедление. Если почитать документацию, есть несколько вариантов easing.
pirtf
Небольшой подводный камень. Можно было обойтись и без метода transform, задав перемещение по оси х методу animate, но тогда объекты line и marker переместились бы не относительно текущей позиции, и объект line не был бы посередине объекта marker. Это конечно можно обойти, но мне метод transform показался проще.

Easing это конечно хорошо, но нам нужны возможности покадровой анимации. Как сделать так, чтобы в заданном месте маркер изменял направление движения? Заданное место имеет название ключевой кадр (kay frame), и возможности анимации с использованием ключевых кадров уже будут на порядок выше. Для этого в raphael js есть особый синтаксис - можно добавлять проценты в анимацию, т.е. на определенном проценте, в определенной точке времени изменить анимацию, создать какое либо событие, а это уже подобие flash анимации.
Пример синтаксиса:
mark.animate({
"30%" : {"transform" : 'T114,0',fill: 'green',stroke:'green'},
"40%" : {"transform" : 'T73,0',fill: 'blue',stroke:'blue'},
"100%" : {"transform" : 'T232,0',fill: 'red',stroke:'red'},
},10000);

Данный код означает, что анимация будет длиться 10 секунд (цифра 10000 в конце), на 3 секунде (30%) маркер подойдет к 15 кадру, изменив при этом цвет на зеленый, потом к 4 секунде он уже будет на 10 кадре, изменив цвет на синий, и на 10 секунде он подойдет к 30 кадру уже с красным цветом.
Собственно анимация:

Возможно, именно этот синтаксис с процентами имел в виду Дмитрий Барановский (автор библиотеки raphael js), когда на утверждение - "Raphaël doesn’t have specific functions for handling animation frames…", (Raphaël не имеет специфичиских функций для обработки покадровой анимации, перевел Меггер с помощью гугла) - ответил - "First of all it does have" (Имеет).

Еще одну крутую возможность библиотеки - добавлять функцию обратного вызова (callback) на определенном этапе анимации - планирую описать в одной из следующей записей.


1 комментарий:

  1. Зашёл в 1:15 ночи. Читать вдумчиво не в силах. Но дизайн понравился. Жаба с присосками это замечательно. Прям lacoste. Понравился знак жёлтый. Все таки должно что - то и визуально запоминаться окромя графиков и цифр. Зачёт. Иду спать.

    ОтветитьУдалить