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

Avenus

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

Подскажите, кто знает, в чем проблема:
Делаю прелоад анимированных картинок GIF на JavaScript...
PHP:
var pre=new Image;
pre.src='....';
некоторые из них с анимацией без повторения, т.е. 1 цикл.

Так вот, они изначально скрыты на странице "display:none" и когда показываю:
PHP:
<img id='i1' src='...'> и document.getElementById('i1').style.display='block';
то:

- в Opera, Google Chrome и Safari показывает анимацию начиная с 1-го кадра в 1 цикл, как и требуется :)
- в IE и Mozilla не хочет сразу показывает последний кадр.

Может быть перед показом "display:block" нужно перезагрузить картинку или перемотать, блин... никак не пойму, что за фигня.
 

vovanium

Новичок
попробуй менять src после того, как делаешь картинку видимой
 

vovanium

Новичок
Что-то ты не то пробовал, вот пример
PHP:
<script>
function clk(){
	var i = document.getElementById('i1');
	if (i.style.display == 'none') i.src = '', i.src = 'img/load.gif', i.style.display = '';
	else i.style.display = 'none';
}
</script>
<input type="button" id="button" value="Вкл./Выкл." onClick="clk();">
<img src="img/load.gif" style="display:none;" id="i1">
Работает везде одинаково, в IE 6, 7, 8, FireFox 3, Chrome, Opera 9.63
Основная фишка в том что src должен меняться пусть и на мгновение, причем очистка src понадобилось только для Chrome, всем остальным оказалось достаточно простого присваивания. Chrome похоже еще и проверяет изменился ли параметр.
 

ksnk

прохожий
Avenus А еще картинки с таким-же именем на странице присутствуют? Если есть, то будут проблемы в FF и IE8.
 

Avenus

Under Glory Yield
vovanium, да, этот код работает...
Но я же написал в начале, что сначала картинки прелоадятся, чтобы анимация не начинала грузится при показе картинки...
Т.е. чтобы на момент показа анимации она была загружена...

Вот, подправил твой скрипт, который теперь не работает нигде :)
PHP:
<html>
<head>
<script type='text/javascript'> 
var pre;

function loader(){
 pre=new Image();
 pre.src=document.getElementById('i1').src;
 checkLoad();
}

function checkLoad(){
 if(!pre.complete) window.setTimeout('checkLoad()',10);
 else document.getElementById('btn').style.display='block';
}
 
function clk(){ 
 var i=document.getElementById('i1');
 if(i.style.display=='none') i.src='',i.src='BigImage.gif',i.style.display='';
 else i.style.display='none';
}

</script>
</head>
<body>
<img src='loader.gif' onload='loader();'>
<input id='btn' style='display:none;' type='button' value='On/Off' onClick='clk();'>
<img id='i1' src='BigImage.gif' style='display:none;'>
</body>
</html>
 

ksnk

прохожий
Avenus Ну отчегож сразу - нигде. В IE 5.5 и IE6 - работает... А вот так - почти везде:
PHP:
function checkLoad(){ 
 if(!pre.complete) window.setTimeout('checkLoad()',10); 
 else {
   pre.src='';
   document.getElementById('btn').style.display='block'; 
 }
}
 

Avenus

Under Glory Yield
ksnk, отлично, спасибо в IE8 заработало...
Остался Mozilla :)
vovanium... видимо я все же неверно src сменял...

-~{}~ 29.04.09 10:24:

P.S. Имел ввиду, что теперь не только в Opera, Chrome, Safari...
но еще и в IE8 работает :)
Что-то Mozilla Firefox 3 не хочет скушать его...
 

vovanium

Новичок
Вообще кривовато ты прелоад делаешь, вся фишка в том что не должно быть картинок с одинаковым src, так как если картинки с одинаковым src то анимация у них синхронная.
Тебе не мешало бы переделать прелоад (юзай события, а не циклические проверки) и нужно убивать сами картинки.

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

Вот в принципе рабочий вариант
PHP:
<html> 
<head> 
<script type='text/javascript'>  
var pr;
function loader(){ 
 pr=new Image(); 
 pr.src='img/load.gif'; 
 pr.onload = function(){pr.src = '';document.getElementById('btn').style.display = ''; };
} 

function clk(){  
 var i=document.getElementById('i1'); 
 if(i.style.display=='none') i.src='',i.style.display='',i.src='img/load.gif'; 
 else i.style.display='none'; 
} 

</script> 
</head> 
<body> 
<img src='img/load1.gif' onload='loader();'> 
<input id='btn' type='button' style='display:none;' value='On/Off' onClick='clk();'> 
<img id='i1' src='img/load1.gif' style='display:none;'> 
</body> 
</html>
 

