Прелоад GIF-анимации

vovanium

Новичок
Я вообще не понимаю в чем смысл такого лоадера, зачем картинки загружать последовательно? Ты не знаешь что броузер может скачивать в несколько потоков? А своим лоадером, ты только тормозишь процесс загрузки.
 

x-yuri

Новичок
во-первых лучше назначать обработчик до установки src, у меня в opera он не срабатывал, пока я не поменял местами img.src = ... и img.onload = ...
Увидишь, что при загрузке первого кадра, сработает функция и т.д. для каждого кадра...
во-вторых, у меня для одного gif-файла обработчик срабатывал 1 раз, т.е. он вызывается когда весь gif загружен, а не для каждого кадра
в-третьих, у меня твой пример работает в ff 2, ff 3, chrome, opera 9, ie 6, ie 7
причем даже если написать так:
Код:
function clk(id){ 
 var i=document.getElementById(id);   
 if(i.style.display=='none')
    i.src=id+'.gif', i.style.display=''; // обрати внимание сюда
 else i.style.display='none'; 
}
и первый кадр при этом виден
p.s. можешь еще ссылку на свою страничку дать - посмотрим, может у тебя gif'ы какие-то особые :confused:
 

Avenus

Under Glory Yield
может у тебя gif'ы какие-то особые
А, что, может быть :) у меня действительно не работает в FF3 (какой-то Minefield 3.0a7pre)

Я вообще не понимаю в чем смысл такого лоадера, зачем картинки загружать последовательно? Ты не знаешь что броузер может скачивать в несколько потоков? А своим лоадером, ты только тормозишь процесс загрузки.
Я это знаю. Но когда вес страницы под 1 Мб, то пока она загрузится пользователь может нажать на кнопку воспроизведения анимации, которая еще не загрузилась - получится косяк :(

Вот, цель сделать прелоадер, который будет загружать всю тяжелую анимацию до показа страницы и заодно показывать процесс загрузки... может быть я выбрал неверный ход?

-~{}~ 01.05.09 20:22:

во-первых лучше назначать обработчик до установки src, у меня в opera он не срабатывал, пока я не поменял местами img.src = ... и img.onload = ...
Можешь подробнее в этом месте, пожалуйста...

-~{}~ 01.05.09 20:29:

Кстати, насчет "...броузер может скачивать в несколько потоков? А своим лоадером, ты только тормозишь процесс загрузки." думаю неверное высказывание... :) может я не прав, но... после объявления:
PHP:
img=new Image();
img.src='...';
Браузер уже начинает загружать картинку...

А прелоадер при проверке img.complete как раз только
проверяет, но не тормозит процесс.... т.к. он прогоняется несколько раз пока не загрузится очередная картинка...

И если даже другими потоками уже зарузились другие картинки, то как только прелоадер дойдет до них, ждать не будет, а сразу быстро перейдет к следующей...

Конечно, было бы иделально, если бы он определял, что уже загружено, а что нет... но это во flash, а я flash не хочу.
 

x-yuri

Новичок
насколько я понял, minefield - это alpha-версия firefox
Я вообще не понимаю в чем смысл такого лоадера, зачем картинки загружать последовательно?
Avenus, твой скрипт загружает изображения последовательную, браузер же может загружать несколько изображений параллельно
зачем использовать complete c setTimeout, если можно точно узнать, когда картинка загружена, с помощью callback'а
И если даже другими потоками уже зарузились другие картинки, то как только прелоадер дойдет до них, ждать не будет, а сразу быстро перейдет к следующей...
они не загрузяться, потому что ты запускаешь загрузку следующей картинки после того, как загрузилась предыдущая (посмотри свой последний вариант)
Можешь подробнее в этом месте, пожалуйста...
лучше писать так:
Код:
img.onload = function() {...}
img.src = ...
а не так
Код:
img.src = ...
//потому что к этому моменту картинка может быть 
//уже загружена (есть в кэше, например)
img.onload = function() {...}
 

Avenus

Under Glory Yield
насколько я понял, minefield - это alpha-версия firefox
C этим разобрался, снес его, поставил нормальный FF3... все работает :)

зачем использовать complete c setTimeout, если можно точно узнать, когда картинка загружена, с помощью callback'а
С удовольствием бы сделал, но я не пойму как применить это к нескольким картинкам в предзагрузке на странице.
 

vovanium

Новичок
Avenus
FF3 (какой-то Minefield 3.0a7pre)
А какой смысл проверять а альфа-версии? Если уже давно есть стабильный релиз 3.0.10?
Что касается загрузки, то обычно gif картинки довольно маленькие, и чаще время на запрос и ожидание ответа сервера, больше, времени скачивания самой картинки, поэтому если ты запустишь их скачивание параллельно, то в итоге будет быстрее.
 

