Posts filed under 'AS2.0'

Анимация Stroke Line.

Задача – надо анимировать линию, летящую по произвольному пути. )) Stroke эффект одним словом.
Задача 2 – анимировать процесс рисования некоей произвольной фигуры.

Если кому то много букв — смотрим видео версию.
Если кому то жалко трафика — читаем ниже.

Все может быть решено довольно просто.

1. Рисуем законченный путь нашей линии (кривая)
step1
2. Дублируем кривую на новый слой.
3. Создаем круглый шейп и конвертируем его в графический клип.
4. Слой с дублем кривой превращаем в моушн-гайд для круглого шейпа.
5. Делаем анимацию шейпа по всему пути.
step5
6. Выделяем фреймы с моушнГайдом и шейпом, вырезаем их и создаем новый графический символ в билиотеке, куда и вставляем вырезанные фреймы. Или пользуемся необычайно полезной штукой Layers manager, который можно найти тут:  http://flash-animation.ru/category/plugins/ (Лерика, если ты это читаешь поправь линки! Прямая ссылка на пост о плагине не работает!!!)
7. Временно переводим моушнГайд в обычный слой, чтобы видеть путь в клипе маски.
8. Возвращаемся на сцену – совмещаем кривую и клип.
step8
9. Возврашаемся в клип маски, и восстанавливаем моушнГайд для слоя с кривой.
10. Слой с клипом, в котором находится анимация превращаем в маску для слоя с изначальной кривой. Ура.
step10
Задача 2.
1. Переводим клип с анимацией в ранг MovieClip. Дадим ему instance-имя masker.
2. Обернем masker в еще один мувиКлип с instance-name = mask_mc
3. Конвертируем кривую в мувиКлим с instance-name = line_mc
4. Пишем на таймлайне с линией и маской нехитрый код.

var mask_count:Number = 1;
mask_mc.masker.stop();
onEnterFrame = function():Void
{
	var mc:MovieClip = mask_mc.masker.duplicateMovieClip("mask"+mask_count,mask_count);
	mc.gotoAndStop(mask_count);
	if(mask_count == mask_mc.masker._totalframes)
	{
		delete onEnterFrame;
	}
	mask_count++;
}
line_mc.setMask(mask_mc);

5. Готово.

Popularity: 23% [?]

10 комментариев апреля 29, 2009

Умные колеса.

Сейчас я работаю над одним весьма интересным проектом — это будет всего лишь интерактивная  флеш-шапка, но она будет полна анимации с алогичным волшебством: кони-рыбы, люди-фрукты и так далее ))

В процессе работы, я уверен, будет накапливатся масса интересных и полезных мелочей, коими я конечно же поспешу поделиться. Сейчас таких мелочей есть две: программный растеризатор сложного вектора. Вектора будет много, и он как пить дать убъет процессор; пришлось выдумывать хитрые вещи. Но об этом позже, сначала я должен убедиться в эффективности выбранного решения ))

Сегодня же я расскажу о колесах. Будет скрипт )) Несложный, но он даст нам чудное колесо, и оно будет вращаться в точности в соответсвии с тем, как далеко продвигается то, к чему это колесо крепится ))) Итак, под кат, там есть небольшой мультик ))

 

Оставим пока лошадей ) (Я намерен, кстати выложить видео запись процесса работы над этой анимацией – так сказать серия Animator at work)
Понаблюдайте за каретой. Колеса, как видите вращаются весьма правильно )) Они следуют всем законам земным и божеским. Вы думаете, я сидел с линейкой и мерял кадр за кадром – каково смещение? Нет. Я вспомнил, что в школе я неплохо разбирался в геометрии ))
Итак, каждое колесо запаковано в мувиКлип, сама карета с ее вложенной анимацией также упакавана в мувиклип.
Каждый клип колеса имеет точку регистрации ровно в его центре, чтобы колесо вращалось вокруг своей оси.
Из геометрии мы знаем формулу длины окружности L = 2PI*R, где R – радиус.
В правильном колесе радиус – это половина ширины клипа.
Рассуждаем логически: когда наше колесо повернется на 360 градусов, оно должно сместиться на расстояние L. Супер! Значит, если колесо повернется на один градус, расстояние будет равно L/360! Запомним это число,  и повесим на колесо событие onEnterFrame в котором смотрим — на сколько сместилась карета (моушвтины тоже считаются!), и считаем угол поворота – дистанцию делим на L/360. Вуаля.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
init(wheel1); // обучаем первое колесо
init(wheel2); // обучаем второе колесо
 
