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
How to change the opacity (alpha, transparency) of an element in a canvas element after it has been drawn?
提问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 globalCompositeOperation
works 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 globalAlpha
parameter 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 setTimeout
function, 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 img
to 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 youronload
handler is called on all platforms, even if the image is already in the cache.Wrap changes to stuff like
globalAlpha
between asave
andrestore
(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
回答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.
如果图像的颜色不是恒定的,那么它会变得有点棘手。在这种情况下,您应该能够使用像素操作方法。只需在绘制图像之前保存该区域,然后将其与不透明度混合回顶部。