Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   отрисовка большого кол-ва картинок на canvas (https://javascript.ru/forum/events/32934-otrisovka-bolshogo-kol-va-kartinok-na-canvas.html)

cyber 04.11.2012 21:43

отрисовка большого кол-ва картинок на canvas
 
вот не много запутался как лучше сделать,
на канве отрисовуется довольно много раз одна и таже картинка и что бы не загружать ее каждый раз заново написал такой код
var imgCache = loaded[type.bg];

              if (!imgCache) {

                      var img = new Image();
                      img.src = type.bg;
                      
                      
                      img.onload = function () {
                          drawImg.call(this, x, y, width, height);
                      };
                     
                       loaded[type.bg] = {
                          obj: img,
                          loaded: false
                      };

                      img = null;
                  }

                  else {
                    
                  if (imgCache.loaded)
                      ctx.drawImage(imgCache.obj, x, y, width, height);


                  else {

                      if (!imgCache.sub) imgCache.sub = [];

                      imgCache.sub.push(function () {//"подписка" на загрузку картинки
                          ctx.drawImage(imgCache.obj, x, y, width, height);
                      });
                  }
                      

                  
              }

              function drawImg(x,y,width, height) {

                  loaded[type.bg].loaded = true;// картинка загружена
                 
                  ctx.drawImage(this, x, y, width, height);

                  var sub = loaded[type.bg].sub;

                  for (var i = 0; i < sub.length; i++) sub[i]();// вызов "подписчиков"
              };

или через кэш браузера будет быстрей?

dmitriymar 04.11.2012 21:49

Цитата:

Сообщение от cyber
или через кэш браузера будет быстрей?

что мешает протестить на время исполнения в разных браузерах самому?

cyber 04.11.2012 21:54

то что не совсем понимаю как, если нужно протестить выполнение какого то действие то можно циклов прогнать 2 варианта
var d = new Date();
for(...)fnc();
var res = new Date() - d;

а тут проблема в том что нужно ждать загрузки картинок и прост прогнать не получиться, а в голову нечего приходит

dmitriymar 04.11.2012 22:15

для канвы
var img = new Image();
img.src = type.bg;
var d = new Date();

....
img.onload = function () {
for(var i=1000;i-- ; ) {
drawImg.call(this, x, y, width, height);
// запускаем перерисовку . у канвы можно offsetHeight запросить

}

};
для вставки через тег имидж -обычные в цикле
изменение src onload , перерисовка

скрипт и отрисовка идут в одном потоке -так что замерять можно
var img = new Image();
img.src = type.bg;
и просто подстановка картинки будут брать картинку из кеша если она там есть

cyber 04.11.2012 22:27

я чет тупонул, только что вспомнил что в хроме можно посмотреть скорость загрузки файлов и все остального.
для хрома:
-При первой загрузке разница огромная.
-При второй в несколько раз меньше .
- При третей и дальнейших грузиться с кеша , т.е время загрузки == 0

cyber 04.11.2012 22:41

сор, за тему, но часто бывает что до меня доходит когда я ее уже создал=(
а насчет кэша , по тому что вижу лучше с ним так как первая загрузка самая главная и разница очень большая и это только для 5 картинок.

dmitriymar 04.11.2012 22:50

Цитата:

Сообщение от cyber
- При третей и дальнейших грузиться с кеша , т.е время загрузки == 0

хром оптимизирует скрипты-отсюда и разница.после первой из кеша , если он включен

cyber 04.11.2012 23:04

dmitriymar, вот тестовые страницы с кэшем
http://cyberua.16mb.com/paint/cache.html
без него:
http://cyberua.16mb.com/paint/withoutCahe.html
если не тяжело можете в хроме запустить и сказать какая быстрей, а то как то странно хром себя ведет ?!

dmitriymar 04.11.2012 23:10

Цитата:

Сообщение от dmitriymar
хром оптимизирует скрипты-отсюда и разница

ответ был ранее)

cyber 04.11.2012 23:29

Цитата:

Сообщение от dmitriymar (Сообщение 214148)
ответ был ранее)

да я понял это, но причем оптимизация к тому что каждый раз разный результат, то быстрей к кэшем то без (кэш брузера очищаю перед каждой загрузкой страници)

Дзен-трансгуманист 04.11.2012 23:31

