FireFox. FlashTracer. FlashPlayer9 debug

Давно не писал, ибо пребываю сейчас в экстремальном непроходящем дебаге ))

О нем и будет короткая моя речь ))

Недавно вышла новая весрия флеш плеера, о чем было уже писано переписано, все дружно обновились, я полагаю ). В куче мы могли также качать дебаг-версию.
И тут я вспомнил, что FlashTracer – милый плагин под файрФокс, позволяющий выводить трейс из флешек в режиме браузера, перестал откликаться, если я использую 9-ю версию дебаггера.

Как оказалось, такая проблема постигла не только меня. Решение найдено, спасибо Silin-у, подсказал верную мысль )

Дело в том, что я мануально поменял путь к файлу flashlog.txt, вытащив его из длинной цепочки C:\Documents and Settings\user\Application Data\Macromedia\Flash Player\Logs немного поближе.
Так вот флешки, опубликованные под версию плеера НИЖЕ 9-ки спокойно отдавали свои логи в этот файл В ЛЮБОМ дебаг плеере (тут конечно участие принял другой полезный аддон для FF – FlashSwitcher). Зато флешки, требующие как минимум 9-ю версию – тихо сдавали свои логи все по тому же длинному адресу по умолчанию, оставляя указанный мной flashlog.txt без должного внимания. Импичмент, понимаешь.

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

PS. Кажется меня приняли в мксня-аггрегатор. Тут и проверим )) Ответсвенность то какая ))

Popularity: 3% [?]

апреля 10, 2008

Разбираемся с 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

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

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

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

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

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

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

Popularity: 7% [?]

февраля 5, 2008

Защита от неплательщиков.

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

Лучшая защита – работать только с теми, кто у вас в local-trust )))

Но вот еще небольшая подмога. Класс Permission.
Для работы с ним, конечно понадобиться свой родной домен, на который вы сможете положить скромный crossdomain.xml. В нем укажите доступ для того домена, на котором будет лежать результат вашей работы. Ну а если не знаете где именно, будет лежать разрешайте доступ всем. Хуже не будет.

Далее. Кладем у себя мальнький текстовый файл, в котором будут записаны две переменных allow=1 и message=ЗАПЛАТИ ДЕНЕГ!!!

Пока allow=1 флешка будет работать как положено.
Но как только вам покажется, что денег больше не видать – меняйте allow=0.
Теперь все будут поверх флешки периодически читать ваш душещипательный message.

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

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

Просто заводим новый экземпляр Permission и передаем в конструкторе путь к текстовому файлу.

var my_permission:Permission = new Permission("my_domain.net/my_permission.txt");

Код классa: ru.decafe.utils.Permission

/**
* class ru.decafe.utils.Permission
* @author Mikhail Ivanchuk
* @version 0.1
*/
import ru.decafe.utils.Cache;
 
class ru.decafe.utils.Permission {
	private var  theURL:String = "";
	private var accessor:LoadVars;
	private var blinker:Number;
	private var alert_mc:MovieClip;
	private var message:String = "";
 
	public function Permission(url:String) {
		theURL = url;
		accessor = new LoadVars();
	}
	public function loadAccess():Void {
		var refer:Permission = this;
		var _key:String = theURL.indexOf("?")==-1?"?":"&";
		accessor.load(theURL+Cache.disable(_key+"nocache="));
		accessor.onLoad = function (success:Boolean) {
			var mode:String = "demo";
			if (success && this.allow == "1") {
				mode = "allow";
			}
			trace("mode: "+mode+"\n"+this.message);
			if (mode=="demo") {
				refer.message = this.message;
				refer.blinker = setInterval(refer,"alert",10000);
			}
		}
	}
	private function alert():Void {
		alert_mc = _level0.createEmptyMovieClip("alrt",_level0.getNextHighestDepth());
		var txt:TextField = alert_mc.createTextField("txt",0,0,0,150,60);
		txt.background = true;
 
		txt.multiline = true;
		txt.wordWrap = true;
		txt.backgroundColor = 0xDEDEDE;
		txt.border = true;
		txt.borderColor = 0;
		txt.html = true;
		txt.condenseWhite = true;
		txt.htmlText = "
 
<span style="font-family: Arial;">"+message+"
 
";
		alert_mc.counter = 100;
		alert_mc.onEnterFrame = function () {
			this.counter--;
			if (this.counter&lt;0) this.removeMovieClip();
		}
	}
}
</span>

+ Cache.as, который необходим для работы класса Permission: ru.decafe.utils.Cache

Popularity: 8% [?]

2 комментария декабря 6, 2007

Опасные FlashVars

Flashvars долго казались мне самой безобидной субстанцией.
Однако и у них есть пара опасных моментов.

  • Не забываем, что все данные, переданные через flashvars – это String.
    То есть если нужно передать число или булеву переменную – будьте добры, используйте приведение типов. И лучше руками, не полагаясь на автомат.
  • Недавно обнаруженная грабля.
    Допустим у нас есть флешка, на основном таймлайне которой мы импортируем пакет flash.filters.* . Или не импортируем на таймлайн, но создаем переменную некоего класса SomeClass, в коде которого мы как раз и производим этот импорт.
    Так вот ежели мы передадим flashvar flash=kill_my_package, то мы наглухо убъем доступ к пакету flash. Точно так же можно убить пакеты mx, ru, com и все необходимое )). Однако если мы будем импортировать пакеты на временной линейке любого другого мувиКлипа, лежащего на основной линейке, то все будет работать.

А вывод прост: следим за именами переменных, откуда бы они не приходили. Потому как и во вложенном клипе можно убить доступ к пакету, просто объявив в нем переменную

var flash:Boolean = false;

Popularity: 3% [?]

3 комментария декабря 5, 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  

Архив

Ссылки

Радио