function init(mc:MovieClip):Void
{
	mc.radius = mc._width/2; // собрали радиус
	mc.baseX = mc._parent._x; // запомнили начальную позицию кареты
	// l = 2PI*R - ах, геометрия...
 
	mc.degreeLength  = (2*3.1415926*mc.radius)/360; // смещение при повороте на один градус
	mc.onEnterFrame = function():Void
	{
		var distance:Number = this.baseX - this._parent._x; // на сколько сместилась карета?
		this._rotation = -distance/this.degreeLength; // поворачиваем колесо
	}
}

Popularity: 16% [?]

3 комментария апреля 24, 2009

Разбираемся с SWFAddress

В сети море полезных фреймворков, классов и решений различных задач.
Однако очень многие из них имеют существенный недостаток – УЖАСНАЯ, если вообще присутствующая документация.

Недавно я прикоснулся к магии SWFAddress, библиотеке AS+JS, решающей проблему deep linking для FLASH и AJAX.
Для таких как я (гуманитариев и не-программистов) предлагаю свой опыт по освоению СВФАдреса.
Нет. Документацию на русский язык я переводить не буду. Не вижу в этом смысла. Документация более чем минималистическая. С тем же успехом ее можно было бы вообще не писать. В прочем + от нее все же есть – сводная таблица всех доступных в классе методов.

Первое что следует сделать – это скачать библиотеку. Настоятельно рекомендую качать 7-мегабайтовый архив с примерами и документацией. Потому что, как выяснилось в процессе, если бы я ограничился скачиванием только классов — меня бы постигла неудача, и я бы так и не понял в чем дело. А непоняток-ошибок на пути встретилось некоторое количество )

Первая ошибка. Исторически сложилось так, что я работал над сайтом, к которому намеревался прикрутить SWFAddress на завершающем этапе. Собираетесь использовать дип линкинг – сразу работайте с SWFAddress. Дело в том, что любое изменение адресной строки браузера (А это именно то, зачем нам вообще нужен дип линкинг) вызывает событие SWFAddress.onChange. То есть фактически и переключение разделов из флеш сайта (конечно если оно должно вести к изменению в адресной строке) , и переключение разделов извне (навигация по кнопкам ВПЕРЕД НАЗАД ,навигация по якорям на хтмл-странице и т.д.) вызывает это событие. В сущности на нем как раз и будет строиться обработка события переключения между разделами.
Ошибка вторая. Я доверился заявлению Flash CS3 Support. Фактически же, если публиковать ролик на странице с помощью AC_RunActiveContent.js, которое генерируется Flash IDE – дип линкинг не работает. Изменения в адресной строке – да, но ролик не реагирует на навигацию из браузера. Я дошел до этого знания случайно. Потеряв веру в свой мозг, я просто взял рабочий пример, и заменил в нем флешку на свою – и все заработало. Путем исключений я нашел камень преткновения. Каким то образом AC_RunActiveContent.js из примера отличается от того, что генерируется FLASH CS3 IDE. Так что пользуйтесь скриптом из примеров. Что касается работы с SWFObject и UFO – не проверял. У вас есть отличная возможность сделать это за меня, а потом отписаться здесь, если пожелаете.

Теперь о некоторых тонкостях и внутренностях. В архиве есть коды для всех трех версий AS. Мои опыты ставились на AS2.0

1. Класс написан как TopLevel-класс, или для тех кто не понимает этого словосочетания, – он не создает экземпляров. Пример такого класса -Math, все функции в нем вызываются подобным образом: Math.sin(), Math.round() и т.д. То же справедливо и для SWFAddress.

2. Адресная строка.
Для решения задачи дип линкинга, к существующему URL добавляется якорь # за которым следует строка, которую разработчик волен генерить сам, по своим правилам, и сам же по своим правилам ее и разбирает. Есть два режима. setStrict(true) – в конце адреса жестко добавляется слеш (/) и setStrict(false) – никаких слешей без ведома разрабочика.

3. Основные полезные методы.
В классе присутствует набор методов для разбора строки. Весьма удобно.
К примеру в адресной строке имеем

http://flashsite.com/#news?page=&img=2

SWFAddress.getValue():String - вернет значение строки аккурат после # со всеми Вашими изысками (парами имя=значение)

news?page=1&img=2

SWFAddress.getPath():String - вернет значение строки аккурат после # без дополнительных параметров
news

SWFAddress.getQueryString():Array - вернет строку с дополнительными параметрами

page=1&img=2

SWFAddress.getParameterNames():Array - вернет массив с именами дополнительных переменных
page,img

