来自以前功能的图像不会在后台绘制(画布) [英] Images from previous functions are not drawn in the background (Canvas)

查看:111
本文介绍了来自以前功能的图像不会在后台绘制(画布)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是关于使用HTML Canvas中的函数绘图。
我尝试用Canvas绘制Trading Cards来创建游戏。
所以我决定写一个函数,获取所有必要的信息来绘制不同的卡。
对于一张卡 - 没有问题。但是如果我尝试在第一张卡上绘制另一张卡片,则可以通过第二张卡片看到第一张卡片的图像。



这里是源代码: / p>

  function RoundRect(x,y,scale,lvl,mage,headline,text,HP,MP,AtckP,DefP,MDefP) {
// Kartenumriss zeichnen
context.strokeStyle =rgb(0,0,0);
context.fillStyle =rgb(180,180,180);
context.lineWidth = 2 * scale;
context.beginPath();
context.moveTo(x + 10 * scale,y + 0 * scale);
context.lineTo(x + 90 * scale,y + 0 * scale);
context.arcTo(x + 100 * scale,y + 0 * scale,x + 100 * scale,y + 10 * scale,10 * scale);
context.lineTo(x + 100 * scale,y + 110 * scale);
context.arcTo(x + 100 * scale,y + 120 * scale,x + 90 * scale,y + 120 * scale,10 * scale);
context.lineTo(x + 10 * scale,y + 120 * scale);
context.arcTo(x + 0 * scale,y + 120 * scale,x + 0 * scale,y + 110 * scale,10 * scale);
context.lineTo(x + 0 * scale,y + 10 * scale);
context.arcTo(x + 0 * scale,y + 0 * scale,x + 10 * scale,y + 0 * scale,10 * scale);
context.fill();
context.stroke();
// innerer Kartenumriss zeichnen
context.strokeStyle =rgb(0,0,0);
context.lineWidth = 2 * scale;
context.beginPath();
context.moveTo(x + 20 * scale,y + 10 * scale)
context.lineTo(x + 80 * scale,y + 10 * scale)
context.arcTo(x + 80 * scale,y + 20 * scale,x + 90 * scale,y + 20 * scale,10 * scale);
context.lineTo(x + 90 * scale,y + 100 * scale);
context.arcTo(x + 80 * scale,y + 100 * scale,x + 80 * scale,y + 110 * scale,10 * scale);
context.lineTo(x + 20 * scale,y + 110 * scale);
context.arcTo(x + 20 * scale,y + 100 * scale,x + 10 * scale,y + 100 * scale,10 * scale);
context.lineTo(x + 10 * scale,y + 20 * scale);
context.arcTo(x + 20 * scale,y + 20 * scale,x + 20 * scale,y + 10 * scale,10 * scale);
context.lineCap =square;
context.stroke();
// Textfeld zeichnen
context.strokeStyle =rgb(0,0,0);
context.fillStyle =rgb(0,0,0);
context.lineWidth = 2 * scale;
context.beginPath();
context.moveTo(x + 90 * scale,y + 65 * scale);
context.lineTo(x + 90 * scale,y + 100 * scale);
context.arcTo(x + 80 * scale,y + 100 * scale,x + 80 * scale,y + 110 * scale,10 * scale);
context.lineTo(x + 20 * scale,y + 110 * scale);
context.arcTo(x + 20 * scale,y + 100 * scale,x + 10 * scale,y + 100 * scale,10 * scale);
context.lineTo(x + 10 * scale,y + 65 * scale);
context.arcTo(x + 20 * scale,y + 65 * scale,x + 20 * scale,y + 75 * scale,10 * scale);
context.lineTo(x + 80 * scale,y + 75 * scale)
context.arcTo(x + 80 * scale,y + 65 * scale,x + 90 * scale,y + 65 * scale,10 * scale)
context.lineCap =square;
context.fill();
context.stroke();
// lvl zeichnen
shift = 0;
for(var greystar = 0; greystar< = 4; greystar ++){
context.strokeStyle =rgb(100,100,100);
context.fillStyle =rgb(100,100,100);
context.beginPath();
context.moveTo(shift + x + 23.33 * scale,y + 112 * scale);
context.lineTo(shift + x + 25.33 * scale,y + 118.66 * scale);
context.lineTo(shift + x + 20 * scale,y + 114.53 * scale);
context.lineTo(shift + x + 26.66 * scale,y + 114.53 * scale);
context.lineTo(shift + x + 21.26 * scale,y + 118.66 * scale);
context.lineTo(shift + x + 23.33 * scale,y + 112 * scale);
context.fill();
shift + = 13.5 * scale;
}
shift = 0;
while(lvl> 0){
context.strokeStyle =yellow;
context.fillStyle =yellow;
context.beginPath();
context.moveTo(shift + x + 23.33 * scale,y + 112 * scale);
context.lineTo(shift + x + 25.33 * scale,y + 118.66 * scale);
context.lineTo(move + x + 20 * scale,y + 114.53 * scale);
context.lineTo(shift + x + 26.66 * scale,y + 114.53 * scale);
context.lineTo(shift + x + 21.26 * scale,y + 118.66 * scale);
context.lineTo(shift + x + 23.33 * scale,y + 112 * scale);
context.fill();
shift + = 13.5 * scale;
lvl--;
}
// Bild einbinden
var chucknorris = new Image();
chucknorris.onload = function(){
context.drawImage(chucknorris,x + 18 * scale,y + 18 * scale,64 * scale,49 * scale)
};
chucknorris.src =pics / chucknorris.png;
// Symbole einbinden
// life
var life = new Image();
life.onload = function(){
context.drawImage(life,x + 87 * scale,y + 11 * scale,7 * scale,7 * scale)
};
life.src =pics / heart_small.png;
// magic
var magic = new Image();
magic.onload = function(){
context.drawImage(magic,x + 6 * scale,y + 11 * scale,7 * scale,7 * scale)
};
magic.src =pics / magic_small.png;
if(mage == true){
// wand
var wand = new Image();
wand.onload = function(){
context.drawImage(wand,x + 6 * scale,y + 102 * scale,7 * scale,7 * scale)
};
wand.src =pics / wand_small.png;
}
else {
// sword
var sword = new Image();
sword.onload = function(){
context.drawImage(sword,x + 6 * scale,y + 102 * scale,7 * scale,7 * scale)
};
sword.src =pics / sword_crossed_small.png;
}
// shield
var shield = new Image();
shield.onload = function(){
context.drawImage(shield,x + 85 * scale,y + 102 * scale,7 * scale,7 * scale)
};
shield.src =pics / shield_small.png;
// magic_shield
var magic_shield = new Image();
magic_shield.onload = function(){
context.drawImage(magic_shield,x + 91 * scale,y + 102 * scale,7 * scale,7 * scale)
};
magic_shield.src =pics / magic_shield_small.png;
// Texteinfügen
context.font ='bold'+ 4 * scale +'px Calibri';
context.fillStyle ='rgb(255,255,255)';
context.fillText(headline,x + 20 * scale,y + 80 * scale);
context.font ='normal'+ 3 * scale +'px Calibri';
context.fillStyle ='rgb(255,255,255)';
wrapText(context,text,x + 20 * scale,y + 85 * scale,maxWidth,lineHeight,scale);
// HP anzeigen
context.font ='bold 20pt Calibri';
context.fillStyle ='rgb(255,0,0)';
var textmetric = context.measureText(HP);
var textwidth = textmetric.width / 2;
context.fillText(HP,x-textwidth + 90.25 * scale,y + 10 * scale);
// MP anzeigen
context.fillStyle ='rgb(0,0,255)';
textmetric = context.measureText(MP);
textwidth = textmetric.width / 2;
context.fillText(MP,x-textwidth + 9.5 * scale,y + 10 * scale);
// AtckP anzeigen
context.fillStyle ='rgb(0,0,0)';
textmetric = context.measureText(AtckP);
textwidth = textmetric.width / 2;
context.fillText(AtckP,x-textwidth + 9.5 * scale,y + 115 * scale);
// DefP und MDefP anzeigen
context.fillStyle ='rgb(0,0,0)';
var DefAll = DefP +'/'+ MDefP;
textmetric = context.measureText(DefAll);
textwidth = textmetric.width;
context.fillText(DefAll,x-textwidth + 98 * scale,y + 115 * scale);
};

