суббота, марта 29, 2008

Первый законченый проект на Flex. Грабли и впечатления.

Вот закончен еще один проект. И отличие его от предыдущих - это чистый Flex-проект построенный на MXML-верстке.

О проекте

Вкратце - результат проедставляет собой презентацию-каталог (оффлайн, версия для CD/DVD и версия для TouchScreen), в котором основной элемент - интерактивная карта России, разделенная на регионы. По клику на регионы осуществляется его увеличение и вывод городов. По клику на город, выводится панель со списком типов объектов (презентуемых заказчиком). По клику на тип объекта, открывается список самих объектов с фото-превьюшками и описаниями. По клику на описание объекта выводится более подробное описание с теми же фото-превьюшками, по клику на которые показывается крупное фото. Кроме того - два доп-раздела "О компании" и "Контакты".

На flash-разработку проекта я выделил две недели, т.е. в реальных условиях менее 10 рабочих дней.

На распутье

Сначала возникло желание делать проект на моем старом (правильнее сказать - устаревшем) но отработанном презентационном движке AS2. Но структура проекта совсем не похожа на послайдовку, поэтому возник соблазн сделать презентацию другим способом, и полностью задействовать Flex.

Дизайн-макет, на первый взгляд, показался довольно сложным, но глаз уже уловил, насколько выигрышно было бы использовать Flex-верстку. Верстать и программировать динамические списки, поставляемые выборками из XML-базы, "ручками" на AS2 - тоска.

Опыт работы с Flex за плечами уже есть, AS3 освоен. Но имеют место сомнения: "А вдруг упрусь в какую-нибудь проблему или глюк, и сроки полетят?" "Сроки жесткие, может быть лучше по-старинке, AS2?" "Зато уверенность, стабильность и предсказуемость". После часа раздумий, решился рискнуть - Flex.

За работу

Моя рабочая платформа - Flex Builder 3 Plug-in for Eclipse.

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

Взаимодействие пользователя представляет собой сложную систему состояний экрана. Решил использовать систему состояний Flex (states). И сделать это так - сначала сверстать все элементы приложения в базовом состоянии, а потом создать ряд состояний для каждого этапа работы приложения, в которых скрывать/открывать и трансформировать элементы.

При верстке проблем не возникло. Очень напоминает верстку сайтов. При помощи стилей можно творить чудеса - использовать скины даже не потребовалось. Всё необходимое было сверстано совсем без затыков за один-два дня. Впечатления самые положительные.

Параллельно, моим коллегой готовилась флэшка с картой. Клип с картой подгружается компонентом mx:SWFLoader. Сначала мы решили сделать ее в виде большого таймлайна, и навигация по карте осуществлялась бы командами gotoAndPlay(""). Выбор такого решения (конечно не очень удачного) был обусловлен желанием сделать карту в виде видео-ролика с 3D-эффектами. В итоге сроки свели задачу к простой флэш-анимации :). Позже стало ясно, что способ тайм-лайновой анимации совсем не интересен и карту анимировали программно Tween-ом.

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

Зашивание проекта в Zinc особых трудностей не составило. Zinc спокойно интегрируется во Flex-проект. Использовались основные объекты глобального класса mdm:
mdm.Application - для получения директории, из которой запускается приложение,
mdm.Application.Library - для работы с библиотекой приложения.
mdm.FileSystem - для тестирования наличия файлов.

В итоге, хочется сказать, что проект завершился успешно. Скорость разработки на Flex превзошла мои ожидания, и сэкономленное время позволило дополнительно отладить и отточить приложение (переделать анимацию интерактивной карты коренным образом). Впечатления от работы с Flex остались самые положительные, и я рад, что рискнул.

* * *

Ниже изложено несколько нехороших ситуаций:

Неверно спроектированная верстка

Дизайн-макет был разработан на разрешение 1600х1200 - для TouchScreen. Позже, когда приложение было уже на этапе отладки, выяснилось, что нужна еще одна версия - предназначенная для распространения на CD/DVD, а значит, под меньшее разрешение. Пришлось срочно переверстать новую версию под 1024х768. Если бы я изначально заложился под трансформируемую верстку (благо, во Flex эта возможность реализована превосходно), лишней работы делать бы не пришлось. И версии можо было бы не плодить. На будущее - нужно изначально закладываться на гибкую верстку - стоит того.

Внедрение шрифта формата .OTF

При внедрении шрифта возникла следующая проблема. Мне необходимо внедрить шрифт MyriadPro. Это TrueType-шрифт формата .OTF.
Код внедрения в стили:


@font-face
{
font-family: MyriadPro;
font-weight: normal;
src: url("Assets/Fonts/MyriadPro-Regular.otf");
unicode-range:
U+0020-U+0040, /* Punctuation, Numbers */
U+0041-U+005A, /* Upper-Case A-Z */
U+005B-U+0060, /* Punctuation and Symbols */
U+0061-U+007A, /* Lower-Case a-z */
U+007B-U+007E, /* Punctuation and Symbols */
U+00FC-U+00FD, /* UE */
U+0410-U+042F, /* Cyrillic Upper-Case */
U+0430-U+0451; /* Cyrillic Lower-Case */
}

В окне FB Design шрифт отображается некорректно, выдает ошибку транскодирования: "Exception during transcoding: Font for alias 'MyriadPro' with plain weight was not found at: ...MyriadPro-Regular.otf ..." И то же самое для версии "bold".
Однако, при компиляции проекта ошибки нет и в приложении шрифт отображается корректно на разных компьютерах. Отнес это к проблемам (читай - глюкам) средства визуальной разработки FB.

Эффект появления/скрытия и states

Пришлось повозиться с эффектом mx:Fade, используемого для появления/скрытия некоторых компонентов.

По началу я предположил, что если я создам эффекты Fade (один для появления и другой для скрытия) и укажу его для некоторых компонентов в стилях showEffect и hideEffect, то при смене состояния, при изменении свойства visible, компоненты будут плавно появляться/исчезать. Как бы не так. При формировании состояния, выполняются (тупо, без каких либо перепроверок и оптимизаций) все действия - начиная с базовых состояний. Если в базовом состоянии visible устанавливается в false, а в текущем, базирующемся на нем, в true, то будет выполнено два действия со всеми вытекающими последствиями. Если Fade-скрытие еще не успело завершится, а уже вызывается Fade-появление, то последнее будет просто проигнорировано. Короче - полный разлад и совсем не адекватный результат. То же самое относится и к другим видам эффектов.

Для анимации такого рода необходим другой прием. При использовании transitions всё сразу встало на свои места. Конечно, это принесло другие сложности, но зато эффект появления/скрытия работает как часы.

Маскирование контента SWFLoader

Проблема связана со следующей особенностью. Клип интерактивной карты в процессе работы приложения может трансформироваться (трансформируемый клип расположен в главном таймлайне загружаемой флэшки). Но он должен отображаться в строго отведенной прямоугольной области. Казалось бы, чего проще - поместить его в Box, у которого horizontalScrollPolicy="off" verticalScrollPolicy="off" clipContent="false". Не работает. Причем странно - пока клип карты перемещается, границы отсекаются. Как только клип останавливается, всё что вылезает за пределы области появляется.

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

Воспроизведение FLV

В самом конце столкнулись со следующей проблемой. Презентация начинается с видео-заставки. Заставка - файл FLV, который подгружается в mx:VideoDisplay. Проблема заключалась в том, что компонент отказался воспроизводить внешнее видео, если презентация находится на удаленном сервере (с этим то всё ясно - включена опция -use-network=false), или на сменном носителе - записанная на CD/DVD (а вот это - критично).

К сожалению, FLV нельзя внедрить посредством @Embed. Но это может сделать Zinc, чем я немедленно воспользовался. Но такое решение не самое красивое. В дальнейшем придется выяснить, почему не воспроизводится FLV со сменных носителей, и как этого избежать. Возможно, необходимо установить параметры безопасности, а может быть проблема связана с задержками доступа к CD/DVD приводу в связи с чем, что-то рассинхронизировалось в приложении.

3 комментария:

Анонимный комментирует...

А если FLV сначала внедрить в SWF как MovieClip, дать ему ID, а потом подцепить во Flex как @Embed? Я не пробовал, но должно же получиться, по идее.

Unknown комментирует...

Да, безусловно это заработает.
Но мы же легких путей не ищем ;).

В идеале хотелось, чтобы при необходимости изменения видео-заставки, достаточно было его просто отсчитать и заменить flv-файл не прибегая к помощи флэшера.
Жаль, что не получилось. Будет время - попробую разобраться.

Анонимный комментирует...

Не нашел Ваших контактов, поэтому пишу тут. Просмотрел блог и подумал, что, возможно, тут могут помочь с глобальной проблемой Flash - ввод русских символов, когда заместо того, что вводишь, отображаются иероглифы.
Система Kubuntu 7.10, все на UTF-8. Можно ли как-то эту проблему решить? Или ввод русских символов возможет лишь при cp1251?