Уроки Flash: Анимированное круговое меню

Источник: demiart
ARTur2

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

Урок по реализации меню

Урок по реализации меню

При выборе пункта меню - все пункты, включая выбранный, поворачиваются по часовой стрелке. Когда выбранный пункт окажется внизу и по центру меню, анимация завершается. При нажатии на пункт меню, он должен, как-то это нажатие обозначить. Решением стало - его изменение цвета. Смотри рис.2. По завершении анимации, совершается переход на внутреннюю страницу сайта, где выбранный пункт сохраняет свое месторасположение и состояние "нажато".
Перейдем к процессу реализации.
1) Для начала была нарисована окружность, в неё вписан правильный пятиугольник и на пересечении вершин пятиугольника и окружности расставлены "точки".
Важная особенность. Слоем ниже, была нарисована окружность большего радиуса, чем у нашего меню, её центр совпадал с центром меню. Этот момент я объясню немного дальше, когда мы доберёмся до анимации меню. Смотри рисунок №3.

Урок по реализации меню

2) Всё это рисование мы конвертируем в клип и называем "krug_mc". Точку регистрации клипа делаем по центру. Не забываем про Instance name! "кrug_mc" снова конвертируем в клип и называем его - "MainMc". Теперь заходим в "MainMc" и слой с кругом называем "krug_mc". Для простоты я всегда называю слои идентично имени расположенных на нём элементов.
3) Теперь нам нужно анимировать движение нашего клипа "krug_mc" по окружности, относительно своего центра. Делается это очень просто. Допустим, на 80 кадре слоя "krug_mc" ставим ключевой кадр. По любому из промежуточных кадров нажимаем мышкой и перемещаемся в панель Properties, в которой выставляем нужные нам значения. Смотри рисунок №4. Та самая окружность с прозрачной заливкой будет нам гарантировать, что меню будет вращаться именно относительно своего геометрического центра.

Урок по реализации меню

4) Теперь нам нужно нарисовать кнопки меню.
Рассмотрим на примере конкретной кнопки "Партнёрство". Выбираем инструмент Text Tool и пишем текст "Партнёрство". Я выбрал чёрный цвет текста (это для маленькой хитрости, о которой будет рассказано ниже) и шрифт Tahoma 12, как того требовал исходный макет странички. Важный момент: в свойствах текста нужно выбрать пункт Anti-alias for animation. Это позволит анимации текста выглядеть качественно и без "скачков". Теперь конвертируем текстовое поле в клип и называем его "partniorstvo_btn". Заходим в него и ещё раз из текста делаем клип с названием "partniorstvo_btn_ins". Не забываем про Instance name у клипов! Вот и готов один из пунктов меню!
5) Теперь нам нужно анимировать его отклик на нажатие по нему мышкой. То самое проявление "нажатия", про которое я говорил в самом начале. Заходим в "partniorstvo_btn", выбираем 15-ый кадр и делаем его ключевым. Теперь в первом кадре нам нужно выставить начальный цвет пункта меню. Я выбрал цвет RGB(110, 111, 115), по требованию макета. Для тех кто не знает - эти настройки можно выставить у клипа таким образом: PropertiesColorпункт AdvancedSetings. Смотри рисунок №5.

Урок по реализации меню

В 15-ом кадре, с помощью инструмента Free Transform и, зажатой клавишей Shift, немного увеличиваем клип "partniorstvo_btn_ins". С помощью всё тех же "продвинутых" цветовых настроек выставляем значение цвета RGB у клипа 144, 157, 143 соответственно.
Между первым и пятнадцатым пунктом ставим Motion Tween. См. рис. 4.
В клипе "partniorstvo_btn" делаем ниже ещё один слой с прозрачной заливкой, которая по размерам будет соответствовать области "Hint" у кнопки. В первом и последнем кадре клипа "partniorstvo_btn" вешаем стопы. Кто-то может сказать, что это очень странный способ анимации изменения цвета текста, но практика показывает, что он более качественный в плане изменения цвета у объекта.
6) Теперь нужно анимировать движение этого пункта меню по окружности. Делается это достаточно просто. С помощью твин трассы.
Коротко расскажу, как это делается. Создаём два слоя. Первый называем для простоты "Partniorstvo_btn". Второй слой расположим над первым и назовем "Guide_Partniorstvo". На первом слое размещаем кнопку "partniorstvo_btn". Кнопку расположим в ее стартовых координатах, они же станут и конечными, после полной анимации поворота меню.
Второму слою назначаем тип - guide над первым. Итоговый результат, как на рисунке №6.

