Build a Dynamic Accordion Menu in Flash CS4 with ActionScript 3.0 and XML
В этом уроке вы научитесь, как с нуля создавать меню в стиле гармошки, которое можно сформировать, используя внешний файл.
Пункты меню можно полностью сконфигурировать в XML с помощью меток, и можно загружать текст, картинку или swf при его открытии. Следуйте этому уроку, и все будет достаточно просто.
Финальный результат этого урока - flash меню, полностью сконфигурированное на основании файла XML, которое может загружать текст, изображения или SWF - файлы, как показано ниже:
Требования
Adobe Photoshop CS 3/4, если вы хотите изготовить свое меню. Вы можете загрузить его отсюда
Вам нужет будет Flash CS4 (но этот урок будет работать также и в ранних версиях).
Также вам необходим сконструированный пункт меню; это может быть любое изображение, но я рекомендую использовать мое, которое можно загрузить отсюда , вы найдете также файл .psd, чтобы вы могли использовать ваш собственный стиль, но убедитесь, что вы имеете по левой стороне 20px.
Вы должны иметь TweenLite, который можно загрузить здесь. Обычно он вам не нужен, но я предпочитаю использовать его, чем родные AS3 tween классы.
Шаг 0 - Начало
Самое первое, что вы сделаете, - создайте новый Action Script 3 проект!
Затем задайте сцене эти размеры:
Сохраните файл в папке с именем menuAccordion, назовите его “tutorial”.
Шаг 1 - Создаем пункт меню
Нам нужен будет только один пункт меню, другие мы будем создавать из этого пункта. Мы должны делать так, потому что наше меню динамическое. Итак… как мы будем делать это? Просто, мы создадим мувиклип, который будет вести себя как пункт меню, затем экспортируем его для использования в action script , и затем нам нужно только продублировать его в action script.
Первое, что нужно сделать, это импортировать картинку, которую я сделал, перейдите в меню File->Import-> Import to stage, таким образом картинка расположится сразу на сцене. Я использовал “itemback1.jpg”:
Теперь конвертируйте его в мувиклип, по правой кнопке мыши по нему - Convert to Symbol, и выберите MovieClip, назовите его menuItem (важно!), и кликните export to Action Script (важно), все это должно выглядеть так, как на картинке ниже:
Такие имена очень важны для нас, потому что мы будем использовать их в Action Script. Если появится предупреждение, нажмите ok.
Нашему меню нужны некоторые части: текстовое поле для получения метки (label), далее textarea, чтобы высвечивать текст, который пользователь определит в XML, и пустой мувиклип для загрузки JPG/SWF файлов, используемый, чтобы отображать контент, когда меню открыто.
Шаг 2 - определяем загрузчики контента на месте
Я имею ввиду метку для меню, текст и пустой мувиклип.
Отредактируем наш только что созданный мувиклип (дважды кликните по нему), создайте новый слой поверх существующего, назовите его label и сначала добавьте текстовое поле в серую секцию, напишите в нем: “HOME”, в свойствах выберите dynamic text (динамический текст), с внедренными фонтами (важно!), выровняйте слева и выберите single line. Размер в соответствии с высотой гармошки и дайте ему черно-серый цвет.
Вы не можете увидеть текст HOME? Вы забыли внедрить фонты правильно? Внедрите только заглавные символы и дайте ему инстанс имя itemLabel!
Создайте новый слой и назовите его buttonBack, затем нарисуйте прямоугольник поверх всей серой области:
Конвертируйте этот прямоугольник в мувиклип, назовите его buttonBack (не экспортируйте для action script) и далее дайте ему инстанс имя “buttonBack” и поставьте альфа в 0 в списке Style.
Следующее, что нужно сделать, - это создать загрузчик контента. Создайте новый слой, назовите его contentLoader, далее нам нужно нарисовать прямоугольник, соответствующий по размеру изображению справа :
Трансформируем его в мувиклип, назовем itemLoader, дадим инстанс имя itemLoader и дважды кликнем по нему, кликнем правой кнопкой по слою и выберем Guide, это на первый взгляд ничего не даст, но когда вы вернетесь в меню, он просто исчезнет, но это не совсем верно на 100%, это будет в слое прозрачный фон…
Теперь создайте новый слой поверх всех , и назовите его text, нарисуйте здесь текст, как на картинке, сделайте его динамическим текстом, выравнивание по центру, и если необходимо с внедренными шрифтами. Дайте ему инстанс имя itemText.
Отлично, ваш пункт меню готов! Сейчас только необходимо записать XML файл, и код action script .
Перед этим, проверьте, выглядят ли ваши слои как здесь:
Шаг 3 - пишем XML
Создайте xml фай, назовите menu.xml и напишите это!:
Code
<?xml version="1.0" encoding="utf-8"?> <menu menuOpen="1" moveonMouseOver="false"> <item Ititle="home" IcontentType="image/swf" IcontentData="image2.jpg"/> <item Ititle="about" IcontentType="text" IcontentData="Our company is based on UK! Know how we have born!; Click here"/> <item Ititle="Products" IcontentType="image/swf" IcontentData="image5.jpg"/> <item Ititle="Services" IcontentType="image/swf" IcontentData="item2.swf"/> <item Ititle="Contact" IcontentType="image/swf" IcontentData="image1.jpg"/> </menu>
Структура xml достаточно простая, свойство menuOpen будет определять таб menu, который будет открываться автоматически при старте, затем moveonMouseOver индицирует, будет ли пункт меню открываться, когда мышь над его табом. Затем пункты, в Ititle мы определяем метку для меню, которая будет использоваться в текстовом поле itemLabel, затем тип контента (IcontentType), который будет загружать меню, если он =”text” текстовое поле itemText будет загружать текст IcontentData, или, если он = “image/swf”, contentLoader будет заружать url объекта IcontentData .
Сохраните этот файл, и поместите также папку gs для загрузки Tweenlite AS3 в ту же самую папку, где находится основной файл Flash (menuAccordion).
Теперь вернитесь во Flash, на основную сцену, мы получили только один пункт меню, верно? Кликните правой кнопкой по нему и выберите Cut (CTRL+X), теперь создайте новый мувиклип (меню Insert -> New Symbol и назовите его menuLoader, нажмите ok и затем вставьте наш menuItem (CTRL+V), положение не важно.
Вернитесь на основную сцену, откройте панель library и перетащите menuLoader в первый слой, это равно тому, что мы получили загрузчик меню, куда будут грузиться пункты меню. Дайте ему инстанс имя menuContainer.
Давайте добавим новый слой на сцену и назовем его mask, в нем создадим прямоугольник, конвертируем его в мувиклип и назовем его masker. Дадим ему инстанс имя masker. По правой кнопке кликнем по этому слою, выберем Mask, эта маска будет использоваться, чтобы скрыть последнее меню и не показывать, когда мы не хотим!
Сейчас добавим третий слой сверху этих двух, назовем его Actions, перейдем в панель actions и запишем это там.
Code
//импорт классов tweenlite import gs.TweenLite; import gs.easing.*;
var MENU_ARRAY:Array; //используем для хранения данных пунктов меню var OPENED_MENU:int; //чтобы информировать, какое меню должно быть открыто при старте var MOVE_ON_MOUSE_OVER:Boolean=false; //имя говорит само за себя var xmlLoader:URLLoader; //загрузчик xml
loadXML("menu.xml"); //загружаем xml
function loadXML(Uri:String):void { xmlLoader = new URLLoader(); xmlLoader.addEventListener(Event.COMPLETE, onComplete); xmlLoader.addEventListener(IOErrorEvent.IO_ERROR, onError); xmlLoader.load(new URLRequest(Uri)); }
function onError(evt:ErrorEvent):void { trace("cannot load xml file"); }
function onComplete(evt:Event):void { //читаем и загружаем xml в массив, распарсим его, используя prepareMenu MENU_ARRAY=prepareMenu(xmlLoader.data.toString()); placeItemsOnStage(); //размещаем все требуемые пункты на сцене. }
function placeItemsOnStage():void { var pos:Number=0; //определяем свойства контейнера menuContainer.x=0; menuContainer.y=0;
for(var c:int=0; c<MENU_ARRAY.length; c++) { var it:menuItem = new menuItem; //загружаем menuItem, поскольку он экспортируется в AS, мы можем использовать его здесь it.x=c*27; //ширина его серого бордюра it.y=0; //помещаем наверх it.id="Item-"+c; //id для menuItem it.name="Item-"+c; //имя для menuItem it.posX=pos; //фактическая позиция, используется, чтобы открывать и знать позицию it.itemLabel.text=String(MENU_ARRAY[c].Ititle).toUpperCase(); //загружаем метку label, переводим в заглавные буквы it.addEventListener(MouseEvent.CLICK, onMouseClick); //добавляем слушатель mouse click if(MOVE_ON_MOUSE_OVER==true) it.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver); //если сконфигурировано, загружаем событие mouse over it.useHandCursor=true; //используем курсор hand it.buttonMode=true; //buttonMode it.itemText.visible=false; //спрячем текстовое поле menuContainer.addChild(it); //добавим пункт меню как child
if(String(MENU_ARRAY[c].IcontentType)=="image/swf") { //проверим контент и зарузим все, что соответствует ему var ldr:Loader = new Loader(); ldr.x=27; ldr.y=0; it.addChild(ldr); ldr.load(new URLRequest(MENU_ARRAY[c].IcontentData.toString())); } else if(String(MENU_ARRAY[c].IcontentType)=="text") { it.itemText.visible=true; it.itemText.text=MENU_ARRAY[c].IcontentData.toString(); } pos+=27; //позиция x следующего menuItem }
//поместим маску в место.... masker.width=(MENU_ARRAY.length*27+325) masker.height=menuContainer.height; masker.x=0; masker.y=0;
moveItem(OPENED_MENU-1); //открываем меню, сконфигурированное в XML
}
function onMouseOver(evt:MouseEvent):void { if(evt.target.name.toString()=="buttonBack") prepareMove(evt) }
function prepareMove(evt:MouseEvent):void { var targetName:String = evt.currentTarget.name.toString(); //получим menuItem var temp:Array = targetName.split("-"); //разделим его имя: Item-x var itemNumber:int=(temp[1]); //получили номер пункта moveItem(itemNumber); //двигаем его }
function onMouseClick(evt:MouseEvent):void { if(evt.target.name.toString()=="buttonBack") prepareMove(evt); //действие мыши произошло на buttonBack else trace("Item "+evt.currentTarget.name+" clicked!"); //действие мыши произошло в области гармошки }
function moveItem(num:int):void { var itemToMove:menuItem=menuContainer.getChildByName("Item-"+String(num)) as menuItem; //получим детку menuItem for(var m=0;m<MENU_ARRAY.length;m++) //двигаем один за одним на новую позицию { var tempMc = menuContainer.getChildByName("Item-"+m); if(tempMc.x > itemToMove.x) TweenLite.to(tempMc, 1, {x:((tempMc.posX) + itemToMove.width-27), ease:Quart.easeOut}); //смотрим информацию об этом в tweenLite . else if(tempMc.x <= itemToMove.x) TweenLite.to(tempMc, 1, {x:(tempMc.posX), ease:Quart.easeOut}); } }
function prepareMenu (XMLData:String):Array { //убедимся, что данные пришли в XML var menuXML:XML = new XML(XMLData); //на всякий случай menuXML.ignoreWhitespace = true;
//получим элементы XML для пунктов var XMLItems = menuXML.descendants("item");
//загружаем все пункты в массив var itemsArray:Array = new Array(); var itemObj:Object; for(var i in XMLItems) { itemObj=new Object(); itemObj.Ititle=XMLItems[i].@Ititle; itemObj.IcontentType=XMLItems[i].@IcontentType; itemObj.IcontentData=XMLItems[i].@IcontentData; itemObj.itemID="menu"+i; itemsArray.push(itemObj); } OPENED_MENU=menuXML.@menuOpen; //получаем меню для открытия. MOVE_ON_MOUSE_OVER=(menuXML.@moveonMouseOver.toString()=="true" ? true : false); //получаем опцию для загрузки : открыта или нет mouseOver return itemsArray; }
//конец.
Код откомментирован, поэтому читайте его внимательно перед тем, как произвести какие-либо действия, после этого вы можете поразвлечься и создать свое меню-гамошку! В XML вы можете легко добавлять, удалять и редактировать метки и пункты гармошки.
Последнее, что вы должны сделать, - это дважды кликнуть по menuContainer / menuLoader и удалить там menuItem , нам нет необходимости иметь его там, потому что мы будем добавлять его как child посредством AS3. Измените высоту сцены на 200px (это высота меню).
Надеюсь вам понравился этот урок! Вы можете загрузить окончательный flash проект отсюда.