简体   繁体   English

html5画布drawimage背景+ 9张图像

[英]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). 我有一个小问题,有时工作或不工作drawimage,我尝试从绘制背景开始,如果绘制,则下一个绘制9张图像(有时图像是相同的还是不相同的)。

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/ 并链接到测试脚本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. 如果我从img1-9.onload中删除,请离开ctx.drawimage(img1-9)并使settimeout从3到5秒,那么还可以,但是我希望没有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 这段代码是可行的,但不幸的是我已经使用了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. Pablo也说对了-在设置源之前设置onload监听器。 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. 您有一个竞争条件:您要同时加载所有图像,但是如果背景图像不是要加载的第一个图像,则在图像加载后添加onload侦听器,因此该事件已经发生并且绘图逻辑从不执行。

Solution? 解? the imgN.onload=function() {...} assignments should be outside the img.onload function: imgN.onload=function() {...}分配应该在img.onload函数之外:

$('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]);
        };
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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