SWFAddress.getParameter(value:String):String - вернет значение дополнительного параметра указанного в value
getParameter(«page») // 1;
getParameter(«img») // 2;

Для того чтобы изменить адресную строку из FLASH существует метод setValue(value:String) – помните, что вызов этого метода автоматически приведет к вызову события onChange, так что фактически переключение между разделами сводится к замене значения адресной строки и последующей обработке события.

Остальные методы описывать не стану, они весьма просты и даже данных документации хватит для их освоения.

4. События.
Я уже говорил о событии onChange. Должен отметить, что событие это вызывается сразу же, при первом же упоминании класса, равно как и событие onInit. Большого смысла в событии onInit я не уловил. В самом начале оно вызывается и тут же за ним вызывается onChange. Возможно есть смысл для более четкой структуризации, и отделении инит-процедур от собственно обработки переключений между разделами.

Более подробно поговрим о событии onChange, хотя в случае с onInit все работает абсолютно так же, за исключением значения cвойств SWFAddressEvent: path=null; value=null; type=init;

События доступны в двух ипостасях:

SWFAddress.onChange = function():Void
{
    trace("SWFAddress.onChange");
}

В данном случае мы просто определяем статичную функцию onChange.

Второй вариант – подписать любой свой объект на событие. Во многом это удобнее, чем описывать вложенные функции с обработчиком события.
К примеру мне удобно подписать экземпляр класса, который напрямую работает с SWFAddress. Для этого я сначала создаю функцию обработчик:

public function onChange():Void \
{
   trace("Class's onChange");
}

И далее подписывась на событие с помощью метода класса SWFAddress – addEventListener(type:String,listener:Function);
Поскольку в этом учавствует стандартный mx.utils.EventDispatcher, нужно подписаться так, чтобы наша функция onChange знала кто в доме хозяин – то есть надо жестко определить this. Делается это при помощи mx.utils.Delegate.create().
Итак подписка на событие для нашего экземпляра будет выглядеть так

SWFAddress.addEventListener("change",Delegate.create(this,onChange));

Теперь мы можем из тела функции onChange обращаться ко всем свойствам и методам нашего экземпляра. Ура.
Продвинемся дальше. В том случае, если мы подписываемся на событие, в качестве параметра в наш обработчик приходит экземпляр SWFAddressEvent, который несет в себе ценную информацию :)
Модифицируем наш обработчик.

public function onChange(evt:SWFAddressEvent):Void
{
  //вернет путь после # из адресной строки БЕЗ параметров
  trace("path:"+evt.path);
  //вернет  путь после # из адресной строки С параметрами
  trace("value:"+evt.value);
}

Также событие несет информацию о своем типе (type=»change» или «init»), target (это всегда отсылка на SWFAddress) а также массив parameters («ассоциативный») с параметрами из queryString. Если в адресной строке есть news?param=value, то значение param можно получить так : SWFAddressEvent.parameters.param

Какие замечены баги.

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

2.Если вручную вставить адрес в браузерной строке в FireFox – адресная строка перестает изменяться, когда переключаешься между разделами. Вроде как адреса заносятся в history, навигация вперед.назад работает, но это не отображается в адресной строке. В принципе – я лично замечал вообще странное поведение адресной строки в Фоксе, и без дип линкинга, например иногда в ней просто невозможно перенабрать адрес.

Работоспособность проверена на:

  • Mozzilla FireFox 2.0.0.12
  • Opera 9.10
  • IE 6.0
  • Safari (win) 3.0.3

В завершении могу только дать ссылку на первый свой опыт с SWFAddress, где вы можете потестировать работоспособность библиотеки в разных браузерах. Будет полезно, если здесь вы запостите свои баг репорты, ну или зададите вопросы о том, что осталось непонятным. Цель этого топика – сделать эту бесспорно полезную опцию более доступной всем категориям разработчиков )) Поэтому -включайтесь )

http://kvadra.net/samples/goodpeople/_flash/#chillout/two?pgid=2t&imgid=36

Popularity: 62% [?]

25 комментариев февраля 26, 2008

_quality = LOW. Производительность против дизайна.

Самое мое любимое качество – LOW. Очень быстро, но смертельно для вектора.

В некоторых случаях, можно с легкостью пользоваться этим чудным режимом, оставляя за собой право на гладкие линии))
Рецепт прост. Если мы имеем дело со статичным вектором, то мы можем сделать с него слепок в битмапДату при режиме _quality=»HIGH», а затем переключиться на LOW и вывести уже не вектор, а битмапДату. Просто до безобразия.