我认为重要的部分在// Bild einbinden和// Texteinfügen之间



这个函数稍后在测试代码中使用,如下所示:

  RoundRect(0,0,4,5,false,'Chuck Norris','Wenn Chuck Norris spricht,hörtGott zu !!! Chuck Norris`TränenkönnenKrebs heilen。Nur schade dass er niemals weint !!! Chuck Norris geht manchmal Blut spenden。Nur nie sein eigenes。Und wenn doch,dann mit ner Knarre und nem Eimer !!!','100','0','120','20',' 60'); 
RoundRect(100,120,4,2,false,'Chuck Norris Vers 0.3','Wenn Chuck Norris Spricht,hörtGott zu !!! Chuck Norris`TränenkönnenKrebs heilen。Nur schade dass er niemals weint !!! Chuck Norris geht manchmal Blut spenden。Nur nie sein eigenes。Und wenn doch,dann mit ner Knarre und nem Eimer !!!','50','100','60','10','30');

这里的结果是:



结果



我希望有人能帮助我。事先感谢你(< - 希望Google-Tranlator在这里 - 对我来说听起来不错...)。



编辑:
一部分的问题,但我仍然需要一个解决方案:
我试图在代码中设置一些alert();。结果是interessting:首先,从第一张卡的背景绘制。然后第二张卡的背景。之后,第一张卡的图像被绘制,然后其他的从第二张卡。所以绘制后的图像在其他一切。
所以问题是如何告诉画布立即绘制图像,或至少在函数内。