Урок по реализации меню

Продолжаем! Теперь нужно заставить двигаться пункт меню по часовой стрелке. В слое "Guide_Partniorstvo" нужно нарисовать твин трассу, по которой будет двигаться этот пункт. Нарисуем окружность с центром, совпадающим с центром меню и радиусом, превышающим радиус меню. Огибающая окружности должна пересекать регистрационную точку клипа "partniorstvo_btn".
С помощью инструмента Free Transform и зажатыми клавишами Shift + Alt немного растянем окружность по бокам. На 80-ом кадре нажимаем F5. Это делается для того, чтобы при вращении пункта меню он не пересекался с меню. Смотри рисунок 7.

Урок по реализации меню

Теперь нужно немного модифицировать полученную твин трассу, чтобы заставить двигаться пункт меню "Партнёрство" по ней. Я делаю это так. В точке, где твин трасса пересекает центр кнопки "Партнёрство", делаю на твин трасе маленький "разрыв". Теперь на слое "Partniorstvo_btn" в 80-ом кадре ставим ключевой кадр. Возвращаемся в первый кадр этого слоя и, предварительно нажав кнопку Snap to Objects, вешаем кнопку

Урок по реализации меню

"Партнёрство" на правый край разрыва твин трассы. Аналогичное действие производим в 80-ом кадре, только кнопку вешаем на левый край разрыва трассы. Для первого кадра смотри рисунок 8.

Урок по реализации меню

Теперь в слое "Partniorstvo_btn" между первым и вторым кадром выбираем тип анимации - Motion Tween. Тестируем клип и видим, что кнопка меню двигается как бы не равномерно по отношению к своей "точке" на окружности меню. Это происходит из-за того, что радиусы твин трассы кнопки не совпадают с радиусом движения точки меню. Этот вопрос решается в следующем пункте.
7) Для начала нам нужно найти "опорные точки" в движении меню. Опорными точками я называю кадры анимации, где, одна из точек, меню находится внизу по центру. Нужно найти все эти опорные точки и на слое "Partniorstvo_btn" в этих местах расставить ключевые кадры. Смотри рисунок 9.

Урок по реализации меню

В итоге получилось 5 ключевых кадров на слое "Partniorstvo_btn", которые "символизируют" опорные точки в анимации вращения меню. В каждом из этих кадров нужно выровнять кнопку "Партнёрство", относительно своей точки меню. Чтобы в дальнейшем остальные кнопки выровнять симметрично относительно друг друга можно воспользоваться Guide. На рисунке 10 представлено размещение кнопки в ключевых кадрах - 9-ом, 25-ом, 41-ом, 57-ом, 73-ем. У Вас эти кадры могу получиться отличными от данного примера. Смотри рисунок 10.

Урок по реализации меню

Теперь анимация вращения кнопки должна совпадать с анимацией вращения её точки в меню.
Эти действия нужно повторить для всех остальных пунктов меню. В результате, должно получиться, как на рисунке 11.

Урок по реализации меню

На этом рисунке можно увидеть, что твин трассы у некоторых пунктов меню различаются по форме. Это отличие обусловлено количеством символов в названии того или иного пункта. Диаметр твин трасы по иксу подбирается в ходе экспериментов с анимацией.
8) Теперь необходимо запрограммировать логику меню. Итак, структура сайта будет иметь такой вид:

http://URL-сайта/events/ - События
http:// URL-сайта /services/ - Услуги
http:// URL-сайта /contacts/ - Контакты
http:// URL-сайта /about/ - О компании
http:// URL-сайта /partnership/ - Партнёрство

