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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2359537/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 02:21:49  来源:igfitidea点击:

How to change the opacity (alpha, transparency) of an element in a canvas element after it has been drawn?

htmlcanvastransparencyopacityalpha

提问by Joe Lencioni

Using the HTML5 <canvas>element, I would like to load an image file (PNG, JPEG, etc.), draw it to the canvas completely transparently, and then fade it in. I have figured out how to load the image and draw it to the canvas, but I don't know how to change its opacity once it as been drawn.

使用 HTML5<canvas>元素,我想加载一个图像文件(PNG、JPEG 等),将它完全透明地绘制到画布上,然后淡入。我已经弄清楚如何加载图像并将其绘制到画布,但我不知道如何在绘制后更改其不透明度。

Here's the code I have so far:

这是我到目前为止的代码:

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

Will somebody please point me in the right direction like a property to set or a function to call that will change the opacity?

有人请指出我正确的方向,例如要设置的属性或要调用的函数会改变不透明度吗?

回答by djdolber

I am also looking for an answer to this question, (to clarify, I want to be able to draw an image with user defined opacity such as how you can draw shapes with opacity) if you draw with primitive shapes you can set fill and stroke color with alpha to define the transparency. As far as I have concluded right now, this does not seem to affect image drawing.

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

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

I have concluded that setting the globalCompositeOperationworks with images.

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

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

I wonder if there is some kind third way of setting color so that we can tint images and make them transparent easily.

我想知道是否有某种第三种设置颜色的方法,以便我们可以轻松地为图像着色并使它们透明。

EDIT:

编辑:

After further digging I have concluded that you can set the transparency of an image by setting the globalAlphaparameter BEFORE you draw the image:

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

//works with images
ctx.globalAlpha = 0.5

If you want to achieve a fading effect over time you need some kind of loop that changes the alpha value, this is fairly easy, one way to achieve it is the setTimeoutfunction, look that up to create a loop from which you alter the alpha over time.

如果你想随着时间的推移实现淡入淡出的效果,你需要某种改变 alpha 值的循环,这很容易,实现它的一种方法是setTimeout函数,查找创建一个循环,从中改变 alpha时间。

回答by Ian

Some simpler example code for using globalAlpha:

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

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

If you need imgto be loaded:

如果需要img加载:

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

Notes:

笔记:

  • Set the 'src'last, to guarantee that your onloadhandler is called on all platforms, even if the image is already in the cache.

  • Wrap changes to stuff like globalAlphabetween a saveand restore(in fact use them lots), to make sure you don't clobber settings from elsewhere, particularly when bits of drawing code are going to be called from events.

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

  • 将更改包装globalAlpha在 asave和之间restore(实际上使用它们很多),以确保您不会破坏其他地方的设置,特别是当将从事件中调用一些绘图代码时。

回答by james.garriss

Edit: The answer marked as "correct" is not correct.

编辑: 标记为“正确”的答案是不正确的。

It's easy to do. Try this code, swapping out "ie.jpg" with whatever picture you have handy:

这很容易做到。试试这个代码,用你手头的任何图片替换“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>

The key is the globalAlpha property.

关键是 globalAlpha 属性。

Tested with IE 9, FF 5, Safari 5, and Chrome 12 on Win7.

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

回答by Soul_man

The post is old so far I'll go with my suggestion. Suggestion is based on pixel manipulation in canvas 2d context. From MDN:

到目前为止,该帖子已经过时了,我会采纳我的建议。建议基于画布 2d 上下文中的像素操作。来自 MDN:

You can directly manipulate pixel data in canvases at the byte level

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

To manipulate pixels we'll use two functions here - getImageData and putImageData

为了操作像素,我们将在这里使用两个函数 - getImageData 和 putImageData

getImageData function usage:

getImageData 函数用法:

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

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

and putImageData syntax:

和 putImageData 语法:

context.putImageData(myImageData, dx, dy); //dx, dy - x and y offset on your canvas

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

Where contextis your canvas 2d context

背景是你的画布2D背景

So to get red green blue and alpha values, we'll do the following:

因此,要获得红绿蓝和 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];

Where xis x offset, yis y offset on canvas

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

So we having code making image half-transparent

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

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

You can make you own "shaders" - see full MDN article here

你可以让你自己的“着色器” -在这里查看完整的 MDN 文章

回答by Og2t

You can. Transparent canvas can be quickly faded by using destination-outglobal composite operation. It's not 100% perfect, sometimes it leaves some traces but it could be tweaked, depending what's needed (i.e. use 'source-over' and fill it with white color with alpha at 0.13, then fade to prepare the canvas).

你可以。使用destination-out全局合成操作可以快速淡化透明画布。它不是 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';

回答by Dillon

I think this answers the question best, it actually changes the alpha value of something that has been drawn already. Maybe this wasn't part of the api when this question was asked.

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

given 2d context c.

给定 2d 上下文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 );
}

回答by cen

If you use jCanvaslibrary you can use opacityproperty when drawing. If you need fade effect on top of that, simply redraw with different values.

如果您使用jCanvas库,您可以在绘图时使用opacity属性。如果您需要除此之外的淡入淡出效果,只需使用不同的值重新绘制即可。

回答by MPG

You can't. It's immediate mode graphics. But you can sort of simulate it by drawing a rectangle over it in the background color with an opacity.

你不能。这是即时模式图形。但是您可以通过在背景颜色中绘制一个矩形而不透明度来模拟它。

If the image is over something other than a constant color, then it gets quite a bit trickier. You should be able to use the pixel manipulation methods in this case. Just save the area before drawing the image, and then blend that back on top with an opacity afterwards.

如果图像的颜色不是恒定的,那么它会变得有点棘手。在这种情况下,您应该能够使用像素操作方法。只需在绘制图像之前保存该区域,然后将其与不透明度混合回顶部。