222 votes

Comment modifier l'opacité (alpha, transparence) d'un élément dans un élément de canevas après qu'il ait été dessiné ?

Utilisation du HTML5 <canvas> Je voudrais charger un fichier image (PNG, JPEG, etc.), le dessiner sur le canevas de manière totalement transparente, puis l'intégrer en fondu. J'ai trouvé comment charger l'image et la dessiner sur la toile, mais je ne sais pas comment modifier son opacité une fois qu'elle a été dessinée.

Voici le code que j'ai jusqu'à présent :

var canvas = document.getElementById('myCanvas');

if (canvas.getContext)
{
    var c           = canvas.getContext('2d');
    c.globalAlpha   = 0;

    var img     = new Image();
    img.onload  = function() {
        c.drawImage(img, 0, 0);
    }
    img.src     = 'image.jpg';
}

Quelqu'un peut-il m'indiquer une propriété à définir ou une fonction à appeler pour modifier l'opacité ?

338voto

djdolber Points 1281

Je suis également à la recherche d'une réponse à cette question (pour clarifier, je veux être en mesure de dessiner une image avec une opacité définie par l'utilisateur, comme vous pouvez dessiner des formes avec opacité) si vous dessinez avec des formes primitives, vous pouvez définir la couleur de remplissage et de course avec alpha pour définir la transparence. Pour autant que j'en aie conclu pour l'instant, cela ne semble pas affecter le dessin d'images.

//works with shapes but not with images
ctx.fillStyle = "rgba(255, 255, 255, 0.5)";

J'ai conclu que la fixation de la globalCompositeOperation fonctionne avec des images.

//works with images
ctx.globalCompositeOperation = "lighter";

Je me demande s'il n'existe pas un troisième moyen de définir la couleur afin de pouvoir teinter les images et les rendre transparentes facilement.

EDIT :

Après avoir creusé davantage, j'ai conclu que vous pouvez définir la transparence d'une image en définissant le paramètre globalAlpha AVANT de dessiner l'image :

//works with images
ctx.globalAlpha = 0.5

Si vous souhaitez obtenir un effet de fondu au fil du temps, vous avez besoin d'une sorte de boucle qui modifie la valeur alpha, ce qui est assez facile, une façon de le faire est la fonction setTimeout consultez-la pour créer une boucle à partir de laquelle vous modifiez l'alpha au fil du temps.

8 votes

GlobalAlpha fonctionne parfaitement. Fait partie de la norme : whatwg.org/specs/web-apps/current-work/multipage/

44 votes

Pour être précis, ce n'est pas le canvas qui possède l'élément globalAlpha mais le contexte que vous obtenez du canevas.

9 votes

Le commentaire de Ian ci-dessous concernant ctx.save() et ctx.restore() empêche l'alpha global d'affecter le reste du canevas.

124voto

Ian Points 1530

Quelques exemples de code plus simple pour utiliser globalAlpha :

ctx.save();
ctx.globalAlpha = 0.4;
ctx.drawImage(img, x, y);
ctx.restore();

Si vous avez besoin img à charger :

var img = new Image();
img.onload = function() {
    ctx.save();
    ctx.globalAlpha = 0.4;
    ctx.drawImage(img, x, y);
    ctx.restore()
};
img.src = "http://...";

Notes :

  • Définissez le 'src' enfin, pour garantir que votre onload est appelé sur toutes les plateformes, même si l'image est déjà dans le cache.

  • Les modifications apportées à des éléments tels que globalAlpha entre un save et restore (en fait, je les utilise beaucoup), afin de vous assurer que vous n'englobez pas des paramètres provenant d'ailleurs, en particulier lorsque des parties du code de dessin vont être appelées à partir d'événements.

0 votes

GlobalAlpha rendra floues toutes les images ou les dessins sur une toile, ce qui n'est pas ce que vous voulez.

6 votes

@Grumpy - non, globalAlpha ne brouille rien. Il va définir l'alpha pour toutes les ultérieur (cela ne change rien à ce qui est déjà dessiné), c'est pourquoi dans le code de l'exemple je l'ai enveloppé dans save et restore pour limiter son champ d'application.