解决方案

p>

这意味着函数将首先渲染图像的背景。第一张卡,为你的Image.onLoad事件注册一个监听器,然后返回,这样你可以进行seconde调用,这将渲染背景,并为新的Image.onLoad事件注册另一个监听器。然后第一个监听器在第一个图像加载时触发,因此它将绘制图片,最后一个监听器将被触发。因此您的结果。



有关解决此问题的方法,您可以在绘制任何卡片之前加载图片,并直接在您的函数中绘制,避免等待为加载,或者你有你的设计异步防护。您可以在此处获取有关异步编程的信息: http://www.html5rocks .com / en / tutorials / async / deferred /?redirect_from_locale =为什么



编辑:第二个解决方案可以帮助第一个解决方案答案enzhflep)。该文章建议使用jquery来处理异步事件,如加载多个图像。但是如果你不需要jQuery,你还可以编写一个小的javascript对象,可以注册要加载的图像,并在所有图像加载时触发侦听器。 此资源似乎提供该特定对象。


My question is about drawing with functions in HTML Canvas. I try to draw "Trading Cards" with Canvas to create a Game. So I decided to write a function that gets all necessary information to draw different cards. For one card - no problem. But if I try to draw another card on top of the first one, the images from the first card can be seen through the second Card.

Here's the source code:

