简体   繁体   中英

html5 Canvas drawimage background + 9 images

I have a little problem, sometimes work or not work drawimage, i tried to begin with draw background and if drawed then next draw 9 images(sometimes images is this same or not same).

var c = document.getElementById('myCanvas');
    var ctx = c.getContext("2d");

    $('button').on('click',function(){

        var img = new Image();
        var img1 = new Image();
        var img2 = new Image();
        var img3 = new Image();
        var img4 = new Image();
        var img5 = new Image();
        var img6 = new Image();
        var img7 = new Image();
        var img8 = new Image();
        var img9 = new Image();
        img.src = $(location).attr('href')+'/img/frames/'+$('#frames option:selected').val();
        img1.src = $(location).attr('href')+'/img/mercmain/'+$('#merc1 option:selected').val();
        img2.src = $(location).attr('href')+'/img/mercmain/'+$('#merc2 option:selected').val();
        img3.src = $(location).attr('href')+'/img/mercmain/'+$('#merc3 option:selected').val();
        img4.src = $(location).attr('href')+'/img/mercmain/'+$('#merc4 option:selected').val();
        img5.src = $(location).attr('href')+'/img/mercmain/'+$('#merc5 option:selected').val();
        img6.src = $(location).attr('href')+'/img/mercmain/'+$('#merc6 option:selected').val();
        img7.src = $(location).attr('href')+'/img/mercmain/'+$('#merc7 option:selected').val();
        img8.src = $(location).attr('href')+'/img/mercmain/'+$('#merc8 option:selected').val();
        img9.src = $(location).attr('href')+'/img/mercmain/'+$('#merc9 option:selected').val();

        img.onload = function(){
            ctx.clearRect(0, 0, c.width, c.height);
            ctx.drawImage(img, 0, 0,307,382);

            img1.onload = function(){
                ctx.drawImage(img1,$xyframe[0][0],$xyframe[0][1],$xyframe[0][2],$xyframe[0][3]);
            };
            img2.onload = function(){
                ctx.drawImage(img2,$xyframe[1][0],$xyframe[1][1],$xyframe[1][2],$xyframe[1][3]);
            };
            img3.onload = function(){
                ctx.drawImage(img3,$xyframe[2][0],$xyframe[2][1],$xyframe[2][2],$xyframe[2][3]);
            };
            img4.onload = function(){
                ctx.drawImage(img4,$xyframe[3][0],$xyframe[3][1],$xyframe[3][2],$xyframe[3][3]);
            };
            img5.onload = function(){
                ctx.drawImage(img5,$xyframe[4][0],$xyframe[4][1],$xyframe[4][2],$xyframe[4][3]);
            };
            img6.onload = function(){
                ctx.drawImage(img6,$xyframe[5][0],$xyframe[5][1],$xyframe[5][2],$xyframe[5][3]);
            };
            img7.onload = function(){
                ctx.drawImage(img7,$xyframe[6][0],$xyframe[6][1],$xyframe[6][2],$xyframe[6][3]);
            };
            img8.onload = function(){
                ctx.drawImage(img8,$xyframe[7][0],$xyframe[7][1],$xyframe[7][2],$xyframe[7][3]);
            };
            img9.onload = function(){
                ctx.drawImage(img9,$xyframe[8][0],$xyframe[8][1],$xyframe[8][2],$xyframe[8][3]);
            };

        };
    });

and link to test script https://tajkjs-olszam.c9users.io/genform/

and if i remove from img1-9.onload, leave ctx.drawimage(img1-9) and make settimeout from 3 to 5 sec then it's ok but i want without settimeout.

setTimeout(function(){

               //img.onload = function(){
                ctx.drawImage(img, 0, 0,307,382);
           // };

                ctx.drawImage(img1,$xyframe[0][0],$xyframe[0][1],$xyframe[0][2],$xyframe[0][3]);



                ctx.drawImage(img2,$xyframe[1][0],$xyframe[1][1],$xyframe[1][2],$xyframe[1][3]);


                ctx.drawImage(img3,$xyframe[2][0],$xyframe[2][1],$xyframe[2][2],$xyframe[2][3]);


                ctx.drawImage(img4,$xyframe[3][0],$xyframe[3][1],$xyframe[3][2],$xyframe[3][3]);


                ctx.drawImage(img5,$xyframe[4][0],$xyframe[4][1],$xyframe[4][2],$xyframe[4][3]);


                ctx.drawImage(img6,$xyframe[5][0],$xyframe[5][1],$xyframe[5][2],$xyframe[5][3]);


                ctx.drawImage(img7,$xyframe[6][0],$xyframe[6][1],$xyframe[6][2],$xyframe[6][3]);


                ctx.drawImage(img8,$xyframe[7][0],$xyframe[7][1],$xyframe[7][2],$xyframe[7][3]);


                ctx.drawImage(img9,$xyframe[8][0],$xyframe[8][1],$xyframe[8][2],$xyframe[8][3]);
            },100);

this code is work but unfortunately I have use settimeout

Try not to draw on each image load. Use counter for loaded images and run draw function on last load. Also Pablo said right thing - set onload listener before set source. This code should run inside your click listener function

 var img; var counter = 0; var imagesLength = 9; var images = []; var backgroundImage = new Image(); var imgFolder = location.href+'/img/mercmain/'; function drawImages(){ ctx.clearRect(0, 0, c.width, c.height); ctx.drawImage(backgroundImage, 0, 0,307,382); //draw background for ( var i=0; i<imagesLength ; i++ ){ //draw images ctx.drawImage(images[i],$xyframe[i][0],$xyframe[i][1],$xyframe[i][2],$xyframe[i][3]); } } function onLoad(){ counter++; if( counter === imagesLength + 1 ){ // +1 - we must count also background image drawImages(); // draw all the images at once } } for ( var i=0; i<imagesLength ; i++ ){ img = new Image(); images.push( img ); // push in array before src, // onload should not fire while image is not in array img.onload = onLoad; // set onload before src, // image should not load before onload listener is set img.src = imgFolder + $('#merc'+ (i+1) +' option:selected').val(); } // do not forget to set the same for background image backgroundImage.onload = onLoad; backgroundImage.src = location.href + '/img/frames/' + $('#frames option:selected').val(); 

You have a race condition: You are loading all the images at the same time, but if the background image is not the first one to be loaded, you are adding the onload listeners AFTER the images have been loaded, so the event has already happened and the drawing logic is never executed.

Solution? the imgN.onload=function() {...} assignments should be outside the img.onload function:

$('button').on('click',function(){

    var img = new Image();
    var imgArr=[];
    for (var i=0;i<9;i++) {
        imgArr[i]=new Image();
    }

    img.src = $(location).attr('href')+'/img/frames/'+$('#frames option:selected').val();
    for (var i=0;i<9;i++) {
        imgArr[i].src=$(location).attr('href')+'/img/mercmain/'+$('#merc'+i+' option:selected').val();
    }
    img.onload = function(){
        ctx.clearRect(0, 0, c.width, c.height);
        ctx.drawImage(img, 0, 0,307,382);
    }
    //Here, instead in the previous function
    for (var i=0;i<9;i++) {
        imgArr[i].onload = function(){
            ctx.drawImage(img1,$xyframe[i][0],$xyframe[i][1],$xyframe[i][2],$xyframe[i][3]);
        };
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM