it-swarm.com.de

Wie ändere ich die Deckkraft (Alpha, Transparenz) eines Elements in einem Canvas-Element, nachdem es gezeichnet wurde?

HTML5 verwenden <canvas> Element, ich möchte eine Bilddatei (PNG, JPEG usw.) laden, diese vollständig transparent auf die Leinwand zeichnen und dann einblenden. Ich habe herausgefunden, wie das Bild geladen und auf die Leinwand gezeichnet wird , aber ich weiß nicht, wie ich die Deckkraft ändern soll, wenn sie einmal gezeichnet ist.

Hier ist der Code, den ich bisher habe:

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

Wird jemand mich bitte in die richtige Richtung weisen, wie eine Eigenschaft, die festgelegt werden soll, oder eine Funktion, die aufgerufen werden soll, um die Deckkraft zu ändern?

185
Joe Lencioni

Ich suche auch nach einer Antwort auf diese Frage (um dies zu verdeutlichen, möchte ich in der Lage sein, ein Bild mit benutzerdefinierter Deckkraft zu zeichnen, z. B. wie Sie Formen mit Deckkraft zeichnen können), wenn Sie mit primitiven Formen zeichnen, können Sie Füllung und Kontur einstellen Farbe mit Alpha, um die Transparenz zu definieren. Soweit ich jetzt zu dem Schluss gekommen bin, scheint dies keinen Einfluss auf das Zeichnen von Bildern zu haben.

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

Ich bin zu dem Schluss gekommen, dass das Setzen von globalCompositeOperation mit Bildern funktioniert.

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

Ich frage mich, ob es eine dritte Möglichkeit gibt, die Farbe so einzustellen, dass wir Bilder leicht tönen und transparent machen können.

EDIT:

Nach weiteren Grabungen bin ich zu dem Schluss gekommen, dass Sie die Transparenz eines Bildes einstellen können, indem Sie den Parameter globalAlpha einstellen, BEVOR Sie das Bild zeichnen:

//works with images
ctx.globalAlpha = 0.5

Wenn Sie mit der Zeit einen Überblendungseffekt erzielen möchten, benötigen Sie eine Art Schleife, die den Alpha-Wert ändert. Dies ist recht einfach. Eine Möglichkeit, dies zu erreichen, ist die Funktion setTimeout. Suchen Sie danach, um eine Schleife zu erstellen was Sie das Alpha im Laufe der Zeit ändern.

292
djdolber

Einfacherer Beispielcode für die Verwendung von globalAlpha:

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

Wenn Sie img laden müssen:

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

Anmerkungen:

  • Setze das 'src' last, um sicherzustellen, dass Ihr onload -Handler auf allen Plattformen aufgerufen wird, auch wenn sich das Image bereits im Cache befindet.

  • Wickeln Sie Änderungen in Dinge wie globalAlpha zwischen save und restore um (verwenden Sie diese tatsächlich in großen Mengen), um sicherzustellen, dass Sie keine Einstellungen von anderen Stellen aus löschen, insbesondere wenn Teile von Zeichencode wird von Ereignissen aufgerufen.

110
Ian

Bearbeiten: Die als "richtig" gekennzeichnete Antwort ist nicht richtig.

Es ist leicht zu machen. Probieren Sie diesen Code aus und tauschen Sie "ie.jpg" mit dem Bild aus, das Sie zur Hand haben:

<!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>

Der Schlüssel ist die Eigenschaft globalAlpha.

Getestet mit IE 9, FF 5, Safari 5 und Chrome 12 unter Win7.

14
james.garriss

Der Beitrag ist soweit alt ich gehe mit meinem Vorschlag um. Der Vorschlag basiert auf der Pixelmanipulation im 2D-Canvas-Kontext. Vom MDN:

Sie können Pixeldaten in Leinwänden auf Byte-Ebene direkt bearbeiten

Um Pixel zu manipulieren, verwenden wir hier zwei Funktionen - getImageData und putImageData

verwendung der Funktion getImageData:

var myImageData = context.getImageData (links, oben, Breite, Höhe);

und putImageData Syntax:

context.putImageData (myImageData, dx, dy); // dx, dy - x und y Versatz auf deiner Leinwand

Wo Kontext ist Ihr Canvas 2d Kontext

Um also Rot, Grün, Blau und Alpha-Werte zu erhalten, gehen wir wie folgt vor:

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];

Wobei x x-Versatz ist, y y-Versatz auf der Leinwand

Wir haben also Code, der das Bild halbtransparent macht

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

Sie können eigene "Shader" erstellen - siehe vollständigen MDN-Artikel hier

11
Soul_man

Du kannst. Transparente Zeichenflächen können schnell ausgeblendet werden, indem Ziel-Aus globaler Zusammensetzungsvorgang verwendet wird. Es ist nicht 100% perfekt, manchmal hinterlässt es einige Spuren, aber es könnte je nach Bedarf optimiert werden (d. H. Verwenden Sie 'Source-Over' und füllen Sie es mit weißer Farbe mit Alpha bei 0,13, und verblassen Sie dann, um die Leinwand vorzubereiten).

// 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

Ich denke, dies beantwortet die Frage am besten. Es ändert tatsächlich den Alpha-Wert von etwas, das bereits gezeichnet wurde. Vielleicht war das nicht Teil der API, als diese Frage gestellt wurde.

gegebener 2d Kontext 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