Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Canvas, проблемы с отрисовкой изображений (https://javascript.ru/forum/misc/32074-canvas-problemy-s-otrisovkojj-izobrazhenijj.html)

sunAirway 02.10.2012 16:13

Canvas, проблемы с отрисовкой изображений
 
Для рисования готового изображения используется 3 паттерна для заливки, всё это собрано в одну функцию:
function drawFooter() {
    var footer = document.getElementById("canvas-footer");
    if (footer.getContext) {
        var footerContext = footer.getContext("2d");                
        var MainFooterimageObj = new Image();
        MainFooterimageObj.src = "images/bg-red2.gif";
        MainFooterimageObj.onload = function() {
            var MainFooterPattern = footerContext.createPattern(MainFooterimageObj, "repeat"); 

            footerContext.fillStyle = MainFooterPattern;
            footerContext.fillRect (0, 23, 940, 205);        
        };  
        
        var DarkFooterimageObj = new Image();
        DarkFooterimageObj.src = "images/bg-red3.gif";
        DarkFooterimageObj.onload = function() {
            var DarkFooterPattern = footerContext.createPattern(DarkFooterimageObj, "repeat");
                              
            footerContext.fillStyle = DarkFooterPattern;
            footerContext.fillRect (24, 70, 453, 148);
            footerContext.fillStyle = DarkFooterPattern;
            footerContext.fillRect (498, 70, 229, 148);
            footerContext.fillStyle = DarkFooterPattern;
            footerContext.fillRect (748, 70, 168, 60);
        };
                
        var LightFooterimageObj = new Image();
        LightFooterimageObj.src = "images/bg-red4.gif";
        LightFooterimageObj.onload = function() {
            var LightFooterPattern = footerContext.createPattern(LightFooterimageObj, "repeat");
            footerContext.beginPath();
            footerContext.moveTo(0, 23);
            footerContext.bezierCurveTo(0, 23, 30, 11, 60, 0);
            footerContext.bezierCurveTo(60, 0, 400, 0, 880, 0);
            footerContext.bezierCurveTo(880, 0, 905, 10, 940, 23);
            footerContext.bezierCurveTo(940, 23, 400, 23, 0, 23);

            footerContext.closePath();
            footerContext.fillStyle = LightFooterPattern;
            footerContext.fill();  
            
            footerContext.fillStyle = LightFooterPattern;
            footerContext.fillRect (53, 86, 410, 118); 
            footerContext.fillRect (512, 86, 200, 118);
        };      
    }
}


Периодически возникают проблемы или с подгрузкой изображений или ещё с чем-то, но в общем-то эффект такой - фоновое изображение, которое MainFooterimageObj отрисовывается, а два других нет, при повторном вызове функции drawFooter() через консоль браузера, в 95% случаев всё становится как надо.

Сталкивался ли кто-нибудь с этим? Может у кого-нибудь есть идеи по оптимизации?

dmitriymar 02.10.2012 16:33

патерны создаются асинхронно по мере загрузки изображений. код по загрузке начинает выполняться а патерна ещё нет. последовательно делать , или проверять существует патерн или нет .
а в том что при повторном вызове-ничего удивительного-изображения уже закешированы

sunAirway 02.10.2012 17:37

Цитата:

Сообщение от dmitriymar
последовательно делать , или проверять существует патерн или нет .

что вы имеете ввиду под последовательностью? ведь я создаю паттерн, когда картинка загрузилась, а под проверкой вы понимаете проверку создание паттерна и повторный вызов этого куска кода при отсутствии?

Цитата:

Сообщение от dmitriymar
а в том что при повторном вызове-ничего удивительного-изображения уже закешированы

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

sunAirway 02.10.2012 18:10

Кажется, я поняла вашу мысль о последовательности, после того, как нашла причину "неотрисовки". На самом деле всё было ок, просто картинки загружаются не в том порядке, в котором они прописаны в коде(что и следовало ожидать), а значит, то что раньше загрузилось, то и отрисовалось в первую очередь, в связи с чем идёт перекрытие и нам просто не видно самых маленьких частей.
Решила это путём вложенности кода, спасибо за то, что натолкнули на эту мысль.

impfromliga 07.01.2016 22:21

Это не ошибка, а следствие многопоточности браузера!
 
Цитата:

Сообщение от sunAirway (Сообщение 207748)
Периодически возникают проблемы или с подгрузкой изображений


:-E Самое противное в этой особенности, что она может в 95% не проявляться.

Дело в том, что загрузка ресурсов браузером производиться в отдельных от JS потоках! И генерация onload может успеть "сработать" еще до того, как обработчик поставлен (если вы ставите его ниже).

Точный момент срабатывания Image.onload в браузерах может быть разным, на всякий случай ВСЕГДА
//назначайте сначала обработчик:
LightFooterimageObj.onload = function() {/*...*/}
//а только потом загрузку:
LightFooterimageObj.src = "images/bg-red4.gif";


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