如何在绘制画布元素后更改元素的不透明度(alpha,透明度)?

Joe*_*oni 190 html5 transparency alpha canvas opacity

使用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';
}
Run Code Online (Sandbox Code Playgroud)

有人请指出我正确的方向,如设置的属性或调用的功能,将改变不透明度?

djd*_*ber 295

我也在寻找这个问题的答案,(澄清一下,我希望能够用用户定义的不透明度绘制图像,例如如何用不透明度绘制形状)如果你用原始形状绘制你可以设置填充和描边用alpha定义透明度的颜色.就我现在所得出的结论而言,这似乎并不影响图像绘制.

//works with shapes but not with images
ctx.fillStyle = "rgba(255, 255, 255, 0.5)";
Run Code Online (Sandbox Code Playgroud)

我已经得出结论,globalCompositeOperation用图像设置作品.

//works with images
ctx.globalCompositeOperation = "lighter";
Run Code Online (Sandbox Code Playgroud)

我想知道是否有某种第三种设置颜色的方式,这样我们就可以着色图像并使它们变得透明.

编辑:

在进一步挖掘后,我得出结论,您可以通过globalAlpha在绘制图像之前设置参数来设置图像的透明度:

//works with images
ctx.globalAlpha = 0.5
Run Code Online (Sandbox Code Playgroud)

如果你想要随着时间的推移实现淡入淡出效果你需要某种类型的循环来改变alpha值,这是相当容易的,实现它的一种方法是setTimeout函数,看起来创建一个循环来改变alpha值时间.

  • 确切地说,它不是具有`globalAlpha`属性的`canvas`元素,而是从画布获得的上下文. (42认同)
  • Ian关于ctx.save()和ctx.restore()的评论可以防止globalAlpha影响画布的其余部分. (8认同)
  • globalAlpha完美运作.是标准的一部分:http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#compositing (7认同)
  • 在我看来,与其控制画布上所画内容的不透明度,不如说更简单,并且仍然可以在绘制图像后(仅一次)控制整个画布本身的不透明度。使用通常的 CSS/样式方法来执行此操作(canvaselement.style.opacity='0.3'; 等)稍后使用 CSS3,您甚至可以完全取消循环,而只让浏览器处理淡入淡出(类似过渡:NNNms不透明度缓入淡出),甚至“动画”淡入淡出。 (2认同)

Ian*_*Ian 110

一些更简单的示例代码用于globalAlpha:

ctx.save();
ctx.globalAlpha = 0.4;
ctx.drawImage(img, x, y);
ctx.restore();
Run Code Online (Sandbox Code Playgroud)

如果您需要img加载:

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

笔记:

  • 设置'src'最后一个,以保证onload在所有平台上调用您的处理程序,即使该图像已经在缓存中.

  • 包含更改为globalAlphaa saverestore(实际上使用它们之间)之类的内容,以确保不会从其他地方删除设置,特别是当要从事件中调用绘图代码时.

  • @Grumpy - 不,`globalAlpha`不会模糊任何东西.它将为所有*后续*绘图设置alpha(它不会改变已经绘制的任何内容),这就是为什么在示例代码中我将它包装在`save`和`restore`中,以限制它适用的内容. (5认同)
  • @Sean - 如果你不确定,你应该检查一下。它一定是一个非常旧的 Chrome,它现在可以在所有平台上运行:https://jsfiddle.net/y0z9h9m7/ (2认同)

jam*_*iss 14

编辑: 标记为"正确"的答案不正确.

这很容易做到.试试这个代码,用你方便的图片交换"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>
Run Code Online (Sandbox Code Playgroud)

关键是globalAlpha属性.

在Win7上使用IE 9,FF 5,Safari 5和Chrome 12进行测试.


Sou*_*man 12

到目前为止,这篇文章很老了,我会按照我的建议去做.建议基于canvas 2d上下文中的像素操作.来自MDN:

您可以在字节级别直接操作画布中的像素数据

要操纵像素,我们在这里使用两个函数 - getImageData和putImageData

getImageData函数用法:

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

和putImageData语法:

context.putImageData(myImageData,dx,dy); //画布上的dx,dy - x和y偏移量

背景是你的画布2D背景

因此,要获得红绿蓝和alpha值,我们将执行以下操作:

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];
Run Code Online (Sandbox Code Playgroud)

其中x是x偏移量,y是画布上的y偏移量

所以我们让代码使图像半透明

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';
Run Code Online (Sandbox Code Playgroud)

你可以让你自己的"着色" -看到完整的MDN文章在这里


Og2*_*g2t 7

您可以.通过使用目标输出全局复合操作,可以快速淡化透明画布.它不是100%完美,有时会留下一些痕迹,但它可以根据需要调整(即使用'source-over'并用白色填充,alpha为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';
Run Code Online (Sandbox Code Playgroud)


小智 6

我认为这最好地回答了这个问题,它实际上改变了已经绘制的东西的 alpha 值。当提出这个问题时,这可能不是 api 的一部分。

给定 2d 上下文c

function reduceAlpha(x, y, w, h, dA) {
    let 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 );
}
Run Code Online (Sandbox Code Playgroud)


小智 5

设置全局 Alpha 绘制具有不透明度的对象,然后设置回正常。

  //////////////////////// circle ///////////////////////
  ctx.globalAlpha = 0.75;
  ctx.beginPath();
  ctx.arc(x1, y1, r1, 0, Math.PI*2);
  ctx.fillStyle = colour;
  ctx.fill();
  ctx.closePath();
  ctx.globalAlpha = 1;
Run Code Online (Sandbox Code Playgroud)