0 votes

Pas sûr que ctx.restore() va restaurer globalAlpha vous pourriez aussi avoir besoin de faire ceci à la fin (au moins je devais le faire dans les versions précédentes de Chrome) ctx.globalAlpha = 1 ;

15voto

james.garriss Points 3647

Edit : La réponse marquée comme "correcte" n'est pas correcte.

C'est facile à faire. Essayez ce code, en remplaçant "ie.jpg" par l'image que vous avez sous la main :

<!DOCTYPE HTML>
<html>
    <head>
        <script>
            var canvas;
            var context;
            var ga = 0.0;
            var timerId = 0;

            function init()
            {
                canvas = document.getElementById("myCanvas");
                context = canvas.getContext("2d");
                timerId = setInterval("fadeIn()", 100);
            }

            function fadeIn()
            {
                context.clearRect(0,0, canvas.width,canvas.height);
                context.globalAlpha = ga;
                var ie = new Image();
                ie.onload = function()
                {
                    context.drawImage(ie, 0, 0, 100, 100);
                };
                ie.src = "ie.jpg";

                ga = ga + 0.1;
                if (ga > 1.0)
                {
                    goingUp = false;
                    clearInterval(timerId);
                }
            }
        </script>
    </head>
    <body onload="init()">
        <canvas height="200" width="300" id="myCanvas"></canvas>
    </body>
</html>

La clé est la propriété globalAlpha.

Testé avec IE 9, FF 5, Safari 5, et Chrome 12 sur Win7.

13voto

Soul_man Points 163

Cette suggestion est basée sur la manipulation des pixels dans le contexte de la toile 2d.

Du MDN :

Vous pouvez manipuler directement les données des pixels dans les toiles au niveau des octets.

Pour manipuler les pixels, nous utiliserons deux fonctions ici - getImageData et putImageData .

getImageData l'usage :

var myImageData = context.getImageData(left, top, width, height);

Le site putImageData la syntaxe :

context.putImageData(myImageData, x, y); 

context est le contexte de votre toile 2d, et x et y sont la position sur la toile.

Donc pour obtenir les valeurs rouge, vert, bleu et alpha, nous allons faire ce qui suit :

var r = imageData.data[((x*(imageData.width*4)) + (y*4))];
var g = imageData.data[((x*(imageData.width*4)) + (y*4)) + 1];
var b = imageData.data[((x*(imageData.width*4)) + (y*4)) + 2];
var a = imageData.data[((x*(imageData.width*4)) + (y*4)) + 3];

x est le décalage horizontal, y est le décalage vertical.

Le code qui rend l'image semi-transparente :

var canvas = document.getElementById('myCanvas');
var c = canvas.getContext('2d');
var img = new Image();
img.onload  = function() {
   c.drawImage(img, 0, 0);
   var ImageData = c.getImageData(0,0,img.width,img.height);
   for(var i=0;i<img.height;i++)
      for(var j=0;j<img.width;j++)
         ImageData.data[((i*(img.width*4)) + (j*4) + 3)] = 127;//opacity = 0.5 [0-255]
   c.putImageData(ImageData,0,0);//put image data back
}
img.src = 'image.jpg';

Vous pouvez créer vos propres "shaders" - voir l'article MDN complet ici

8voto

Og2t Points 41

Vous le pouvez. La toile transparente peut être rapidement estompée en utilisant destination-out opération composite globale. Elle n'est pas parfaite à 100%, elle laisse parfois des traces mais elle peut être ajustée en fonction des besoins (par exemple, utiliser 'source-over' et le remplir de couleur blanche avec un alpha de 0.13, puis faire un fondu pour préparer la toile).

// Fill canvas using 'destination-out' and alpha at 0.05
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = "rgba(255, 255, 255, 0.05)";
ctx.beginPath();
ctx.fillRect(0, 0, width, height);
ctx.fill();
// Set the default mode.
ctx.globalCompositeOperation = 'source-over';

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X