А) Есть анимация движения всего меню по кругу один раз.
Б) Есть ключевые кадры (9, 25, 43 и т.д.) в которых нужные пункты меню находятся в нужном нам положении. Т.е. снизу по центру.
В) С самого начала грузится всё меню и тормозит на первом кадре.
Г) По нажатию на ту или иную кнопку меню запускается анимация. Каждой кнопке нужно присвоить свой флаг, который отвечает за состояние кнопки (нажата/отжата) в данный момент. Т.е. если на кнопку не нажимали, значение флага равно false, если нажимали, то true.
Д) Анимация доходит до того места, где как раз проверяется флаг кнопки.
Если проверка даёт значение true, то переходим по нужному адресу и меню загружается опять с первого кадра, где проверяется домен страницы.
Е) В зависимости от имени домена переходим на нужный кадр в анимации меню.
Пункт А) и Б) уже готов.
Пункт В и Д) В клипе "MainMc" создаём ёщё один слой и называем его "Stops_AS".
Теперь в этом слое нужно расставить ключевые кадры соответственно опорным точкам анимации, которые были определены раньше. Смотри рисунок 12.

Урок по реализации меню

В первом кадре этого слоя вешаем такой код:


Code

 this.stop();// останавливаем анимацию вращения при начальной загрузке
if (_global.kontakty_flag == true or _global.kompanija_flag == true or _global.partniorstvo_flag == true or _global.sobytija_flag == true or _global.uslugi_flag == true) {
gotoAndPlay(2);
}// Данная проверка нужна для того, чтобы анимация вращения меню не тормозила на стопе, который находится выше, при нажатии кнопки, чей цикл анимации находится, например, в кадрах с 43-ого по 25-ый. О присвоении флагу состояния true будет рассмотрено в пункте Г.

Теперь нужно заняться ключевыми кадрами, они же опорные точки анимации. Смотрим, какой пункт меню в данной точке является в положении "внизу и по центру" и соответственно прописываем следующий код. Для кнопки "Партнёрство" это будет такой код:

Code

 if(_global.partniorstvo_flag==true){
stop();
getURL("URL-сайта /partnership/", "_self");
};
// Проверяем состояние флага, отвечающего за состояние кнопки (нажали её или нет), если нажали, то прерываем анимацию вращения меню и переходим на соответствующую внутреннюю страницу сайта.


 


И так для каждой кнопки в своём ключевом кадре.
Пункт Г) Выходим из клипа "MainMc" на уровень выше, т.е. на основную сцену. Создаём в ней два слоя для кода и называем их "as_Knopki" и "as_ProverkaDomena". Смотри рисунок 13.

Урок по реализации меню

В слое "as_Knopki" будет размещаться код, который реагирует на нажатие той или иной кнопки, а в слое "as_ProverkaDomena" расположим код, который отвечает за проверку домена после перехода пользователя на внутреннюю страницу сайта.
Итак, в слое "as_Knopki" вешаем такой код для каждой кнопки соответственно (в этом примере для многострадальной кнопки "Партнёрство"):

Code

 _root.mainMc.partniorstvo_btn.onRelease = function() { //нажали кнопку "Партнёрство"
// Эту кнопку заставляем проиграть свою внутреннюю анимацию. Смотри пункт 5.
_root.mainMc.partniorstvo_btn.gotoAndPlay(2);
//Остальные кнопки переводим на первый кадр своей внутренней анимации.
_root.mainMc.kompanija_btn.gotoAndStop(1);
_root.mainMc.sobytija_btn.gotoAndStop(1);
_root.mainMc.uslugi_btn.gotoAndStop(1);
_root.mainMc.kontakty_btn.gotoAndStop(1);
// Присваиваем значение флага кнопки "Партнёрство", как true (Для пункта В ), а остальным кнопкам false.
_global.kontakty_flag = false;
_global.kompanija_flag = false;
_global.partniorstvo_flag = true;
_global.sobytija_flag = false;
_global.uslugi_flag = false;
_root.mainMc.gotoAndPlay(_root.mainMc._currentframe);// Основную анимацию вращения меню запускаем с кадра, на котором остановились.
};

И такой код напишем для каждой кнопки, соответственно меняя нужные значения флага и параметров внутренней анимации кнопок.
Теперь нужно научиться отличать одно имя домена от другого. Для этого заводим переменную self. Переменная self передаётся в меню через html-код вставки флешки на страницу сайта.
Делается это так (опять на примере внутренней страницы "Партнёрство"):

Code

 …
<param name="movie" value="http:// URL-сайта /meniu.swf?self=partnership" />
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
<embed src="http:// URL-сайта /meniu.swf?self=partnership"