Avenus

Under Glory Yield
Что касается загрузки, то обычно gif картинки довольно маленькие
В моем случае, на одной странице получается...
28 анимированных GIF весом по 150 кб каждая :)
 

vovanium

Новичок
С удовольствием бы сделал, но я не пойму как применить это к нескольким картинкам в предзагрузке на странице.
Точно так же как и к одной, у каждой картинки своё событие onload.
И поясни почему ты стартуешь предзагрузку после загрузки другой картинки, почему не запустить предзагрузку сразу.

-~{}~ 01.05.09 19:54:

Avenus
28 анимированных GIF весом по 150 кб каждая
Это уже аномалия какая-то, какой смысл таких гифок, видео в гифках показывать?
 

Avenus

Under Glory Yield
Это уже аномалия какая-то, какой смысл таких гифок, видео в гифках показывать?
Красивая анимация... не видео, конечно...
А как же, меньше не сделаешь...

почему не запустить предзагрузку сразу.
Как? Просто выполнить функцию?... почему-то не всегда срабатывает...

-~{}~ 01.05.09 21:24:

Насчет веса...
http://eu.blizzard.com/diablo3/ тоже аномалия? :)
Когда нужна красота, меньше никак не сделаешь... я так думаю. Просто я не хочу использовать flash.
 

vovanium

Новичок
Avenus
Для таких вещей есть Flash, который ты не хочешь использовать ;)
 

Avenus

Under Glory Yield
vovanium, flash - это плохо... мое мнение, можно сейчас не оспаривать :)

Для примера я сделал примитивный прогресс бар, но есть мысли как сделать его нормальным.
Вот рабочий скрипт, с некоторыми опущениями:
PHP:
<script type='text/javascript'>
var f={
id:'i1,i2',
src:'i1.gif,i2.gif',
pl:'50,50'}; /* pl - процент для примитивного прогресс бара */
var pre=new Array();
var cpl=0; /* процент загрузки */

/* Создание кэша изображений */
function preLoad(){
var id=f.id.split(',');
var src=f.src.split(',');
for(i=0;i<id.length;i++){
 pre[i]=new Image();
 pre[i].src=src[i];
}
chLoad(0); /* запуск прелоадера
с проверкой на загрузку первого изображения
и поочередно остальные. Понимаю, что плохо...
Вот, хотелось бы сделать лучше */
}

/* Прелоадер и примитивный прогресс бар */
function chLoad(i){
 var id=f.id.split(',');
 var src=f.src.split(',');
 var pl=f.pl.split(',');
 if(i<id.length){
	if(pre[i].complete){
	 cpl+=parseInt(pl[i]); /* увеличил процент загрузки */
	 document.getElementById('cpl').style.width=cpl+'px'; /* показал процент загрузки */
	 pre[i].src='';
	 i++;
	 setTimeout('chLoad('+i+')',10);
 	}
	else{
	 setTimeout('chLoad('+i+')',10);
	}
 }
 else window.setTimeout(function(){
	 document.getElementById('cpl').style.display='none';
	 document.getElementById('btn').style.display='block';
	},1000);
}

/* Включение и выключение показа анимации */
function show(id){
if(document.getElementById(id).style.display=='none'){
 document.getElementById(id).src='';
 document.getElementById(id).src=id+'.gif';
 document.getElementById(id).style.display='';
}
else document.getElementById(id).style.display='none';
}

/* Запускаю прелоад */
preLoad();
</script>

<!-- Примитивный прогресс бар -->
<div style='background:#c00;width:0px;height:10px;' id='cpl'></div>

<!-- Кнопки управления анимацией -->
<div id='btn' style='display:none;'>
 <input onclick="show('i1');" type='button' value='i1'>
 <input onclick="show('i2');" type='button' value='i1'>
</div>

<!-- GIF анимация, с одним циклом! -->
<img id='i1' src='i1.gif' style='display:none;'>
<img id='i2' src='i2.gif' style='display:none;'>
Работает везде: прогресс бар ползет, анимация проигрывается....
Но, в FF3 первый раз нормально, а при обновлении страницы ничего не происходит.

-~{}~ 01.05.09 22:28:

Такая же фигня в NN, как и в FF3 :(

-~{}~ 01.05.09 22:42:

Заменяю в функции chLoad строки с complete на onload
PHP:
function chLoad(i){ 
 var id=f.id.split(','); 
 var src=f.src.split(','); 
 var pl=f.pl.split(','); 
 for(i=0;i<id.length;i++){
	pre[i].onload=function(){
	 cpl+=parseInt(pl[i]); /* увеличил процент загрузки */
	 document.getElementById('cpl').style.width=cpl+'px'; /* показал процент загрузки */
 	}
 }
 if(cpl<100) setTimeout('chLoad()',10);
 else window.setTimeout(function(){
	 document.getElementById('cpl').style.display='none';
	 document.getElementById('btn').style.display='block';
	},1000);
}
Теперь работает в NN и FF3, но блин процент не изменяется и не отображается прогресс бар соответственно. А в IE не проигрывается анимация...ппц :(
Область видимости переменной cpl пропадает куда-то...
 

vovanium

Новичок
Avenus
Подозреваю что Flash - плохо, только потому, что ты не умеешь им пользоваться ;)
Вот ты прицепился к complete, тебе сколько раз говорили не юзать его? Что-то у тебя совсем индусокод получается, посмотри что у тебя в функции chLoad и вспомни что у тебя эта функция вызывается 100 раз в секунду.

Ну и кроме того загружать прелоадом 4 метра гифок, далеко не самое лучшее решение.
 

Avenus

Under Glory Yield
vovanium, ну а 4 метра флэша? будет лучше, думаешь...
Блин, я понимаю, что плохое решение... что функция вызывается 100 раз в секунду...
Но не работает с onload прогресс бар... отказаться от него тогда получается и показывать какую-нибудь картинку до окончательной загрузки... :(

-~{}~ 01.05.09 22:51:

Подозреваю что Flash - плохо, только потому, что ты не умеешь им пользоваться
Согласен, но и не только поэтому...

-~{}~ 01.05.09 23:00:

Тем более, что я отказываюсь от complete :) это просто привел пример кода, который я полностью использовал...
 

vovanium

Новичок
Avenus
ну а 4 метра флэша? будет лучше, думаешь...
Ты пропустил слово прелоад ;) Т.е. если чел посмотрит только 2 твоих gif'а, зачем ему прелоадом скачивать все 28?
Да и что касается Flash, то их размер явно будет меньше, как-то у нас дизайнер нарисовал баннер в Gif на 250 КБ (ну рисует красиво, но над оптимизацией не особо задумывался), путем оптимизаций удалось получить 30 КБ, а потом переделал на Flash и размер уменьшился до 15 КБ. Конечно многое зависит от того какая именно у тебя там анимация...
Прелоад нужен для элементов интерфейса (различных кнопок и т.п.).
Что касается onLoad, ты не совсем понимаешь как работают события. Ты напиши хотя бы что-то ты хочешь получить в итоге, а то постоянно что новое дополняется.
 

Avenus

Under Glory Yield
vovanium, точно... а то я и сам запутался с подсказками...

В общем, дело такое:
1. Загружается страница.
2. На ней есть несколько анимированных картинок.
3. При нажатии на одну из анимированных картинок проигрывается соответствующая для нее анимация.

Вот, чтобы все это было красиво... нужно прелоадить всю эту анимацию. Иначе при нажатии на картинку, недозагруженная
анимация только начнет грузиться.

Ну а, чтобы пока грузится страница было ясно, когда конец... показывать прогресс бар загрузки :)

Все... вроде ничего сложного. Да, видел... многие во flash это и решают, а я хотел попробовать сделать без него. Может и зря, конечно, но все же.

P.S. Почему при:
pre.onload=function(){
// здесь внешние переменные не видны?
}
 

vovanium

Новичок
картинки могут просматриваться в любом порядке или только по очереди?

насчет onload это отдельная функция, она не может обращаться к переменным из функции chLoad, просто потому, что функция chLoad уже отработала, к тому времени как запустится onload.
 

Avenus

Under Glory Yield
картинки могут просматриваться в любом порядке или только по очереди?
В любом, какую нажмет пользователь - для той и будет показываться своя анимация.

насчет onload это отдельная функция
Нет, я имею ввиду, почему не работает:
pre.src='...';
pre.onload=function(){
alert(pre.src); /* ничего не выведет */
}

-~{}~ 01.05.09 23:57:

Попробовал вогнать во flash одну из картинок gif-анимации...
была 217кб - стала 550 кб
К тому же прозрачный фон изчез... не, все же flash не покатит... даже если преобразовать gif в вектор.
 

vovanium

Новичок
Avenus
В таком случае имхо не нужен этот прелоад вообще, так как грузить 4 метра, ради того что бы чел посмотрел всего пару картинок, только лишнее гоняние трафика.

Попробовал вогнать во flash одну из картинок gif-анимации...
была 217кб - стала 550 кб
Ну тут скорее вопрос в том как её перегонял ;) Если тупо как последовательность кадров, то конечно можно получить больший размер :)
что касается онлоад, то ты пойми что он выполняется, уже после того как функция в которой ты его сделал отработало, т.е. переменных которые были в той функции уже нет.
очень советую поставить firebug для фокса, и тогда будет больше понятно что же там происходит.
 
Сверху