Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Загрузка анимированного .gif из кеша браузера


Автор: Dima 2015 31.1.2010, 06:37
Доброго времени суток всем!

Во-первых...
Я долгое время не посещал этот сайт и рад снова поприветствовать всех братьев по разуму и пообщаться с умными людьми smile

Во-вторых смысл моего появления - вопрос...
Есть ли способ загружать анимированные .gif изображения из кеша браузера не теряя анимацию?
Долго думал это тема джаваскрипта или верстки, и решил таки что к js ближе...

Подробнее.
Думаю известная проблема - если мы делаем при каких-то событиях мыши загрузку анимированных изображений, то анимацию мы будем видеть ровно до тех пор, пока изображение не закешируется браузером, обычно этих разов будет 1, если не предпринять доп. усилий. После кеширования мы будем видеть уже не анимированное изображение, а его последний кадр.
Стандартное js-решение этой проблемы - добавление случайного числа к урлу загружаемой картинки, это приводит к загрузке изображения снова с сервера.

В моем случае это решение содержит изъян: картинок может загружаться довольно много одновременно и скорость их загрузки критична. Если у юзера нету тормозов инета и мой хост отдает изображения нормально, то проблем не наблюдается. Но стоит появиться лагам с той или другой стороны и загрузка изображений начинает подтормаживать. Это может сбить с толку...


Конкретно, где это используется:
Есть приложение логической игры онлайн для ВКонтакта (вернее сделано оно давно для себя и сейчас на ВКонтакт интегрируется):
http://vkontakte.ru/app180099
Кстати рекомендую любителям логических игр...
Вот тут, когда едим чужие шарики - анимация может тормозить.

Для тех кто не зарегистрирован, моделирование проблемы:
http://mskhost.nichost.ru/lagmodel.html

P.S. У меня проявляется в ФФ 3.5.7, но точно помню что раньше было и в других браузерах. Сейчас ИЕ и Опера вроде не задерживают, возможно более новые версии сейчас.


Что можно придумать?
Слышал про новую технологию с элементом canvas, может она поможет?

Upd: речь идет именно об однотактовых анимированных гифах, с циклическими вроде бы этой проблемы нет.

Автор: Dima 2015 1.2.2010, 00:52
Так что, госпада профи, никаких идей?

Автор: 12345c 1.2.2010, 02:53
Цитата(Dima 2015 @  31.1.2010,  06:37 Найти цитируемый пост)
об однотактовых анимированных гифах
это называется JS-анимация и гифы ни при чём; верно? Или об однократно анимированных?

canvas не поможет. Нужно кешировать отдельные картинки и анимировать через JS.

Автор: Dima 2015 1.2.2010, 05:46
12345c, если я правильно понял твой вопрос, то речь именно об однотактно-анимированных. Вот:
http://mskhost.nichost.ru/bwars/design/0-red.gif?v1

Кешировать отдельные картинки и анимировать через JS, т.е. разбить гифку на кадры и реализовать динамику тупым джаваскриптовым быстрым перебираением кадров? Плюс - одновременно может происходить подстановка до 10ти картинок, а в экстремальных случаях до 60-ти, и каждая скажем кадров из 10-ти, это потянут браузеры?
Ну в любом случае попробовать можно конечно...

А почему канвас не поможет, ведь много чего на нем хитрого делают...

Автор: Dima 2015 8.2.2010, 12:26
Up

Господа, вопрос до сих пор открыт, гениальные идеи до сих пор востребованы...

Автор: Dima 2015 22.2.2010, 07:50
В общем появилось 3+ идеи.

1. Заменить анимационные однотактовые гифы на циклические, в которых последний кадр задерживается на несколько секунд. За эти несколько секунд менять их на статические.
Эта идея себя не оправдала - не работает.

2. Сделать анимацию статическими гифами на javascript. Т.е. разбиваем картинки на кадры, кешируем все кадры и подставляем js-ом примерно вот так
Код

im = new Image(); // создали объект для картинки
im.src = 'my.jpg'; // загрузили картинку
td_1.appendChild(im); // прилепи ее к 1 ячейке
td_2.appendChild(im); // ко 2й
td_3.appendChild(im); // к 3й

im.src = 'my_2.jpg'; // загрузили другую картинку
im.src = 'my_3.jpg'; // еще другую

Тут особенно прильщает то, что при таком подходе мы меняем src лишь у одного объекта и будут перезагружены все картинки. Я прав? И во всех ли это браузерах так? Еще не успел написать тестер, вдруг кто выведет из заблуждения что это будет работать...

3. Самый в общем-то ломовой и простой способ. Кешируем статические картинки и меняем их размер javascript-ом. На сколько я понимаю, это самый неФенШуйный способ js-анимации, да и уступает п.2 т.к. число итераций прямо пропорционально числу анимируемых картинок.

4. Я жду ваших идей!

Автор: 12345c 22.2.2010, 13:18
Посмотрел на моделирование проблемы:
http://mskhost.nichost.ru/lagmodel.html
Решения.
1) если картинка одного типа, то никакой многокартиночности не надо - используется одна предзагруженная, меняется при анимации по JS масштаб и положение или просто центровка в диве, и этого достаточно для анимации.
2) Если поведение картинок сложнее и их больше одной - анимация на JS делается сгруппированной картинкой (то, что называется CSS-спрайт, но используется для целей анимации) (тоже с предзагрузкой), меняются CSS. Для экономии траффика в одну картинку ничего не мешает вставить несколько сгруппированных.
3) анимация уже есть в jQuery, там есть очереди и работа с ними, что может быть полезно, поэтому можно использовать её. http://jqapi.com/#p=animate

Автор: Dima 2015 22.2.2010, 18:18
Черт, как неудачно.
12345c ты смотрел именно в тот момент, когда она была на половину поломана, сейчас восстановил. Но все равно спасибо за советы, буду разбираться, идей уже прилично набирается smile

Автор: 12345c 22.2.2010, 21:08
Посмотрел ещё раз - ничего не изменилось: грузятся картинки в почти произвольном порядке, что само по себе некрасииво. При управляемой анимации можно делать, как требуется.

Автор: SelenIT 23.2.2010, 19:56
Голосую за спрайты. Там, кроме прочего, при необходимости можно и http://habrahabr.ru/blogs/javascript/67179/ реализовать...

Автор: 12345c 24.2.2010, 04:18
Почему так долго и всё на уровне идей?
Вот заготовка, на которую остаётся наложить логику и анимацию, чтобы получить красивое демо. (Использовать jQ-ui.)
В данном виде демонстрируется, что обновляется группа картинок синхронно и мгновенно (кеширована заранее). Почти то же будет с анимацией (JS).

Код

<title>перебор доступных рисунков в доступных полях отображения</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="jquery-1.4.2.js"></script>
<script>
    //hrefImgBase = "http://www.corado.ru/upload/images/60x60/"; //для сторонних файлов
    hrefImgBase = ""; //для локал.файлов
    ii=0;
    imgSrc = //части имён и подписи картинок
        ("1103-0145,жёлт.улыбк.,1103-0382,фиол.1,1103-0204,красн.сердц.,1103-0240,фиол.фейерв.,1103-0393,жёлт.21,"
        +"1103-0249,зелен.рож.,1103-0250,фиол.звезд.,1103-0267,красн.сердц.,1103-0193,сирен.звезд.,"
        +"1103-0197,коричн.лист.,1103-0264,кр.-салат.-син.,1103-0380,красн.рис.,1103-0394,син.18,"
        +"1103-0139,5жёлт.улыбк.,1103-0386,фиол.5,1103-0385,малин.4,1103-0388,син.6,1103-0389,фиол.7,"
        +"1103-0391,фиол.9,1103-0384,красн.3,1103-0390,син.8,1103-0382,желт.2,1202-0212,Принцессы").split(',');
    aa=[]; for(i=0; i<imgSrc.length; i+=2) {aa[i]=new Image(); aa[i].src =hrefImgBase +imgSrc[i]+'.jpg';} //кеш
    $(function(){
        $('.d0').html('Всего картинок ' + imgSrc.length/2);
        ww=setInterval(function(){ //смена изображений
          $('.im1').each(function(){
            $(this).attr('src', hrefImgBase + imgSrc[ii = (ii+2) % imgSrc.length] + '.jpg' )
                .attr('title', '=='+ii+'==')
                .parents('.d1').find('.d2').html(imgSrc[ii+1]);
          });
        }, 3000);
        
        nCols = 5;
        nRows = 3;
            //размножение шаблона
        for(j=1;j<nCols;j++)
            $('.dRow').append($('.d1').eq(0).clone());
        for(i=1;i<nRows;i++)
            $('.dTable').append(
                $('.dRow').eq(0).clone()
            );
        
    });
</script>
<style>
.dRow, .d3{
    clear:both;
    float:left;
}
.d1{
    float:left;
    width:160px;
    height:160px;
    margin:1px;
    overflow:hidden;
    border:1px solid;
}
.t1{
    width:160px;
    height:160px;
    border:1px solid red;
    display:block;
    border-collapse:collapse;
}
.t1 td, .t1 th{
    width:158px;
    height:140px;
    padding:0;
}
.t1 td{
    height:18px;
}
.im1{
    width:60px;
    height:60px;
}
.d2{
    text-align:center;
}
</style>
<body>
<div class="d0"></div>
<div class="dTable">
    <div class="dRow">
        <div class="d1">
            <table class="t1"><tr><th>
                <img class="im1" src="http://www.corado.ru/upload/images/60x60/1103-0145.jpg">
            </th></tr><tr><td>
                <div class="d2" style=""></div>
            </td></tr>
            </table>
        </div>
    </div>
</div>
<a class="d3" href=# onclick="clearInterval(ww);return!1">Остановить</a>

Код без кириллицы для демонстрации вынесен сюда: http://savedbythegoog.appspot.com/?id=584c72b3f8e349808ca74f688adf1b230cd3a563
(Используется http://forum.vingrad.ru/forum/topic-291798.html; другого в онлайне, с кириллицей и без регистрации пока не известно; здесь же можно http://code.google.com/apis/ajax/playground/ из демонстрации в EditHTML и тут же править и отлаживать.)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)