cyber,
Сперва надо указывать img.onload, затем img.src. Ибо если картинка в кэше браузера, то событие может не отработать.

Хотя иногда и так не отрабатывает. Можно после присвоения img.src дополнительно проверять на img.width и img.height или img.complete. Есть топик на тему предзагрузки на Stack Overflow и простецкий прелоадер на гитхабе.

cyber 04.11.2012 23:46

Дзен-трансгуманист,
да все равно таже хрень то один быстрей то другой =(

cyber 04.11.2012 23:49

в мозиле явное преимущество варианта c cache.

Дзен-трансгуманист 04.11.2012 23:55

cyber,
Та дождись уже пока все загрузятся - тогда рисуй. Юзеры-то кэш нарочно сбрасывать не будут. При первой загрузке всё что угодно ждать приходится, как ни крути.

cyber 04.11.2012 23:57

Дзен-трансгуманист, т.е вариант с кэшем лучше?

Дзен-трансгуманист 05.11.2012 00:01

cyber,
С каким кэшем, не понял, браузера, или в скрипте?
В скрипте храни картинки либо в Image, либо рисуй Image на буферный Canvas, и храни там. Откуда рисовать быстрее, с буферной канвы или с Image - не знаю, не мерял, и, думаю, это зависит от браузера. Но присваивать заново один и тот же src точно не нужно: один раз загрузил - и рисуй потом хоть до второго пришествия.
В некоторых случаях без буферной канвы попросту не обойтись.

cyber 05.11.2012 00:06

Дзен-трансгуманист,
я про кэш скрипта
var imgCache = loaded[type.bg];

              if (!imgCache) {

                      var img = new Image();
                      img.src = type.bg;
                      
                      
                      img.onload = function () {
                          drawImg.call(this, x, y, width, height);
                      };
                     
                       loaded[type.bg] = {
                          obj: img,
                          loaded: false
                      };

                      img = null;
                  }

                  else {
                    
                  if (imgCache.loaded)
                      ctx.drawImage(imgCache.obj, x, y, width, height);


                  else {

                      if (!imgCache.sub) imgCache.sub = [];

                      imgCache.sub.push(function () {
                          ctx.drawImage(imgCache.obj, x, y, width, height);
                      });
                  }
                      

                  
              }

              function drawImg(x,y,width, height) {

                  loaded[type.bg].loaded = true;
                  console.log(this);
                  ctx.drawImage(this, x, y, width, height);

                  var sub = loaded[type.bg].sub;

                  for (var i = 0; i < sub.length; i++) sub[i]();
              };

работает так:
-если картинки нет в кэше то создать и добавить ее туда свойство ,loaded = false;

- если картинка не загружена , но есть в кэше то в свойство sub (подписка) добавляется функция которая вызовется после загрузки

- если картинка есть в кэше и загружена просто от рисовать

Дзен-трансгуманист 05.11.2012 00:12

cyber,
Я думаю, лучше сначала дождаться, пока загрузится всё что нужно, потом уже начинать рисовать. Это как когда загружаешь сохранение какой-нибудь обычной игры, там еще прогресс-бар как правило есть. Игра не начинается, пока не загрузятся ВСЕ нужные для данной точки игры ресурсы. Иначе бы ты наблюдал, как тысячи серых полигонов постепенно обретают конечную текстуризацию, в то время как по тебе уже палит десяток гангстеров, которых даже не различить. Странно было бы, не так ли? :)

cyber 05.11.2012 00:24

Дзен-трансгуманист,
суть понял , сделал так
if (!imgCache) {

                      var img = new Image();
                     
                      
                      imgCache = loaded[type.bg] = {
                          obj: img,
                          sub:[]
                      };

                      imgCache.sub.push(function () {

                          ctx.drawImage(imgCache.obj, x, y, width, height);
                      });


                      img.onload = function () {

                          for (var i = 0; i < imgCache.sub.length; i++) imgCache.sub[i]();
                      };
                      
                      img.src = type.bg;
                      img = null;
                  }

                  else {
                    
                      imgCache.sub.push(function () {
                          ctx.drawImage(imgCache.obj, x, y, width, height);
                      });
                  
                   }

спасибо за подсказку.


Часовой пояс GMT +3, время: 20:25.