Мультипликация
Естественным продолжением идеи замещения значения атрибута SRC в контейнере IMG является мультипликация, т.е. последовательное изменение значения этого атрибута во времени. Для реализации мультипликации используют метод объекта Window — setTimeout().
Собственно, существует два способа запуска мультипликации:
- onLoad();
- onClick(), onChange() ...
Наиболее популярный — setTimeout() при onLoad().
Событие onLoad()
Событие onLoad() наступает в момент окончания загрузки документа браузером. Обработчик события указывается в контейнере BODY:
...
<BODY onLoad="JavaScript_code">
...
В нашем случае при загрузке документа должен начать выполняться цикл изменения картинки:
function movie()
{
eval("document.images[0].src='clock"+i+".gif';");
i++;if(i>6) i=0;
setTimeout("movie();",500);
}
...
<BODY onLoad="movie();">
...
В примере используется бесконечный цикл, хотя можно реализовать и конечное число подмен:
function movie()
{
eval("document.images[0].src='clock"+i+".gif';");
i++;
if(i<7)
{
setTimeout("movie();",500);}
}
...
<BODY onLoad="movie();">
В обоих примерах следует обратить внимание на использование метода setTimeout(). На первый взгляд, это просто рекурсия. Но в действительности все несколько сложнее. JavaScript разрабатывался для многопоточных операционных систем, поэтому правильнее будет представлять себе исполнение скриптов следующим образом:
- Скрипт получает управление при событии onLoad().
- Заменяет картинку.
- Порождает новый скрипт и откладывает его исполнение на 500 миллисекунд.
- Текущий скрипт уничтожается JavaScript-интерпретатором.
После окончания срока задержки исполнения все повторяется. В первом примере (бесконечное повторение) функция порождает саму себя и, тем самым, поддерживает непрерывность своего выполнения. Во втором примере (конечное число итераций) после девяти повторов функция не порождается. Это приводит к завершению процесса отображения новых картинок.
Запуск и остановка мультипликации
Перманентная мультипликация может быть достигнута и другими средствами, например многокадровыми графическими файлами. Однако движение на странице — не всегда благо. Часто возникает желание реализовать запуск и останов движения по требованию пользователя. Удовлетворим это желание, используя предыдущие примеры (запустить или остановить мультипликацию):
var flag1=0;
function movie()
{
if(flag1==0)
{
eval("document.images[0].src='clock"+i+".gif';");
i++;if(i>6) i=0;
}
setTimeout("movie();",500);
}
...
<BODY onLoad="movie();">
...
<FORM>
<INPUT TYPE=button VALUE="Start/Stop" onClick="if(flag1==0) flag1=1; else flag1=0;">
</FORM>
В данном случае мы просто обходим изменение картинки, но при этом не прекращаем порождение потока. Если мы поместим setTimeout() внутрь конструкции if(), то после нажатия на кнопку Start/Stop поток порождаться не будет, и запустить движение будет нельзя.
Существует еще один способ решения проблемы остановки и старта мультипликации. Он основан на применении метода clearTimeout(). Внешне все выглядит по-прежнему, но процесс идет совсем по-другому:
var flag1=0;
var id1;
function movie()
{
eval("document.images[0].src='clock"+i+".gif';");
i++;if(i>6) i=0;
id1 = setTimeout("movie();",500);
}
...
<BODY onLoad="movie();">
...
<FORM>
<INPUT TYPE=button VALUE="Start/Stop"
onClick="if(flag1==0) { id1=setTimeout('movie();',500); flag1=1;} else {clearTimeout(id1); flag1=0;};">
</FORM>
Обратите внимание на два изменения. Во-первых, объявлен и используется идентификатор потока (id1); во-вторых, применяется метод clearTimeout(), которому, собственно, идентификатор потока и передается в качестве аргумента. Чтобы остановить воспроизведение функции movie() достаточно "убить" поток.
Оптимизация отображения
При программировании графики следует учитывать множество факторов, которые влияют на скорость отображения страницы и скорость изменения графических образов. При этом обычная дилемма оптимизации программ — скорость или размер занимаемой памяти — решается только путем увеличения скорости. О размере памяти при программировании на JavaScript думать как-то не принято.
Из всех способов оптимизации отображения картинок мы остановимся только на нескольких:
- оптимизация отображения при загрузке;
- оптимизация отображения за счет предварительной загрузки;
- оптимизация отображения за счет нарезки изображения.
Если первые две позиции относятся в равной степени как к отображению статических картинок, так и к мультипликации, то третий пункт характерен главным образом для мультипликации.
Оптимизация при загрузке
Практически в любом руководстве по разработке HTML-страниц отмечается, что при использовании контейнера IMG в теле HTML-страницы следует указывать атрибуты WIDTH и HEIGHT. Это продиктовано порядком загрузки компонентов страницы с сервера и алгоритмом работы HTML-парсера. Первым загружается текст разметки. После этого парсер разбирает текст и начинает загрузку дополнительных компонентов, в том числе графики. При этом загрузка картинок, в зависимости от типа HTTP-протокола, может идти последовательно или параллельно.
Также параллельно с загрузкой парсер продолжает свою работу. Если для картинок заданы параметры ширины и высоты, то можно отформатировать текст и отобразить его в окне браузера. До тех пор, пока эти параметры не определены, отображения текста не происходит.
Таким образом указание высоты и ширины картинки позволит отобразить документ раньше, чем картинки будут получены с сервера. Это дает пользователю возможность читать документ или задействовать его гипертекстовые ссылки до момента полной загрузки (событие load).
С точки зрения JavaScript, указание размеров картинки задает начальные параметры окна отображения графики внутри документа. Это позволяет воспользоваться маленьким прозрачным образом, для того, чтобы заменить его полноценной картинкой. Идея состоит в передаче маленького объекта для замещения его по требованию большим объектом.
Предварительная загрузка
Замена одного образа другим часто бывает оправдана только в том случае, когда это происходит достаточно быстро. Если перезагрузка длится долго, то эффект теряется. Для быстрой подмены используют возможность предварительной загрузки документа в специально созданный объект класса Image.
Реальный эффект можно почувствовать только при отключении кэширования страниц на стороне клиента (браузера). Кэширование часто используют для ускорения работы со страницами Web-узла. Как правило, загрузка первой страницы — это достаточно длительный процесс. Самое главное, чтобы пользователь в этот момент был готов немного подождать. Поэтому, кроме графики, необходимой только на первой странице, ему можно передать и графику, которая на ней не отображается. Но зато при переходе к другим страницам узла она будет отображаться без задержки на передачу с сервера.
Описанный выше прием неоднозначен. Его оправдывает только то, что если пользователь нетерпелив, то он вообще отключит передачу графики.
Нарезка картинок
Нарезка картинок применяется довольно часто. Она позволяет достигать эффекта частичного изменения отображаемой картинки. Чаще всего он применяется при создании меню.
Кроме подобного эффекта нарезка позволяет реализовать мультипликацию на больших картинках. При этом изменяется не весь образ, а только отдельные его части.
|