function RoundRect(x,y,scale,lvl,mage,headline,text,HP,MP,AtckP,DefP,MDefP){
            //Kartenumriss zeichnen
            context.strokeStyle="rgb(0,0,0)";
            context.fillStyle="rgb(180,180,180)";
            context.lineWidth=2*scale;
            context.beginPath();
            context.moveTo(x+10*scale,y+0*scale);
            context.lineTo(x+90*scale,y+0*scale);
            context.arcTo(x+100*scale,y+0*scale,x+100*scale,y+10*scale,10*scale);
            context.lineTo(x+100*scale,y+110*scale);
            context.arcTo(x+100*scale,y+120*scale,x+90*scale,y+120*scale,10*scale);
            context.lineTo(x+10*scale,y+120*scale);
            context.arcTo(x+0*scale,y+120*scale,x+0*scale,y+110*scale,10*scale);
            context.lineTo(x+0*scale,y+10*scale);
            context.arcTo(x+0*scale,y+0*scale,x+10*scale,y+0*scale,10*scale);
            context.fill();
            context.stroke();
            //innerer Kartenumriss zeichnen
            context.strokeStyle="rgb(0,0,0)";
            context.lineWidth=2*scale;
            context.beginPath();
            context.moveTo(x+20*scale,y+10*scale)
            context.lineTo(x+80*scale,y+10*scale);
            context.arcTo(x+80*scale,y+20*scale,x+90*scale,y+20*scale,10*scale);
            context.lineTo(x+90*scale,y+100*scale);
            context.arcTo(x+80*scale,y+100*scale,x+80*scale,y+110*scale,10*scale);
            context.lineTo(x+20*scale,y+110*scale);
            context.arcTo(x+20*scale,y+100*scale,x+10*scale,y+100*scale,10*scale);
            context.lineTo(x+10*scale,y+20*scale);
            context.arcTo(x+20*scale,y+20*scale,x+20*scale,y+10*scale,10*scale);
            context.lineCap="square";
            context.stroke();
            //Textfeld zeichnen
            context.strokeStyle="rgb(0,0,0)";
            context.fillStyle="rgb(0,0,0)";
            context.lineWidth=2*scale;
            context.beginPath();
            context.moveTo(x+90*scale,y+65*scale);
            context.lineTo(x+90*scale,y+100*scale);
            context.arcTo(x+80*scale,y+100*scale,x+80*scale,y+110*scale,10*scale);
            context.lineTo(x+20*scale,y+110*scale);
            context.arcTo(x+20*scale,y+100*scale,x+10*scale,y+100*scale,10*scale);
            context.lineTo(x+10*scale,y+65*scale);
            context.arcTo(x+20*scale,y+65*scale,x+20*scale,y+75*scale,10*scale);
            context.lineTo(x+80*scale,y+75*scale)
            context.arcTo(x+80*scale,y+65*scale,x+90*scale,y+65*scale,10*scale)
            context.lineCap="square";
            context.fill();
            context.stroke();
            //lvl zeichnen
            shift=0;
            for(var greystar=0;greystar<=4; greystar++){
                context.strokeStyle="rgb(100,100,100)";
                context.fillStyle="rgb(100,100,100)";
                context.beginPath();
                context.moveTo(shift+x+23.33*scale,y+112*scale);
                context.lineTo(shift+x+25.33*scale,y+118.66*scale);
                context.lineTo(shift+x+20*scale,y+114.53*scale);
                context.lineTo(shift+x+26.66*scale,y+114.53*scale);
                context.lineTo(shift+x+21.26*scale,y+118.66*scale);
                context.lineTo(shift+x+23.33*scale,y+112*scale);
                context.fill();
                shift+=13.5*scale;
            }
            shift=0;
            while(lvl>0){
                context.strokeStyle="yellow";
                context.fillStyle="yellow";
                context.beginPath();
                context.moveTo(shift+x+23.33*scale,y+112*scale);
                context.lineTo(shift+x+25.33*scale,y+118.66*scale);
                context.lineTo(shift+x+20*scale,y+114.53*scale);
                context.lineTo(shift+x+26.66*scale,y+114.53*scale);
                context.lineTo(shift+x+21.26*scale,y+118.66*scale);
                context.lineTo(shift+x+23.33*scale,y+112*scale);
                context.fill();
                shift+=13.5*scale;
                lvl--;
            }
            //Bild einbinden
            var chucknorris = new Image();
            chucknorris.onload = function() {
                context.drawImage(chucknorris,x+18*scale,y+18*scale,64*scale,49*scale);
            };
            chucknorris.src="pics/chucknorris.png";
            //Symbole einbinden
            //life
            var life = new Image();
            life.onload = function() {
                context.drawImage(life,x+87*scale,y+11*scale,7*scale,7*scale);
            };
            life.src="pics/heart_small.png";
            //magic
            var magic = new Image();
            magic.onload = function() {
                context.drawImage(magic,x+6*scale,y+11*scale,7*scale,7*scale);
            };
            magic.src="pics/magic_small.png";
            if(mage==true){
                //wand
                var wand = new Image();
                wand.onload = function() {
                    context.drawImage(wand,x+6*scale,y+102*scale,7*scale,7*scale);
                };
                wand.src="pics/wand_small.png";
            }
            else{
                //sword
                var sword = new Image();
                sword.onload = function() {
                    context.drawImage(sword,x+6*scale,y+102*scale,7*scale,7*scale);
                };
                sword.src="pics/sword_crossed_small.png";
            }
            //shield
            var shield = new Image();
            shield.onload = function() {
                context.drawImage(shield,x+85*scale,y+102*scale,7*scale,7*scale);
            };
            shield.src="pics/shield_small.png";
            //magic_shield
            var magic_shield = new Image();
            magic_shield.onload = function() {
                context.drawImage(magic_shield,x+91*scale,y+102*scale,7*scale,7*scale);
            };
            magic_shield.src="pics/magic_shield_small.png";
            //Text einfügen
            context.font = 'bold '+4*scale+'px Calibri';
            context.fillStyle = 'rgb(255,255,255)';
            context.fillText(headline,x+20*scale, y+80*scale);
            context.font = 'normal '+3*scale+'px Calibri';
            context.fillStyle = 'rgb(255,255,255)';
            wrapText(context, text, x+20*scale, y+85*scale, maxWidth, lineHeight, scale);
            //HP anzeigen
            context.font = 'bold 20pt Calibri';
            context.fillStyle = 'rgb(255,0,0)';
            var textmetric = context.measureText(HP);
            var textwidth = textmetric.width/2;
            context.fillText(HP,x-textwidth+90.25*scale, y+10*scale);
            //MP anzeigen
            context.fillStyle = 'rgb(0,0,255)';
            textmetric = context.measureText(MP);
            textwidth = textmetric.width/2;
            context.fillText(MP,x-textwidth+9.5*scale, y+10*scale);
            //AtckP anzeigen
            context.fillStyle = 'rgb(0,0,0)';
            textmetric = context.measureText(AtckP);
            textwidth = textmetric.width/2;
            context.fillText(AtckP,x-textwidth+9.5*scale, y+115*scale);
            //DefP und MDefP anzeigen
            context.fillStyle = 'rgb(0,0,0)';
            var DefAll = DefP+'/'+MDefP;
            textmetric = context.measureText(DefAll);
            textwidth = textmetric.width;
            context.fillText(DefAll,x-textwidth+98*scale, y+115*scale);
        };