Более того, замечено, что текст с типом рендеринга ADVANCED – не подвластен козням качества LOW.
ПРи должной сноровке, несложно написать класс, который переводил бы нужный вектор в битмап дату. МОжно даже продумать подобные фокус с анимированными векторами (массив фрейм_в_битмап) Конечно в данном случае больше нагрузки идет на ОЗУ, но в основом именно нагрузка на CPU дает притормаживание.

Пример:

Код фокуса:

import flash.display.BitmapData;
_quality="BEST";
var bmp:BitmapData = new BitmapData(oval._width,oval._height,true,0);
bmp.draw(oval);
_quality = "LOW";
this.createEmptyMovieClip("mc",1);
mc._x = oval._width*2;
mc._y = oval._y;
mc.attachBitmap(bmp,1);

Ссылка по теме: http://www.bytearray.org/?p=117

Popularity: 11% [?]

2 комментария февраля 6, 2008

BitmapData + mask = мертвый браузер.

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

Коротко об алгоритме:

1.В библиотеке есть клип для маски (дабы прямоугольный кусок растра оформить в «фигурный» контур).
2. Там же, в библотеке, несколько растров с linkageID.
3. Создается временный клип, аттачится маска, временный клип маскируется.
4. Создается временная битмапДата, аттачится во временный клип (Под маско получается картинка «в рамке»)
5. Создаем еще одну битмап дату, делаем слепок с маскированного клипа.
6. Заносим полученную битмапу в массив, для дальнейшего использования.
7. Убираем временные клипы, диспоузим временный битмап.

При этих нехитрых действиях, дебаг, стендалон – работаю как и предполагается.
Браузер (любой) вылетает, сообщив о б ошибке.

Опытным путем, установил, что проблема в маске. И это же навело меня на решение.
Перед тем , как задать маску, нужно и маскируемому, и маскиующему клипам задать свойство cacheAsBitmap = true. И хотя особоенно логичного объяснения я этому не вижу – плагин принимает такой вариант.

Popularity: 7% [?]

февраля 5, 2008

Новое в классе FileReference

Недавно в блоге GarbageCollector появилась статья о новых событиях класса NetStream.

Я в свою очередь ) недавно обнаружил некоторые нововведения и в классе FileReference, впервые появившемся в Macromedia Flash 8.


Когда я впервые стал смотреть на возможности этого класса, меня разочаровало то, что на сервер вместе с загружаемым файлом можно отправить данные только GET-методом. (Классический урл-запрос с парами переменная=значение). Также нельзя было получить от сервера никаких данных, по завершении загрузки.

Недавно вновь обратился к этому классу, но уже в Adobe Flash CS3 – и, о чудо! Новые свойства и события, как раз на эту тему.

Новое свойство postData:String. – Как видно из названия (опыты подтверждают) – POST параметры, которые отправляются на сервер вместе с загружаемым файлом.
Польза? Как минимум отправка сложной формы, включающей некий файл (картинку, звук, архив) на сервер. Данные формируются строкой из все тех же пар переменная=значение.

Новое событие:

1
onUploadCompleteData  =  function (fileRef:FileReference, data:String) {};

Как видно из конструкции – по завершению аплоада, если сервер отдает какие то данные в ответ, то мы можем их получить в переменной data:String. Очень удобно хотя бы для того, чтобы сообщить пользователю, что его драгоценные данные отправлены и приняты.

Вот такие бонусы. Добавлю только, что все это работает в плеере 9.0.r28 и выше.

Popularity: 8% [?]

2 комментария января 29, 2008

Первая помощь флешовому HTML Render-у

Форматирование текста с помощью HTML во флеш,что ни говори – гораздо удобнее, чем форматирование с TextFormat, практически в любой ситуации.

Если Вас сильно огорчает сильно урезанный набор тегов, который HTML парсер флеша понимает – читайте дальше.

Итак, что мы имеем в распоряжении:
P, B, I, U, A, BR, LI, I, IMG, SPAN, TEXTFORMAT, FONT.

Как видим – ни хедеров, ни STRONG, который рекомендуется вместо B. Заставить флеш-хтмл-парсер понимать h1, h2…. strong, em не прибегая к хакам – елементарно.
У нас же есть законный TextField.StyleSheet. А с помощью css можно форматировать любой XML документ. Грамотный HTML – это тот же XML, поэтому нам достаточно описать в каком виде мы хотим видеть наши заголовки, описать strong, em – и все что нам нужно в таблице стилей.

Маленькая странность – любой неподдерживаемый тег, описанный в таблице стилей – разрывает строку. В случае заголовоков это даже полезно, а вот strong, разрывающий пасть строке – это экзотика К счастью флеш поддерживает свойство display. Так что display: inline – поставит все на свои места.