Теперь слой "as_ProverkaDomena". Опять на примере кнопки "Партнёрство" вешаем такой код:

Code

 if (self == "partnership") { // если мы перешли на внутреннюю страницу "Партнёрство"
то перемещаем головку флеш плеера на ключевой кадр анимации, где кнопка "Партнёрство" находится в выбранном состоянии
_root.mainMc.gotoAndStop(41);
_root.mainMc.uslugi_btn.gotoAndStop(1);
_root.mainMc.sobytija_btn.gotoAndStop(1);
_root.mainMc.partniorstvo_btn.gotoAndStop(15);// Переходим на кадр внутренней анимации изменения состояния кнопки после нажатия на неё, а остальные кнопки возвращаем в начальное состояние, если они были в состоянии "нажали"
_root.mainMc.kompanija_btn.gotoAndStop(1);
_root.mainMc.kontakty_btn.gotoAndStop(1);

 

*********************************************************
А теперь другой вариант кода. Он элегантнее и занимает меньше строчек:
*********************************************************

Code

 var buttons:Array=[uslugi_btn, sobytija_btn, partniorstvo_btn, kompanija_btn, kontakty_btn];
//Ссылки на доступные кнопки меню
var endFrame:Array=[9, 25, 41, 57, 73];
//Ключевые стоп-кадры
var links:Array=["services.html", "events.html", "partnership.html", "about.html", "contacts.html"];
//Адреса внутренних страничек сайта
var pressFlag:Boolean=true;
//Флажок нажатия кнопки
var button_id:Number
//Идентификатор выбранной кнопки
var tot_f:Number=this._totalframes;
// Общее кол-во кадров меню
Stage.scaleMode = "noScale";
Stage.showMenu = false;
this.stop();
//Инициализация кнопок.
//Циклом проходим по массиву с кнопками и назначаем каждой, идентификатор и обработку нажатия.
//В обработчике проверяем, если флаг нажатия поднят и кнопку эту не нажимали, то разрешаем анимацию поворота меню.
for(var i =0; i<buttons.length; i++){
buttons[i].id=i;
buttons[i].onRelease=function(){
 pressFlag&&button_id!=this.id?rotator(this):null;
}
}
/*Процедура вращения меню. Аргументом является ссылка на нажатую кнопку. Построчные комментарии
1) Запомним текущий кадр меню
2) Запретим нажатия на кнопки
3) Запомним идентификатор кнопки
4-6) Установи все кнопки в состояние "отжато"
7) Запомним конечный кадр анимации
8) Адрес страницы, назначенной текущей кнопке
9,10) Старт анимации кнопки и меню
11) далее ежекадрово:
13) проверим, добрались ли мы до конца таймлайна меню? Если так, то перезапустим анимацию сначала
14) Если добрались до выбранного конечного кадра:
15) Остановим анимацию меню
16) Разрешим, нажимать кнопки
17) Остановим ежекадровую слежку
18)Перейдем на выбранную страничку*/
function rotator(arg:MovieClip){
1.  var cf:Number=this._currentframe;
2.  pressFlag=false;
3.  button_id=arg.id;
4.  for(var i =0; i<buttons.length; i++){
5.   buttons[i].gotoAndStop(1);
6.  }
7.  var ef:Number=endFrame[arg.id];
8.  var link:String=links[arg.id];
9.  arg.play();
10.  this.play();
11.  this.onEnterFrame=function(){
12.   cf=this._currentframe;
13.   cf==tot_f?this.gotoAndPlay(2):null;
14.   if(cf==ef){
15.    this.stop();
16.    pressFlag=true;
17.    delete this.onEnterFrame;
18.    getURL(link, "_top");
19.   }
20.  }
21. }
//По загрузке странички, установим меню на нужный кадр
this.gotoAndStop(endFrame[_root.self]);

Этот код прописывается в первом кадре меню и полностью заменяет вышеизложенные кодовые последовательности. Кроме того, переменная "self" должна содержать число - адрес выбранного пункта в массивах.
услуги - 0,
события - 1,
партнерство - 2,
о компании - 3,
контакты - 4.

Вот и всё! Некоторое время эту меню можно будет потестить на http://artur.azteko.com/


Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=18894