Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   XML меню аккордеон (http://www.flasher.ru/forum/showthread.php?t=157636)

vivado 08.06.2011 18:41

XML меню аккордеон
 
Всем привет,
Подскажите можно ли сделать меню типа аккардион (раскрывающееся) средствами AS 2.0 (без Tween анимации)?
Например гружу из XML Имена пунктов меню + ссылки к ним вот так.

Код AS1/AS2:

menu_xml = new XML(); // Создаём обьект XML
menu_xml.ignoreWhite = true; // Игнорируем все ненужные пробелы
// Отслеживаем загрузку xml
menu_xml.onLoad = function(ok) {        if (ok) { F_createMenu();        } }
 
menu_xml.load("menu.xml"); // Загружаем menu.xml
 
// Функцию для создания меню
F_createMenu = function () {
 
// Заводим переменную для хранения количества элементов массива
var lenMass = menu_xml.childNodes[0].childNodes.length;
 
// В цикле перебираем массив
        for (var i = 0; i<lenMass; i++) {
 
// Для каждой кнопки создаём мувик
                _root.createEmptyMovieClip("btn"+i, i);
 
// Переменная хранящая название кнопки
                var b = _root["btn"+i];
 
// Аттачим из библиотеки задний фон для кнопки
                b.attachMovie("back", "back", 1);
 
// Создаём текстовое поле для отображения названия кнопки
                b.createTextField("tf", 2, 0, 0, 200, 20);
 
// Применяем к тексту нужные параметры
                with (b.tf) {
                        selectable = false;
// Вытаскиваем из массива нужное название кнопки
                        text = menu_xml.childNodes[0].childNodes[i].attributes.menu_name;
                }
 
// Устанавливаем кнопки по вертикали друг за другом с промежутком в один пиксель
                b._y = (b._height+1)*i;
 
// Задаём для каждой кнопки ссылку для перехода по ней при нажатии
                b.link = menu_xml.childNodes[0].childNodes[i].attributes.link;
 
// Вешаем обработчик событий нажатия на кнопку
                b.onPress = function() {
                getURL(this.link, "_self"); // При нажатии переходим по ссылке
                };
        }
};

XML у меня такого типа:
PHP код:

<item menu_name="Главная" link="http://test.ru" />
<
item menu_name="Галерея" link="http://test.ru/2" />
<
item menu_name="Контакты" link="http://test.ru/3" /> 

Как можно организовать появляющееся подменю для каждого из пунктов меню, я так понимаю нужно особым способом сформировать XML и потом грузить по порядку и главное как сделать
анимацию для раскрывающегося списка подменю с помощью AS 2.0?

Была у меня идея создать отдельные XML для каждого пункта меню и грузить их по порядку но это думаю неправильно?

И пожалуйста не отправляйте меня Гуглить или Читать учебник. Лучше направьте в нужное русло подсказками.

mooncar 08.06.2011 19:03

Есть стандартный компонент Accordion (кстати, по русски все-таки правильно писать "аккордеон")
Adobe Flash, Ctrl + F7, выбираете Accordion и программно настраивайте в соответствии с вашими данными, полученными из XML.
Что и как, есть в хелпе, статья "Accordion component".

dark256 08.06.2011 20:54

http://wedding-tur.ru/

Меню-книжка с аккордеоном. рассмотрю коммерческие предложения :)

ХМЛ также содержит следующие настройки.

// speed - скорость раздвигания. Сдивгание - в 2 раза быстрее (сек)
// flipspeed - скорость перелистывания (миллисек)
// X0, Y0 - позиция первой строки осн.меню
// mainSpace - - интервал между строками осн.меню
// spacing - интервал строк субМеню
// delay - задержка перед переходом на ссылку (сек)

При желании сама листалка легко отламывается.

vivado 09.06.2011 11:12

dark256 Мне книжка эта не нужна, причем исходников подобных куча бесплатно нагуглить можно. Помоги лучше если можешь по доброте душевной, а это предложение в вакансии )))

Добавлено через 3 минуты
Цитата:

Сообщение от mooncar (Сообщение 1002151)
Есть стандартный компонент Accordion (кстати, по русски все-таки правильно писать "аккордеон")
Adobe Flash, Ctrl + F7, выбираете Accordion и программно настраивайте в соответствии с вашими данными, полученными из XML.
Что и как, есть в хелпе, статья "Accordion component".

Спасибо но я хотел, так сказать все компоненты меню сам сделать. Может знаешь как?

mooncar 09.06.2011 11:37

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

Готового такого у меня нет, нужно просто сесть и написать, используя весь свой опыт. :)
Единственное, что могу посоветовать, для анимаций можно использовать класс TweenLite от Greensock.

dark256 09.06.2011 11:46

Цитата:

Помоги лучше если можешь по доброте душевной
Чем тут помочь-то?
Литературным языком рассказать ВСЕ от начала и до конца?
Это малоконструктивно. Не говоря уже о том, что толку будет мало.

1. Хмл - сделайте со вложенными узлами 2-го уровня.
2. Двигать - можно так, как сказал mooncar, а можно самому по onEnterFrame
3. код на кнпках не писать.

все ;)

vivado 09.06.2011 18:56

Цитата:

Сообщение от dark256 (Сообщение 1002297)
Чем тут помочь-то?
Литературным языком рассказать ВСЕ от начала и до конца?
Это малоконструктивно. Не говоря уже о том, что толку будет мало.

1. Хмл - сделайте со вложенными узлами 2-го уровня.
2. Двигать - можно так, как сказал mooncar, а можно самому по onEnterFrame
3. код на кнпках не писать.

все ;)

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

1. Насчет сделать XML с вложенными узлами я не смог прописать условие по которому будут извлекаться подменюшки. Единственное до чего пока допер это сделал XML с узлами 1 уровня но прописал параметр показывающий что это пункт меню или пункт подменю (при pmenu="0" - меню при pmenu="1" - подменю)... В подменю прописал переменную которая говорит к какому пункту меню енто подменю относится (NumMenu). Примерно так.

PHP код:

<all_menu>
<
menu name="Меню 0" url="" NumMenu="0" pmenu="0"/>
<
menu name="Меню 1" url="" NumMenu="1" pmenu="0"/>
<
menu name="Меню 2" url="" NumMenu="2" pmenu="0"/>

<
menu name="Подменю 1" url="" NumMenu="0" pmenu="1"/>
<
menu name="Подменю 2" url="" NumMenu="0" pmenu="1"/>
<
menu name="Подменю 3" url="" NumMenu="0" pmenu="1"/>
</
all_menu

Дальше планирую Дублировать ролики для Меню и Подменю в зависимости от переменных, как прогу напишу так пришлю на критику, мож подскажите как лучше дальше будет делать. :)

mooncar 09.06.2011 19:30

Неверный подход к XML...
Много избыточного и вы совершенно не используете вложенность узлов, отражая ею структуру меню. Теряется сам смысл XML.
Например, нет необходимости указывать, к какому меню относится подменю. Это и так следует из структуры XML.
Так лучше:
Код:

<?xml version="1.0" encoding="utf-8"?>
<all_menu>
        <menu id="1" url="" name="Меню 1">
                <submenu id="1" url="" name=""/>
                <submenu id="2" url="" name=""/>
                <submenu id="3" url="" name=""/>
        </menu>
        <menu id="2" url="" name="Меню 2">
                <submenu id="1" url="" name=""/>
                <submenu id="2" url="" name=""/>
                <submenu id="3" url="" name=""/>
        </menu>
        <menu id="3" url="" name="Меню 3">
                <submenu id="1" url="" name=""/>
                <submenu id="2" url="" name=""/>
                <submenu id="3" url="" name=""/>
        </menu>       
</all_menu>

Если проблемы это распарсить, это понятно, напишите об этом.

dark256 09.06.2011 20:48

во. именно. далее читаем про childNodes

vivado 10.06.2011 11:38

Цитата:

Сообщение от mooncar (Сообщение 1002471)
Неверный подход к XML...
Много избыточного и вы совершенно не используете вложенность узлов, отражая ею структуру меню. Теряется сам смысл XML.
Например, нет необходимости указывать, к какому меню относится подменю. Это и так следует из структуры XML.
Так лучше:
Код:

<?xml version="1.0" encoding="utf-8"?>
<all_menu>
        <menu id="1" url="" name="Меню 1">
                <submenu id="1" url="" name=""/>
                <submenu id="2" url="" name=""/>
                <submenu id="3" url="" name=""/>
        </menu>
        <menu id="2" url="" name="Меню 2">
                <submenu id="1" url="" name=""/>
                <submenu id="2" url="" name=""/>
                <submenu id="3" url="" name=""/>
        </menu>
        <menu id="3" url="" name="Меню 3">
                <submenu id="1" url="" name=""/>
                <submenu id="2" url="" name=""/>
                <submenu id="3" url="" name=""/>
        </menu>       
</all_menu>

Если проблемы это распарсить, это понятно, напишите об этом.

Да вы правы так намного красивее, и действительно теперь проблемы с распарсить возникли (((

Цитата:

Сообщение от dark256 (Сообщение 1002489)
во. именно. далее читаем про childNodes

Про childNodes почитал, со своей XML делал так
Код AS1/AS2:

MenuName = menu.firstChild.attributes.name;

а в "правильном" XML я так понимаю нужно
делать примерно так

Код AS1/AS2:

//Для главных менюшек
idMenu = menu.firstChild.attributes.id;
MenuName = menu.firstChild.attributes.name;
//Для подменюшек
idMenu = menu.firstChild.ChildNodes.attributes.id;
MenuName = menu.firstChild.ChildNodes.attributes.name;

Или так неправильно делать, лучше в массив и циклом грузить? Но тогда чето пока я не понимаю как из массива все доставать по id.

mooncar 10.06.2011 12:18

Для вышеприведенного XML загрузка и парсинг:
Код AS1/AS2:

var configXmlPath:String = '';//URL конфигурационного XML
var xmlData:XML = new XML();
xmlData.ignoreWhite = true;
xmlData.onLoad = loadXML;
xmlData.load(configXmlPath);
 
function loadXML (success:Boolean)
{
        if (success)
        {
                var xmlNode:XMLNode = this.firstChild ; //для сокращения записи
                var amountMenu:Number = xmlNode.childNodes.length ;
 
                for (i = 0; i < amountMenu; i++)
                {
                        var menuId:Number = parseInt(xmlNode.childNodes[i].attributes['id']);
                        var menuName:Number = xmlNode.childNodes[i].attributes['name'];
 
                        var amountSubmenu:Number = xmlNode.childNodes[i].childNodes.length ;
 
                        for (j = 0; j < amountSubmenu; j++)
                        {
                                var submenuId:Number = parseInt(xmlNode.childNodes[i].childNodes[j].attributes['id']);
                                var submenuName:Number = xmlNode.childNodes[i].childNodes[j].attributes['name'];                               
                        }
                }
        }
}

1. Получение атрибутов url уж сами по аналогии.
2. Что и когда делать с полученными данными - тоже на ваше усмотрение: можно в цикле загонять в многомерные массивы для последующего использования (правда это тоже избыточно, ведь экземпляр XML с полученными данными - это тоже своего рода массив, по ходу прямо его и использовать), а можно тут же и использовать даннные, в процессе парсинга.
3. parseInt для id - ну это чтобы как-то вычислять можно было, например, или для удобства создания и использования многомерного массива, чтобы по номерным индексам обращаться к элементам, причем эти индексы были бы равны id. Факультативно, можете убрать это приведение к числу.
4. Запись вида attributes['name'] - я так привык просто, строковое имя атрибута выделяется лучше в редакторе кода.

vivado 14.06.2011 14:29

Всем привет. Спасибо за помощь. Благодаря вам кое что начинает получаться.

Код AS1/AS2:

xn=162; //Начальные координаты меню по X
yn=210; //Начальные координаты меню по Y
xrast=78; //расстояние между пунктами меню по X
yrast=15; ////расстояние между пунктами меню по Y
 
var configXmlPath:String = 'menu_horizontal.xml';//URL конфигурационного XML
var xmlData:XML = new XML(); //Создаем переменную
xmlData.ignoreWhite = true;
xmlData.onLoad = loadXML;
xmlData.load(configXmlPath);
 
function loadXML (success:Boolean){
        if (success){
                var xmlNode:XMLNode = this.firstChild ; //для сокращения записи
 
                //Переменная колличества пунктов меню
                var amountMenu:Number = xmlNode.childNodes.length;
 
                for (i = 0; i < amountMenu; i++){
                        //Считываем ID для подменю
                        var MenuId:Number = parseInt(xmlNode.childNodes[i].attributes['id']);
                        //Считываем Url для меню
                        var MenuUrl:Number = xmlNode.childNodes[i].attributes['url'];
                        //Считываем Имя для меню
                        var MenuName:Number = xmlNode.childNodes[i].attributes['name'];
                          //Прикрепляем мувик Меню из библиотеки
                        _root.attachMovie("Menu","Menu"+MenuId,MenuId);
                        //Задаем координаты по x и y для мувика
                        _root["Menu"+MenuId]._x = xn+xrast*MenuId;
                        _root["Menu"+MenuId]._y = yn;
                      //Загружаем переменные Имя Меню и Url
                        _root["Menu"+MenuId].txt_menu = MenuName;
                        _root["Menu"+MenuId].url_menu = MenuUrl;
 
                                //Переменная колличества пунктов подменю
                                var amountSubmenu:Number = xmlNode.childNodes[i].childNodes.length;
 
                                for (j = 0; j < amountSubmenu; j++)        {
                                //Считываем ID для подменю
                                var SubmenuId:Number = parseInt(xmlNode.childNodes[i].childNodes[j].attributes['id']);
                                //Считываем Url для подменю
                                var SubmenuUrl:Number = xmlNode.childNodes[i].childNodes[j].attributes['url'];
                                //Считываем Имя для подменю
                                var SubmenuName:Number = xmlNode.childNodes[i].childNodes[j].attributes['name'];
                                //Прикрепляем мувик Подменю из библиотеки
                                _root["Menu"+MenuId].attachMovie("SubMenu","SubMenu"+SubmenuId,SubmenuId);
                                //Задаем координаты по x и y для мувика
                                _root["Menu"+MenuId]["SubMenu"+SubmenuId]._x = 0;
                                _root["Menu"+MenuId]["SubMenu"+SubmenuId]._y = _root["Menu"+MenuId]._y/yn+15+yrast*SubmenuId;
                                //Загружаем переменные Имя Подменю и Url
                                _root["Menu"+MenuId]["SubMenu"+SubmenuId].url_submenu = SubmenuUrl;
                                _root["Menu"+MenuId]["SubMenu"+SubmenuId].txt_submenu = SubmenuName;
                        }
                }
        }
}

Меню распарсинговано и приаттачено, теперь хочу сделать чтоб соответствующие пункты подменю раскрывались и скрывалось при подводе мыши к основным пунктам меню. Хочу спросить совета, как лучше это сделать.

Думаю сделать это так.
Способ 1. Аттачить мувики Подменюшек в отдельный мувик (например в какой-нибудь listSubMenu) расположенный в мувике пунктов Меню, который по умолчанию будет скрыт (_visible=false) а потом на пункт Меню повесить:
Код AS1/AS2:

onRelease = function() {
listSubMenu._visible=true.
}

Способ 2. Писать условие для каждого из главных пунктов меню, чтото типа
Код AS1/AS2:

 if (MenuId=="0"){
_root["Menu"+MenuId].onRollOver = function() {
listSubMenu.gotoAndPress(1); //отображаем подменю для Меню 0
};
 if (MenuId=="1"){
_root["Menu"+MenuId].onRollOver = function() {
listSubMenu.gotoAndPress(2); //отображаем подменю для Меню 1
};
 
//и т.д.

Подскажите как будет правильнее.
Вот ссылка на текущий исходник.menu

dark256 14.06.2011 15:32

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

vivado 14.06.2011 16:01

Цитата:

Сообщение от dark256 (Сообщение 1003651)
Спрашивать "как лучше" - не имеет ровно никакого смысла. Ибо вам тут сейчас предложат 100 вариантов и вы утонете во вводных.
Надо просто сесть и делать. На это может уйти час, день, неделя, месяц.
В любом случае чужой опыт Вам не пригодится.
Каждый сам, лично должен наступить на все грабли, чтобы ориентироваться в процессе в дальнейшем.

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

Задача 1 решена, меню парсится из xml и все данные грузятся. Приступил к тому о чем собственно тема, к созданию вертикального разъезжающегося меню (а ля аккордеон). Мучаюсь над написанием функции которая будет "раздвигать" менюшки. Сново взываю о помощи )))

Итак я вижу это так в функцию должны передаваться
1. Имя "активного" меню
2. Кол-во пунктов подменю этого меню (чтоб знать на сколько опустить/поднять ниже расположенные пункты меню

Добавлено через 23 часа 23 минуты
Сломал мозг слегка но что то родилось, правда опять как то криво работает (((
Код AS1/AS2:

function SlideMenu(NumSelectedMenu,NumPodmenu){ //Раздвигает пункты меню
NumPodmenu=NumPodmenu/3; //Так надо не обращайте внимания )))
 
trace("Номер выбранного меню "+NumSelectedMenu+" в нем подменю "+NumPodmenu+" Всего пунктов меню "+PunktovMenuVsego);
hpodmenu=20; //высота пункта подменю
 
if (NumSelectedMenu<PunktovMenuVsego){ //Если Номер выбранной менюшки меньше чем всего менюшек
        MoveMenuStart = NumSelectedMenu; //Первое меню под активным
        _root["Menu"+MoveMenuStart]._y=NumPodmenu*hpodmenu; //Сдвигаем вниз первое меню под активным
        trace ("Опускаем Menu "+MoveMenuStart);
}
OtherDownMenu=MoveMenuStart+1;
for ( r = OtherDownMenu; OtherDownMenu<PunktovMenuVsego; r++){
        //Опускаем остальные менюшки
        i++;
        _root["Menu"+r]._y=_root["Menu"+MoveMenuStart]._y+hpodmenu*i;
        trace ("Опускаем Menu "+OtherDownMenu);
        OtherDownMenu++; //к следующей менюшке
 
}
}

Гляньте что не так пожааалуста...
Вот исходник Меню

Nina 15.06.2011 16:11

А зачем вводить переменную?
Код AS1/AS2:

MoveMenuStart = NumSelectedMenu; //Первое меню под активным


vivado 16.06.2011 13:03

Цитата:

Сообщение от Nina (Сообщение 1003894)
А зачем вводить переменную?
Код AS1/AS2:

MoveMenuStart = NumSelectedMenu; //Первое меню под активным


Ну да чето я лишнего понаписал )))
Вот так будет лучше.

Код AS1/AS2:

function SlideMenu(NumSelectedMenu,NumPodmenu){ //Раздвигает пункты меню
NumPodmenu=NumPodmenu/3; //Так надо не обращайте внимания )))
 
trace("Номер выбранного меню "+NumSelectedMenu+" в нем подменю "+NumPodmenu+" Всего пунктов меню "+PunktovMenuVsego);
hpodmenu=23; //высота пункта подменю
 
MoveMenuStart = NumSelectedMenu+1; //Первое меню под активным
//OtherDownMenu=MoveMenuStart+1;
for ( r = MoveMenuStart; r<PunktovMenuVsego; r++){
        //Опускаем остальные менюшки
        _root["Menu"+r]._y=_root["Menu"+NumSelectedMenu]._y+hpodmenu*i;
        trace ("Опускаем Menu "+r);
        i++;
}
}

Теперь нужно придумать как обратно менюшки возвращать при отведении мышки. Наверное нужно переменную для предыдущей активной менюшки ввести и отслеживать ее координаты. Блин как все запущено (((

Добавлено через 2 часа 19 минут
УРА У МЕНЯ ВСЕ ПОЛУЧИЛОСЬ!
Вертикальное и горизонтальное XML меню на AS 2.0 готово!
МОжет конечно код кривоват + кое-где он размещен на мувиках (знаю, знаю, что это плохо,
но не смог сделать по другому) но в конце концов все работает и я счастлив )))
Выкладываю работающие исходники, может кому пригодится.

Горизонтальное и вертикальное XML меню


Часовой пояс GMT +4, время: 19:01.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.