web-dev-qa-db-fra.com

Comment changer l'opacité (alpha, transparence) d'un élément d'un élément de canevas après son dessin?

En utilisant l’élément HTML5 <canvas>, je voudrais charger un fichier image (PNG, JPEG, etc.), le dessiner sur le canevas de manière totalement transparente, puis le faire passer en fondu. J'ai découvert comment charger l’image. et le dessiner à la toile, mais je ne sais pas comment changer son opacité une fois qu'il a été dessiné.

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';
}

Est-ce que quelqu'un peut me diriger dans la bonne direction, comme une propriété à définir ou une fonction à appeler qui changera l'opacité?

185
Joe Lencioni

Je cherche également une réponse à cette question (pour préciser, je veux pouvoir dessiner une image avec une opacité définie par l'utilisateur, telle que la façon dont vous pouvez dessiner des formes avec une opacité) si vous dessinez avec des formes primitives que vous pouvez définir avec le fond et le trait. couleur avec alpha pour définir la transparence. Pour autant que j'en ai conclu à l'heure actuelle, cela ne semble pas affecter le dessin de l'image.

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

J'ai conclu que le réglage de la globalCompositeOperation fonctionne avec des images.

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

Je me demande s’il existe une troisième manière de régler les couleurs afin que nous puissions teinter les images et les rendre facilement transparentes.

EDIT:

Après des recherches approfondies, 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 avec le temps, vous avez besoin d’une sorte de boucle qui modifie la valeur alpha. C’est assez facile. Pour y parvenir, utilisez la fonction setTimeout, recherchez-la pour créer une boucle à partir de vous modifiez l'alpha avec le temps.

292
djdolber

Quelques exemples de code plus simples pour utiliser globalAlpha:

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

Si vous avez besoin de charger img:

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

Remarques:

  • Définissez 'src' en dernier, pour que votre gestionnaire onload soit appelé sur toutes les plates-formes, même si l'image se trouve déjà dans le cache.

  • Modifiez les modifications pour créer des éléments tels que globalAlpha entre save et restore (en fait, utilisez-les beaucoup), afin de ne pas entraver les paramètres importés, en particulier lorsque des éléments de code de dessin sont utilisés. va être appelé à partir d'événements.

110
Ian

Modifier: 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 à portée de 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.

14
james.garriss

Le post est vieux jusqu'à présent, je vais suivre ma suggestion. La suggestion est basée sur la manipulation de pixels dans un contexte canvas 2d. De MDN:

Vous pouvez manipuler directement les données de pixels dans les toiles au niveau octet

Pour manipuler les pixels, nous allons utiliser ici deux fonctions: getImageData et putImageData.

utilisation de la fonction getImageData:

var myImageData = context.getImageData (gauche, haut, largeur, hauteur);

et la syntaxe putImageData:

context.putImageData (myImageData, dx, dy); // dx, dy - x et y décalés sur votre toile

le contexte est le contexte de votre toile 2d

Donc, pour obtenir les valeurs rouge vert bleu et alpha, nous allons procéder comme 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 x offset, y est y offset sur la toile

Nous avons donc un code rendant 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 complet de MDN ici

11
Soul_man

Vous pouvez. Le canevas transparent peut être rapidement estompé en utilisant l'opération composite destination-sortie. Ce n’est pas parfait à 100%, parfois il laisse des traces, mais il peut être modifié en fonction des besoins (c’est-à-dire, utilisez 'source-over' et remplissez-le de couleur blanche avec alpha à 0,13, puis 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';
7
Og2t

Je pense que cela répond mieux à la question, cela change en réalité la valeur alpha de quelque chose qui a déjà été dessiné. Peut-être que cela ne faisait pas partie de l'api quand cette question a été posée.

contexte 2d donné c.

function reduceAlpha(x, y, w, h, dA) {
    var screenData = c.getImageData(x, y, w, h);
    for(let i = 3; i < screenData.data.length; i+=4){
    screenData.data[i] -= dA; //delta-Alpha
    }
    c.putImageData(screenData, x, y );
}
1
Dillon