I think the important part is between "//Bild einbinden" and "//Text einfügen" but I'm not sure about that.

The function is used later in the test code like this:

RoundRect(0,0,4,5,false,'Chuck Norris','Wenn Chuck Norris spricht, hört Gott zu!!! Chuck Norris` Tränen können Krebs heilen. Nur schade dass er niemals weint!!! Chuck Norris geht manchmal Blut spenden. Nur nie sein eigenes. Und wenn doch, dann mit ner Knarre und nem Eimer!!!','100','0','120','20','60');
RoundRect(100,120,4,2,false,'Chuck Norris Vers 0.3','Wenn Chuck Norris spricht, hört Gott zu!!! Chuck Norris` Tränen können Krebs heilen. Nur schade dass er niemals weint!!! Chuck Norris geht manchmal Blut spenden. Nur nie sein eigenes. Und wenn doch, dann mit ner Knarre und nem Eimer!!!','50','100','60','10','30');

Here the result:

Result

I hope there's someone who can help me. Thank you in advance ever (<- hope Google-Tranlator is right here - sounds wrong for me...).

Edit: I figured out a part of the problem, but I still need a solution: I tried to set some "alert();"s in the code. The result was interessting: First, the background from the first card is drawed. Then the background of the second card. After that the images of the first card are drawed, then the others from the second card. So the images where drawn AFTER everything else is drawn. So the Problem is how to tell the the Canvas to draw the images immediately, or at least within the function.

解决方案

You get the images drawn after everything because they are drawn in the callback of Image.onLoad().

This means that the function will first render the background of the first card, register a listener for your Image.onLoad events, then return, so that you can make the seconde call, which will render the background, and register another listener for the new Image.onLoad events. Then the first listener is triggered when the first image is loaded, so it will draw the picture, and a last the second listener will be triggered. Hence your result.

As for a way to resolve this issue, either you can load your images before drawing any card, and draw it directly in your function, avoiding to wait for the loading, or you hav to make your design Asynchronous-proof. You can get information about asynchronous programming here: http://www.html5rocks.com/en/tutorials/async/deferred/?redirect_from_locale=why

Edit: The second solution can help with the first one (which corresponds to the answer of enzhflep). The article recommands the use of jquery to deal with asynchronous events such as loading multiple images. But if you don't need jQuery, you can also code a small javascript object that can register images to be loaded, and trigger a listener when all images are loaded. This ressource seems to offer that specific object.

这篇关于来自以前功能的图像不会在后台绘制(画布)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