Все нижесказанное содержит мысли и идеи многих уважаемых
мною флэшеров, и я с удовольствием указал бы авторство, но, к сожалению,
я просто не помню где или от кого я это услышал. Если вы увидите ниже
какую-либо свою мысль, напишите мне и ваше авторство будет непременно
указано. А пока - виноват :)
Итак, давайте, наконец, займемся опровержением расхожего мифа о том,
что Flash это просто навороченный графический редактор и что флэш элементы
на веб-страницах являются не более чем украшательством. Мне, например,
очень обидно, когда некоторые личности (назовем их нарицательным выражением
"упертые сисадмины") считают что Flash нужно "давить", потому как все
действия, выполняемые флэшовыми роликами, лучше и быстрее выполняются
стандартными средствами HTML. Кстати говоря, по мнению некоторых моих
знакомых из этой категории, из нужных в быту вещей Flash умеет делать
только "Get URL" и это просто "тормознутый аналог гиперссылки". Ладно,
граждане "упертые" :) Попробуйте-ка, вооружившись только средствами HTML,
Java и Perl проделать те фокусы, которые описываются ниже. Хотя конечно
наверняка это все можно сделать, но что это будет намного сложнее - это
факт !
Кстати, хочу обратить ваше внимание на то, что во многих из этих примеров
вовсе не используются никакие графические объекты, и конечные флэш-ролики
будут состоять просто из одного или нескольких пустых ключевых кадров.
Итак, начнем сначала с неказистых и общеизвестных задачек.
1. Определение версии браузера и Flash-плугина.
Главным инструментом Flash во всех не графических действиях являются
переменные и "Frames Actions". Давайте попробуем применить эти инструменты
для простой задачки:
Требуется определить наличие или отсутствие поддержки Flash
у посетителя и в зависимости от результата переправить его на страничку
для "упертых", на вариант сайта для счастливых обладателей Flash3-плугина
или на основной Flash4-вариант. При этом мы не будем пытаться автоматически
проинсталлировать поддержку Flash в браузеры "упертых", а в основном варианте
выведем приветствие пользователям IE.
Для решения этой незамысловатой задачки (на анлийском оно
лежит вот тут)
http://www.macromedia.com/support/flash/ts/documents/scriptfree_detection.htm
попробуем создать ролик, состоящий из пустых кадров, первому из которых
не будем назначать никаких действий, второму зададим следующее действие:
Get URL ("flash4.html")
Set Variable: "var" = "end"
Причем впишем "flash4.html" вместе с кавычками
в окошко Get URL c установленной опцией "Variable". Вот так
В восьмом кадре сделаем:
Go to and Stop (var)
В девятом кадре:
Get URL ("flash3.html")
Причем впишем flash3.html без с кавычек
в окошко Get URL c установленной опцией "String Literal". Вот так
и десятому кадру присвоим метку "end" и
действие
Stop
После этого проэкспортируем эти кадры в .swf (тут я назвал его index.swf
и получился он весом около 130 байт) и, открыв в каком-либо редакторе
.html файл, получившийся после "Publish", внесем в него небольшие изменения.
<html> <head> <title>Detection</title> <meta HTTP-EQUIV="Refresh" CONTENT="4;URL=nonflash.html"> </head> <body bgcolor="#000000"> <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ID=index WIDTH=1 HEIGHT=1> <param NAME=movie VALUE="index.swf"> <param NAME=quality VALUE=high> <param NAME=bgcolor VALUE=#000000> <embed src="index.swf" quality=high bgcolor=#0000 WIDTH=2 HEIGHT=2 TYPE="application/x-shockwave-flash"> </embed> </object> </body> </html>
Невооруженным глазом видно, что из исходного текста удалены все url,
принудительно выставлены размеры ролика 1х1 (реальный размер .swf может
быть любым) и в заголовке появилась строчка насчет HTTP-EQUIV="Refresh" (переход на nonflash.html через 4секунды).
Посмотрим теперь, как это все работает.
Предположим, что на страничку зашел пользователь с полноценной поддержкой
Flash4. Тогда он будет практически моментально перенаправлен на flash4.html из действия внутри 2-го кадра. 8-й
кадр в этом случае является страховочным. Ecли коннект хреновый и за
время попытки уйти на flash4.html дело дойдет
до 8-го кадра, девятый будет перепрыгнут и дожидаться выполнения действия
из второго кадра ролик будет находясь в 10-м. Если же плугин у посетителя
устаревший, то он не поймет этих двух переходов и, соответственно, пойдет
дальше и будет перенаправлен на flash3.html в
девятом кадре. Необходимо заметить, что некоторые методы определения
версии плугина, на основе циклов, работают неустойчиво - трудно предсказать
реакцию Flash3-плугина на действия внутри циклов if - к сожалению, в разных условиях реакция получается
разная. Если вам больше нравятся исторические но очень проверенные методы,
можно использовать что-то вроде вот
этого .fla. Далее, если браузер посетителя вообще не знает что такое
.swf, через 4секунды сработает мина замедленного действия из заголовка
и посетитель будет переброшен на nonflash.html чтобы полюбоваться там, на чисто
текстовый вариант вашего сайта. Работа всей этой комбинации основана
на том, что перенаправление по "Frame Action" из .swf происходит быстрее,
чем срабатывает "Refresh" в заголовке. Время перехода указанное в строке
<meta... может зависеть от множества параметров,
главным из которых является скорость вашего сервера. В большинстве случаев
2-3 секунд вполне достаточно для ухода на нужную страницу по Frame Action,
поэтому тут используются 4 секунды. Размеры ролика уменьшены до точки
по одной простой причине - например IE, при обнаружении неизвестного
объекта предлагает перейти на страницу для "поиска ..." чего-то там.
Но переход этот осуществляется только после щелчка на пустом окошке
из-под объекта, а на окошко размером 1х1 щелкнуть тяжеловато :)
В этом процессе есть еще одна тонкость - если кто-то зайдет на вашу
страничку сначала броузером без поддержки Flash и потом, установив эту
поддержку, попытается еще раз, он может быть снова переброшен на nonflash.html
из-за наличия кэша браузера. Я пока не вижу никаких способов надежно
обойти эту проблему без использования Cookies. Не имеет смысла именно
здесь ударятся в описание того как это сделать - хороших руководств
по ява-скрипту много. Но я например пробовал записывать Cookie скриптом
из nonflash.html, а в заголовке detection.html пытался прочитать Cookie и в случае
его обнаружения убивал Cookie и в заголовке подставлял
document.write("<meta HTTP-EQUIV='Refresh' CONTENT='1'>");
а в случае не обнаружения
document.write("<meta HTTP-EQUIV='Refresh' CONTENT='4;URL=nonflash.html'>");
Что характерно, это почему-то срабатывало :)
Теперь нам остается поприветствовать пользователей IE на flash4.html и это уж сделать совсем просто. В
исходный код flash4.html добавим несколько
знаков:
вместо
<param NAME=movie VALUE="main.swf">
сделаем
<param NAME=movie VALUE="main.swf?ie=1">
После этого добавим в основную сцену main.swf объект типа "Символ" вида "Movie Clip"
c Instance Name hi содержащий текст приветствия
и в первый кадр добавим следующее действие
If (ie=1)
Set Property ("/hi", Visibility) = "1"
Else
Set Property ("/hi", Visibility) = "0"
End If
Таким образом при заходе на эту страничку эксплорером из исходного
текста html в swf будет передана переменная ie со значением 1, а если посетитель использует
NN эта переменная не будет передана в swf (ну не понимает NN тэга <object...
:) Соответственно в первом кадре, после проверки равенства ie=1,
будет принято решение насчет видимости или невидимости приветствия.
На этом в принципе задачу можно считать решенной. Не знаю кому как,
а мне например этот способ кажется значительно проще чем стандартный
ява-скриптовский :)
PS: Только не нужно думать, что я агитирую за запрет автоустановки плугина
в IE - это просто такая задача попалась для примера :) Хотя, в принципе,
иногда такой запрет может быть полезен.
2. Пароль на вход.
С помощью все тех же переменных и "Frames Actions" очень легко
защитить вход на флэшовые странички паролем. Нужно просто организовать
в самом начале ролика (в кадре с акцией Stop) поле ввода и в его свойствах указать имя
какой-нибудь переменной (к примеру, Pass) и кнопку Submit, которой можно назначить
что-то вроде следующих действий:
On (Release, Release Outside)
If (Pass eq "truepass")
Go to and Play ("Welcome")
Else If (n>3)
Go to and Play ("Sorry - you are wrong")
Else If (n eq "")
Set Variable: "n" = "1"
Else If (0 < n < 3)
Set Variable: "n" = n+1
End If
End On
Очень легко увидеть, что при правильно введенном пароле (слово "truepass"
в поле ввода (само собой без кавычек :)) посетитель будет перенаправлен
на ключевой кадр с меткой Welcome, а после пятой неправильной попытки -
на метку Sorry - you are wrong. Для пущей
защищенности не следует вводить правильное слово в поле ввода по умолчанию
:) Кроме того, можно основное содержание подгружать из дополнительного
.swf действием Load Movie из кадра с меткой
Welcome. Причем действие это лучше привязать
к нажатию кнопки - действия кнопок немножко сложнее вычислить, не имея
исходника. Особенно если перед проверкой с введенным словом производятся
какие-нибудь арифметические или логические операции, а имя загружаемого
ролика передавать в виде переменной.
3. Новости. Или почти Cookies...
Долгое время, бродя по флэшовым страничкам, я почему-то пришел
к мысли, что в последнее время сильно распространилась мода на флэш-ролики
с "распределенной загрузкой". Помнится, были времена, когда даже нормальный
"прелоадер" был редкостью, и приходилось просто тупо сидеть и смотреть
на слово Loading..., не имея ни малейшего понятия, сколько звуков, в формате
ADPCM напихал в ролик его автор, и сколько еще времени понадобится, чтобы
посмотреть, наконец, на его творение, имея цпс 200-300. Сейчас же особым
шиком считается сделать страничку, на которой почти невесомое "интро"
запускается почти сразу же и по мере загрузки начинает обрастать новыми
деталями, звуками, и плавно переходит в какое-нибудь навороченное меню
абсолютно космического дизайна. Вы тоже были на таких страничках ? Не
знаю как вам, а мне такой подход к созданию флэшовых роликов очень нравится.
И почему-то мне кажется, что за таким подходом будущее. Есть только у
такого подхода один недостаток - создатель странички почти всегда почему-то
считает, что все посетители заходят к нему в первый раз. А создание кнопки
"Skip intro" противоречит самому принципу распределенной загрузки - тормоза
получатся, если попытаться перейти на еще не загруженный кадр. И тут возникает
простая до безобразия мысль. А что если этот кадр уже загружен ? Что если
этот swf уже спокойно лежит в кэше браузера и ждет когда же его, наконец,
загрузят ? А что собственно нам мешает проверить в первом кадре ролика
по действию If Frame Is Loaded ("метка самого последнего
кадра") не лежит ли наш .swf в кэше ? И если это условие выполнится
можно будет сделать вывод насчет того, что к вам заглянул старый знакомый
и можно даже выделить специальную переменную на то, чтобы поздороваться
с ним как-нибудь по особенному или, например, вывести специально для него
кнопочку "Skip Intro". Дальше больше - к примеру, обновляете вы свою страничку
пару раз в месяц, тогда вполне можно сообщить посетителю, что новенького
появилось на вашей страничке за время его отсутствия. Сделать это можно
простым способом - что мешает нам после каждого обновления создавать отдельный
.swf c "новостями" в пару строк ? И хранить на сервере последние штук
5-6 новостных небольших флэшовых роликов ? Сами уже, наверное, догадались,
как их показать :) Конечно! Это очень просто! Помните старый фокус с незаметной
подгрузкой нового ролика ? Именно это способ и можно использовать. Все
как обычно - делаем ролик, в котором первый кадр пуст и содержит только,
например вот такие действия
If Frame Is Loaded ("end1")
Set Variable: "_level0:variable1" = "1"
End Frame Loaded
Stop
во второй кадр вставляем текст новости, а третьему с этим же текстом
(иногда полезно сделать этот третий ключевой кадр), присваиваем метку
"end1". Потом, действием Load Movie... (после
положительного результата проверки наличия основного ролика в кэше) загружаем
все эти маленькие .swf в основной. Если посетитель уже видел какую-либо
новость, то она уже есть у него в кэше и переменную, прописанную в первом
кадре этой новости, увидит основной .swf. Поскольку разные новостные ролики
передают в основной ролик разные переменные, в случае если соответствующая
переменная не равна единице, даем команду загруженному ролику перейти
на метку "endxx", а если равна - не даем и загруженный ролик остается
невидимым. Можно даже организовать навигацию по новостям, с автоматическим
выводом в начале первой новости, которую посетитель не видел (которой
нет в кэше браузера).
Сложновато конечно слегка получится, но зато только средствами
Flash :)
4. Определяем быстродействие компьютера в он-лайн.
Итак, давайте посмотрим, что еще можно применить для наших антинаучных
экспериментов из богатого (только на первый взгляд, к сожалению...) ассортимента
действий Flash4. Get URL- старо, If
Frame Is Loaded - слишком скучно, Load Movie
- уже было... Ага ! Вот что мне нравится из Actions, это
GetTimer ! Интересная штукенция :) Давайте попробуем
приспособить ее к какому-нибудь общественно-полезному делу.
Вы когда-нибудь замечали что некоторые .swf ролики подтормаживают ? Да,
иногда сидя за PIII-600 забываешь, что есть компьютеры слегка помедленнее
:) А что есть тормоза при воспроизведении .swf ? Это просто процесс происходящий
с компьютером, который не может выполнить заданную в ролике последовательность
действий с заданной в этом же ролике частотой кадров. А от чего зависят
тормоза ? Правильно - тормоза однозначно зависят от производительности
компьютера пользователя и от числа свободных ресурсов на этом компьютере.
Если бы можно было оценить тормоза в цифрах, по этим цифрам можно было
бы судить о производительности системы. Использование GetTimer дает нам уникальную возможность в цифрах
оценить тормоза компьютера посетителя вашей флэшовой странички.
Итак, задача упрощается. Для определения быстродействия компьютера необходимо
взять таймер (например, в первом пустом кадре сделать Set
Variable: "time1" = GetTimer ), потом загрузить процессор так,
чтобы даже PIII-600 немного призадумался, потом в еще одном пустом ключевом
кадре сделать Set Variable: "time2" = GetTimer.
В результате разница time2 - time1 будет практически
линейно зависеть от частоты процессора (конечно не загруженного в этот
момент другими непосильными задачами :)
Как показывает мировая практика, наилучшим способом затормозить процессор
является действие Duplicate Movie Clip. Попробуем использовать
для этого что-то очень похожее на исходник про звездное небо (со странички
с исходниками :). Создадим Символ вида Movie Clip содержащий маленькую
белую точку и поместим этот символ в основную сцену с присвоением ему
Instance Name "star". Далее, в первом кадре берем таймер, во втором что-то
вроде
Set Variable: "number" = 1
Loop While (number <= 5000)
Duplicate Movie Clip ("/star", "zvezda" & number, number)
Set Property ("zvezda" & number, Visibility) = 0
Set Variable: "number" = number +1
End Loop
В третьем кадре похожим циклом уничтожаем все эти 5000 точек и, наконец,
в четвертом снова берем таймер и вычисляем разницу. Кстати цифра 5000
взята абсолютно с потолка - попробуйте поэкспериментировать сами :)
Один из самых первых моих опытов по определению быстродействия лежит вот
тут, а вы попробуйте придумать что-нибудь сами (так получится намного
интереснее :) Пока я встречал еще только одну попытку вычислять быстродействие.
Очень интересный подход к этой задаче продемонстрировал некто c y b e t* . Архив с его 3dflash
bench можно взять тут. Применений этому можно придумать массу - например,
пере направлять пользователей со слабыми процессорами на более другой
урл или просто отключать для них самые навороченные графические эффекты
:)
5. Определяем скорость соединения с интернетом.
Это же самое действие GetTimer можно применить и для оценки качества
коннекта посетителей вашей странички. Здесь все намного проще. Если используется
цикл If Frame Is Loaded (для стандартных задач
типа Loading...), просто засекаем время в самом первом кадре и еще раз
засекаем после окончания этого цикла. Объем данных загружаемых пользователем
в этом цикле нам известен, время загрузки узнаем как разницу двух значений
GetTimer - получается, что скорость соединения
вычислить не просто, а очень просто :) Можно еще для этой же цели подгрузить
пару комбинаций из "невидимых" роликов весом по полтора-два килобайта
с паузой секунды в 3-4 (а вдруг как раз в этот момент попадется ретрейн
? :) Тогда время засекать лучше действиями в подгружаемых роликах, а переменные
хранить в основном. В первом из подгружаемых (например up_1.swf
) роликов получится три Blank Keyframes и действия похожие на что-то вроде:
в первом кадре
Set Variable: "_level0:time1" = GetTimer
во втором
Load Movie ("up_up_1.swf", 1)
и в третьем
Set Variable: "_level0:time2" = GetTimer
где up_up_1.swf это дополнительный подгружаемый
ролик весом 1-2 кб состоящий из двух кадров - первый кадр пустой с действием
Stop, а второй кадр содержит какой-нибудь объект
весящий 1-2 кб. Для пущей точности из основного ролика нужно подгружать
эту комбинацию раза 2-3 и брать среднюю разницу time2-time1.
При этом просто нужно иметь две-три переименованных копии up.swf и up_up.swf.
Это совсем не так страшно как кажется - на самом деле такой подход очень
удобен. Для определения скорости не нужно будет каждый раз подбирать соотношение
времени и объема данных - нужно только иметь эти 2 ролика up.swf
и up_up.swf (две-три пары под разными именами)
и, подобрав один раз константу в соотношении время загрузки - величина
файла, просто загружать из любой точки ролика up_х.swf и в любой другой точке ролика вычислять
скорость коннекта формулой N/(time2 - time1),
где N - известная (подобранная раз и навсегда)
константа. При этом в основном ролике ничего отображаться не будет. Как
уже говорилось, для пущей точности скорость коннекта лучше посчитать минимум
2 раза с паузой 2-4 секунды (комбинация up_1.swf и
up_up1.swf может посылать в основной ролик константы
time1 и time2, а, к примеру, up_2.swf и up_up_2.swf - time3
и time4). Кстати, вычисляя скорость, не забывайте
задавать верхний предел возможного, чтобы отсеять, подгружаемые из кэша
браузера, ролики.
Поняли что-нибудь ? :) Честно говоря, я тоже :) Но более понятного и удобного
варианта, я например, найти не смог - виноват :)
6. Месть флэшера, или удаленное администрирование.
Все мы, даже те, кто занимается флэшем из чисто спортивного интереса,
иногда работаем "на заказ". Легкий заработок никогда не мешает, но обычно
все происходит по схеме
делаем проект
показываем заказчику
Loop while "OК ?" ne "Nu da !"
переделываем
показываем заказчику
End Loop
доводим проект до ума
сдаем заказчику
на заработанные деньги ведем девушку в кино
на "Матрицу" :)
Но есть у подобной схемы недостаток - заказчик иногда оказывается буджумом...
И не в какую не хочет расплачиваться (это ж страшно подумать, сколько
девушек останутся без кино, при современных расценках на Flash ! Не говоря
уже об общем упадке системы кинопроката :) Но нас, создателей флэшовых
меню и заставок, голыми руками не возьмешь !
Спрашивается, что мешает нам в первом кадре нашего ролика загрузить в
какой-нибудь Level маленький .swf, лежащего где-нибудь на собственной
страничке (например, провайдерской) ? (прочитать переменную из текстового
файла с новыми версиями плугинов и Active-x с удаленного сервера не удается...)
А что мешает нам задать из ключевого кадра этого файла несколько переменных
и проверять их периодически по ходу ролика ? А что мешает нам изменить
значения переменных в этом .swf, если заказчик решил сэкономить на нашей
работе и сделать соответствующие и заранее запланированные действия в
этом ролике ?
Правильно - ничто не мешает :) Так что трепещите слишком хитрые заказчики
!
7. Переход по условию, или долой ошибку 404 !
Кроме борьбы с вредными заказчиками метод загрузки переменных
из удаленного файла можно применить для абсолютно уникального действия
- опроса состояния зеркал какого-либо сайта (читайте варезного :) Например,
имеется 3 зеркала какой-либо многострадальной странички, которая прибивается
постоянно то тут, то там (и за что интересно ? :) Используя Flash можно
полностью автоматизировать доступ посетителя на самое живое зеркало. Для
этого создаем абсолютно благообразную страничку где-нибудь на надежном
сервере (что-то типа spee.com и других без доступа через FTP - на таких
серверах не лежит никаких файлов, и тормозят они крайне редко). Кладем
на эту страничку index.html c флэшовым роликом с одной единственной фразой
- что-то типа "Please wait" :)
И уже используя Frames Actions, по очереди пытаемся загрузить .swf, c
заданными в них переменными, расположенных на разных зеркалах. Если какая-либо
переменная не поступит в ролик в течение 3-4 секунд, делаем вывод о том,
что соответствующее зеркало прибито или лежит. После этого замеряем скорость
коннекта посетителя с каждым из живых зеркал (помните пункт 5 ? :) и перенаправляем
его на самое быстрое :) У такого подхода есть недостаток - никто не может
дать гарантии, что пользователь не загрузит что-нибудь из кэша браузера
- ну дык ведь никто никого не заставляет делать странички, которые могут
быть прибиты в любой момент - суетитесь, почаще переименовывайте файлы
:)
Кстати кроме перенаправления посетителя на живое зеркало, можно еще и
отослать себе письмецо насчет кончины одного из зеркал через Sendmail
где-нибудь на Virtualave. Но это уже совершенно другая опера - тут, наверное,
все-таки без Perl не обойтись :)
На этом разрешите закончить краткий обзор возможностей замечательной
программы Flash. Надеюсь вы узнали что-то новое для себя. Кстати если
у вас есть интересные идеи, но вы не можете их реализовать или есть предложения
насчет исходников из раздела с исходниками - пишите
- что-нибудь придумаем :
|