web-dev-qa-db-ja.com

描画後にキャンバス要素内の要素の不透明度(アルファ、透明度)を変更する方法

HTML5の<canvas>要素を使用して、画像ファイル(PNG、JPEGなど)を読み込み、それをキャンバスに完全に透過的に描画してからフェードインします。画像の読み込み方法と描画方法を考え出しました。キャンバス、しかし私はそれが描かれたように一度不透明度を変える方法を知りません。

これが私がこれまでに持っているコードです:

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

プロパティを設定したり、それを呼び出して不透明度を変更する機能のように、正しい方向を向いている人がいますか。

180
Joe Lencioni

原始的な形で描くのであれば、私はこの質問に対する答えも探しています。透明度を定義するためにアルファ色で色付けします。私が今結論した限りでは、これは画像描画には影響しないようです。

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

globalCompositeOperationの設定は画像でも機能すると私は結論しました。

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

画像を色付けして簡単に透明にできるように、色を設定するためのある種の第3の方法があるのだろうか。

編集:

さらに掘り下げた後、画像を描画する前にglobalAlphaパラメータを設定することで、画像の透明度を設定できると結論づけました。

//works with images
ctx.globalAlpha = 0.5

時間の経過とともにフェード効果を達成したい場合は、アルファ値を変更するある種のループが必要です。これを達成する1つの方法は、setTimeout関数です。時間とともに。

283
djdolber

globalAlphaを使用するための簡単なコード例

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

ロードするのにimgが必要な場合:

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

ノート:

  • イメージが既にキャッシュにある場合でも、すべてのプラットフォームでonloadハンドラーが確実に呼び出されるように、'src'を最後に設定します。

  • globalAlphasaveの間にrestoreのようなものへの変更をラップし(実際にはたくさん使用します)、特に描画コードの一部がイベントから呼び出されるような場合は、他の場所から設定を削除しないようにします。

107
Ian

編集する 「正しい」とマークされた答えは正しくありません。

簡単です。このコードを試してみて、便利な写真を使って "ie.jpg"を交換してください。

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

重要なのはglobalAlphaプロパティです。

Win7上のIE 9、FF 5、Safari 5、およびChrome 12でテスト済み。

14
james.garriss

投稿はこれまでのところ古く、私は私の提案を持って行きます。提案はキャンバス2Dコンテキストでのピクセル操作に基づいています。 MDNから:

キャンバス内のピクセルデータをバイトレベルで直接操作できます。

ピクセルを操作するために、ここでは2つの関数 - getImageDataとputImageDataを使います。

getImageData関数の使い方:

var myImageData = context.getImageData(左、上、幅、高さ);

そしてputImageDataの構文:

context.putImageData(myImageData、dx、dy); // dx、dy - キャンバス上のxとyのオフセット

ここでcontextはあなたのキャンバス2Dコンテキストです

それで、赤、緑、青の値とアルファ値を得るために、次のようにします。

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がx offset、yがy offsetです。

そのため、画像を半透明にするコードがあります。

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

あなたはあなた自身の "シェーダ"を作ることができます - MDNの全記事を見てください ここ

11
Soul_man

あなたはできる。透明なキャンバスは、destination-outグローバル複合操作を使用してすばやく色あせすることができます。 100%完璧ではありません、時々それはいくらかの跡を残します、しかし必要とされるものに応じてそれは微調整されることができました(すなわち 'source-over'を使って0.13のアルファで白い色で塗りつぶし、そしてキャンバスを準備するためにフェード).

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

私はこれが質問に最もよく答えると思います、それは実際にはすでに描かれているもののアルファ値を変えます。この質問がされたとき、多分これはapiの一部ではありませんでした。

与えられた2次元コンテキスト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