x-yuri

Новичок
как-то сложно у вас все получилось
вот такая штука работает в ie 7, ff 3, opera 9 и chrome
Код:
<img src="raznoe02.gif" style="display: none;">
asdasd
<script>
pr=new Image();  
pr.src='raznoe02.gif';
</script>
если закомментировать скрипт, то gif не загружается только в opera

p.s. проверял и сниффером и визуально... может дашь свой gif, который "в IE и Mozilla не хочет сразу показывает последний кадр"?

и вот такая штука работает в тех же браузерах, в частности в Chrome
Код:
<script> 
function clk(){ 
    var i = document.getElementById('i1'); 
    if (i.style.display == 'none') i.style.display = ''; 
    else i.style.display = 'none'; 
} 
</script> 
<input type="button" id="button" value="Вкл./Выкл." onClick="clk();"> 
<img src="raznoe02.gif" style="display:none;" id="i1">
т.е. мне непонятно, зачем там было "i.src = '', i.src = 'img/load.gif'"
 

vovanium

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

А проверять просто, сделай гифку с двумя кадрами на которых написано 1 и 2, и задержку между кадрами 2 секунды, без зацикливания, и потом по нажатию кнопки у тебя должна показать гифка на которой сначала написано 1, а потом меняется на 2, а не сразу показываться 2 (как будет в твоих примерах).
 

Avenus

Under Glory Yield
x-yuri, либо я неверно выразился, либо ты неверно понял пост :) все равно спасибо, т.к. все ответы помогли разобраться с моим скриптом, который теперь работает в:
IE 7+, Opera 9+, Chrome, Safari 3+

Основные изменения, которые позволили это сделать:
1. При прелоаде
PHP:
if(img.complete){
...
img.src=''; // добавил замену загруженного src
...
}
2. При показе
PHP:
...
img.src=img.src; // добавил перед показом img
img.style.display='block';
...
Единственное, теперь в Chrome при первом показе img оно моргает (исчезает и снова появляется), но очень быстро, поэтому не страшно. В остальных браузерах нет такого глюка.
 

x-yuri

Новичок
да, действительно, я думал, что речь идет просто о предзагрузке :)
 

Avenus

Under Glory Yield
А вот в Mozilla вообще сплошные глюки...
Первая загрузка идет нормально... при том, что показ анимации так и не происходит, сразу последний кадр показывает.
Так еще и при обновлении страницы прелоад уже не работает... т.к. все уже в кэше и проверка на complete не работает почему-то...
 

vovanium

Новичок
Avenus
я тебе дал рабочий пример, не юзай complete (который может вообще кстати не появиться), люди давно придумали события для таких целей
 

Avenus

Under Glory Yield
vovanium, какие события?
Подскажи, пожалуйста... что-то я упустил тогда

-~{}~ 01.05.09 06:22:

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

Avenus

Under Glory Yield
x-yuri, а ты попробуй с onLoad сделать прелоад нескольких картинок :) ... именно с анимацией...
Увидишь, что при загрузке первого кадра, сработает функция и т.д. для каждого кадра...
 

dimagolov

Новичок
Увидишь, что при загрузке первого кадра, сработает функция и т.д. для каждого кадра...
это разве проблема? сделать флаг и реагировать только на первый кадр? или вообще чистить обработчик после первого срабатывания?
 

Avenus

Under Glory Yield
К тому же ни один из вариантов не работает в Mozilla.
Анимация не проигрывается.

-~{}~ 01.05.09 19:38:

Вот, для пары картинок скрипт... кстати, вместо complete стоит onload. В Mozilla все равно не работает, т.е. анимация не проигрывается, а сразу показывается последний кадр.
PHP:
<html>  
<head>  
<script type='text/javascript'>
var im=['i1','i2'];
var pr=new Array();

function loader(i){
if(i<im.length){
 pr[i]=new Image();  
 pr[i].src=im[i]+'.gif';  
 pr[i].onload=function(){
	 pr[i].src='';
	 i++;
	 loader(i);
 }
}
else{
 document.getElementById('loader').style.display='none';
}
}  

function clk(id){
 var i=document.getElementById(id);  
 if(i.style.display=='none')  i.src='',i.style.display='',i.src=id+'.gif';
 else i.style.display='none';
}  
</script>  
</head>  
<body>
<img id='loader' src='loader.gif' onload='loader(0);'>  
<input type='button' value='i1' onClick="clk('i1');">
<input type='button' value='i2' onClick="clk('i2');">
<img id='i1' src='i1.gif' style='display:none;'>
<img id='i2' src='i2.gif' style='display:none;'>  
</body>  
</html>
 
Сверху