Дружите с цсс+хтмл. Великий поклон разработчикам за то, что они избавили меня лично от необходимости повсеместно пользоваться текстФорматом. Даже за такой куцый парсер хтмл.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// стиль
var style_string:String = "h1 {font-size: 20; font-weight: bold} ";
style_string += "strong {font-weight: bold; display: inline;}";
var style_css:TextField.StyleSheet = new TextField.StyleSheet();
style_css.parseCSS(style_string);
// текст
var html_text:String = "
</code>
<h1>Нeader</h1>
";
html_text +="<strong> Very strong line </strong>";
html_text +="usual text";
 
// текстовое поле
var tf:TextField = this.createTextField("tf",0,10,10,400,200);
tf.multiline = true;
tf.wordWrap = true;
tf.border = true;
tf.html = true;
tf.condenseWhite = true;
tf.styleSheet = style_css;
tf.htmlText = html_text;

Ну, а если требуется что-то более продвинутое – посмотрите на компонент HTMLRenderer Андрея Горбатова: http://gorbatov.blogspot.com/…/htmlrenderer

Popularity: 10% [?]

Один комментарий января 28, 2008

Прелоадер для ‘img’

TextField – субстанция крайне интересная, взбаломошная и мистическая.
Обуздание оной подчас превращается в подвиг Геракла.
Несколько статей о TеxtField я обязательно размещу на страницах этого блога.

Многие знают, что в текстовое поле с подключенным html можно грузить картинки и флешки, а также вставлять символы из библиотеки.
Но вот вопрос – а можно ли взаимодействовать с этими объектами? Например возможен ли прелоадер?

ДА и очень просто. Фактически тег <IMG> создает внутри тексатового поля новый MovieClip. Если в html-коде прописан id для IMG, то будет создан клип именно с таким instance name. И обращаться к этому клипу можно через текстовое поле. К примеру если в текстовое поле my_txt внедряется картинка

<img id="img" src="http://yoursite.com/images/someIMG.pg" alt="" />

То мы можем обратиться к ней my_txt.img

Но что если у нас есть html-текст с img без id, и таких картинок много, а нам необходимо сделать скроллер для текстового поля. Пока картинки не загружены мы с большой долей вероятности получим неверную высоту поля.
Есть простой способ – нам нужно просто завести массив для учета встроенных картинок

var htmlIMG:Array = [];

И пройтись по текстовому полю циклом for…in, помня, что картинки – это объекты типа MovieClip.

for (var mc in my_txt)
  {
     if(typeof(my_txt[mc]) == "movieclip")
     {
         trace("found IMG: "+my_txt[mc]);
         htmlIMG.push(my_txt[mc]);
     }
}

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

Popularity: 9% [?]

5 комментариев декабря 11, 2007

ScrollRect vs setMask

На заметку.

Если нужно применить к клипу прямоугольную маску, вместо MovieClip.setMask(mc:MovieClip) лучше воспользоваться свойством scrollRect (доступно от 8-й версии и выше).

Плюс в производительности на лицо. Более того – под такой «маской» не пропадают системные и не-внедренные шрифты.

Использование предельно просто:

1
2
3
import flash.geom.Rectangle;
var maskRect:Rectangle = new Rectangle(x,y,width,height);
my_mc.scrollRect = maskRect;

С такой «маской» удобно делать также и скроллеры (собственно название выдает).
Достаточно поменять значение x, y для Rectangle, и визуально мы видим смещение контента мувиКлипа.

Popularity: 12% [?]

7 комментариев декабря 9, 2007

SmartFont

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

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

Вашему вниманию мой класс SmartFont.
На сайте поддержки описаны все телодвижения, здесь же упомяну только общий ход использования:

1
2
3
4
5
6
var my_font:SmartFont = new SmartFont();
my_font.load("someFont.swf");
my_font.onLoad = function():Void
    {
     trace("Шрифт: "+this._font+" готов к использованию");
    }

Popularity: 1% [?]

декабря 6, 2007




МЕТА

Метки

2d 3D ActionScript adobe ae after effects animation animator_at_work AS2.0 AS3.0 astro bones bug bugfix debug deep linking draw drawing extension Flash flash CS4 flex fscommand fx html IK Math mindstream music-video NB opensource security swfaddress TextField traps uafpug useful utils video Новости анимация кинематика кости поток сознания туториал

Календарь

Сентябрь 2010
Пн Вт Ср Чт Пт Сб Вс
« Июл    
 12345
6789101112
13141516171819
20212223242526
27282930  

Архив

Ссылки

Радио