2015-03-17 2 views
0

Je suis en train de dessiner le texte à une toile avec un certain niveau alpha et le clip le texte et dessiner une couleur de fond avec son propre niveau alpha:html5 Toile filltext avec une certaine alpha et arrière-plan avec une autre alpha

ctx.globalCompositeOperation = '...'; 
    ctx.fillStyle = 'rgba(' + fgcolor.r + ', ' + fgcolor.g + ', ' + fgcolor.b + ',' + (fgcolor.a/255.0) + ')'; 
     ctx.fillText(String.fromCharCode(chr), x,y); 
ctx.globalCompositeOperation = '...'; 
    ctx.fillStyle = 'rgba(' + bgcolor.r + ', ' + bgcolor.g + ', ' + bgcolor.b + ',' + (bgcolor.a/255.0) + ')'; 
    ctx.fillRect(x, y, chr_width, chr_height); 

J'ai essayé de jouer avec globalCompositeOperation et beginPath mais j'ai été incapable d'atteindre le résultat souhaité. Je voudrais également éviter drawImage et les toiles hors écran car la vitesse est une préoccupation majeure.

+0

Veuillez clarifier ce que vous désirez. – markE

+0

Je veux essentiellement dessiner un caractère de texte sur le canevas en utilisant filltext et créer une région de découpage pour dessiner l'arrière-plan. De cette façon, le caractère de premier plan peut avoir un niveau alpha et la couleur de fond peut avoir son propre niveau alpha. Pensez à une console DOS où chaque cellule a une couleur de premier plan et une couleur de fond. –

Répondre

1

Cette fonction vous permet de convertir des couleurs RGBA RGB:

function RGBAtoRGB(r, g, b, a, backgroundR,backgroundG,backgroundB){ 
    var r3 = Math.round(((1 - a) * backgroundR) + (a * r)) 
    var g3 = Math.round(((1 - a) * backgroundG) + (a * g)) 
    var b3 = Math.round(((1 - a) * backgroundB) + (a * b)) 
    return "rgb("+r3+","+g3+","+b3+")"; 
} 
  1. Convertir le RGBA de fond RVB et remplir le fond avec RGB.

  2. Convertissez le RGBA de premier plan en RGB et remplissez le texte de premier plan avec RGB.

+0

Réponse intéressante mais j'aurais dû mentionner qu'il y a plusieurs couches. Il doit avoir l'alpha pour voir les couches en dessous. –

+0

Cette réponse fonctionnera si toutes les couches sont monochromatiques (par opposition aux dégradés ou aux images). Il suffit de réduire toutes les couches monochromatiques de RGBA à RVB de la couche la plus basse à la couche supérieure. – markE

+0

Chaque calque est une console de texte. Il ne s'agirait donc pas d'une couleur solide mais d'un caractère de police. N'y a-t-il aucun moyen de le faire en utilisant une séquence d'appels globalCompositeOperation? L'accès aux données du tampon est trop lent et l'utilisation de drawImage est également un goulot d'étranglement. –

0

C'est exactement ce que je suis en train de faire:

    ctx.clearRect(x, y, chr_width, chr_height); 
       ctx.save(); 
      ctx.beginPath(); 
      ctx.rect(x, y, chr_width, chr_height); 
      ctx.clip();  

      if (fgcolor.a != 255) { 
       ctx.fillStyle = 'rgba(' + fgcolor.r + ', ' + fgcolor.g + ', ' + fgcolor.b + ',' + (fgcolor.a/255.0) + ')'; 

       ctx.fillText(String.fromCharCode(chr), x,y); 

       var imgData=ctx.getImageData(x,y,chr_width,chr_height); 
       for (var idx = 0; idx < imgData.data.length; idx+=4) { 
        if (! imgData.data[idx+3]) { 
         imgData.data[idx] = bgcolor.r; 
         imgData.data[idx+1] = bgcolor.g; 
         imgData.data[idx+2] = bgcolor.b; 
         imgData.data[idx+3] = bgcolor.a; 
        } 
       } 

       ctx.putImageData(imgData,x,y); 
      } 
      else { 
       ctx.fillStyle = 'rgba(' + bgcolor.r + ', ' + bgcolor.g + ', ' + bgcolor.b + ',' + (bgcolor.a/255.0) + ')'; 
       ctx.fillRect(x, y, chr_width, chr_height); 
       ctx.fillStyle = 'rgba(' + fgcolor.r + ', ' + fgcolor.g + ', ' + fgcolor.b + ',' + (fgcolor.a/255.0) + ')'; 
       ctx.fillText(String.fromCharCode(chr), x,y); 

      } 

      ctx.globalAlpha = 1.0; 

      ctx.globalCompositeOperation = 'source-over'; 

      ctx.restore(); 

Y a-t-il des moyens plus rapides d'y parvenir en évitant d'accéder aux données directement? Merci.