javascript 是否可以使用画布制作渐变透明/图层蒙版图像?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3320417/
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
Is it possible to make a gradient-transparent/layer masking image using canvas?
提问by mjrevel
I've been following the lessons about transparency and gradients on the Mozilla site: https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Applying_styles_and_colorsbut I have not been able to figure this one out.
我一直在关注 Mozilla 网站上关于透明度和渐变的课程:https: //developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Applying_styles_and_colors但我一直无法弄清楚这一点一出。
I know I can achieve these effects with a png image; however, in the program I am working on the gradient will change constantly according to where the image is moved.
我知道我可以用 png 图像实现这些效果;然而,在我正在处理的程序中,渐变将根据图像移动的位置不断变化。
Here's an example of the effect I'm looking for. http://home.insightbb.com/~epyonxl1/gradientex.jpg
这是我正在寻找的效果示例。 http://home.insightbb.com/~epyonxl1/gradientex.jpg
采纳答案by Castrohenge
I've aded some code here http://code.google.com/p/canvasimagegradient/that adds a drawImageGradientfunction to the CanvasRenderingContext2D. You can draw an image with a linear or radial gradient. It doesn't work in IE, even with excanvas, due to the lack of getImageData/putImageData support.
我在这里添加了一些代码http://code.google.com/p/canvasimagegradient/将drawImageGradient函数添加到 CanvasRenderingContext2D。您可以绘制具有线性或径向渐变的图像。由于缺乏 getImageData/putImageData 支持,它在 IE 中不起作用,即使使用 excanvas。
The following code for example will draw an image with a radial gradient (context retrieve and image load not shown):
例如,以下代码将绘制具有径向渐变的图像(未显示上下文检索和图像加载):
var radGrad = ctx.createRadialGradient(
img.width / 2, img.height / 2, 10,
img.width / 2, img.height / 2, img.width/2);
radGrad.addColorStop(0, "transparent");
radGrad.addColorStop(1, "#000");
ctx.drawImageGradient(img, 112.5, 130, radGrad);
The code works as follows:
该代码的工作原理如下:
- Create a canvas element dynamically and draw the image on it.
- Retrieve the imageData for this new canvas.
- Retrieve the imageData for the location on the canvas you want to draw the image on to.
- Iterate through the destination imageData and update each pixel adding together a percentage (derived from the gradient transparency value) of the image and destination pixel values.
- Finally put the updated image data back onto the destination canvas.
- 动态创建一个画布元素并在其上绘制图像。
- 检索此新画布的 imageData。
- 检索要在其上绘制图像的画布上位置的 imageData。
- 迭代目标 imageData 并更新每个像素,将图像和目标像素值的百分比(源自渐变透明度值)相加。
- 最后将更新后的图像数据放回目标画布上。
Obviously performance is an issue as images get larger. The image on http://code.google.com/p/canvasimagegradient/it takes about 6-10ms to draw. A 1024x768 image takes about 100ms-250ms to draw. Still usable though as long as you're not animating.
显然,随着图像变大,性能是一个问题。http://code.google.com/p/canvasimagegradient/上的图像绘制大约需要 6-10 毫秒。绘制 1024x768 图像大约需要 100ms-250ms。只要您不制作动画,仍然可以使用。
回答by Tommyka
Its possible to use context.globalCompositeOperation to make the the mask
可以使用 context.globalCompositeOperation 来制作掩码
context.drawImage(img, 0, 0, img.width, img.height, 0,0, img.width, img.height);
context.globalCompositeOperation = "destination-out";
gradient = context.createLinearGradient(0, 0, 0, img.height);
gradient.addColorStop(0, "rgba(255, 255, 255, 0.5)");
gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)");
context.fillStyle = gradient;
context.fillRect(0, 0, img.width, img.height);
This do not do per pixel manipulation and should be faster
这不会按像素操作,应该更快
回答by Alnitak
To correctly merge two images using a transparency mask it's first necessary to take one of the two images and put it into an off screencanvas, and add the desired transparency mask using context.globalCompositeOperation = destination-outper @Tommyka's answer
要使用透明蒙版正确合并两个图像,首先需要取两个图像之一并将其放入屏幕外画布,然后使用context.globalCompositeOperation = destination-out@Tommyka 的回答添加所需的透明蒙版
var offscreen = document.createElement('canvas'); // detached from DOM
var context = offscreen.getContext('2d');
context.drawImage(image1, 0, 0, image1.width, image1.height);
var gradient = context.createLinearGradient(0, 0, 0, img.height);
gradient.addColorStop(0, "rgba(255, 255, 255, 0.5)");
gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)");
context.globalCompositeOperation = "destination-out";
context.fillStyle = gradient;
context.fillRect(0, 0, image1.width, image1.height);
Then, to actually merge the two images you then need to draw the other image into another canvas, and then simply draw the alpha-composited offscreen canvas on top of that:
然后,要实际合并这两个图像,您需要将另一个图像绘制到另一个画布中,然后简单地在其上绘制 alpha 合成的屏幕外画布:
var onscreen = document.getElementById('mycanvas');
var context2 = onscreen.getContext('2d');
context2.drawImage(image2, 0, 0, image2.width, image2.height);
context2.drawImage(offscreen, 0, 0, onscreen.width, onscreen.height);
回答by qw3n
If you need to make an image transparent set the ctx.globalAlphato whatever you need (1, no transparency, is default). Then reset it after you draw your image. This URL probably will help as well https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Compositing.
如果您需要使图像透明,请将 设置ctx.globalAlpha为您需要的任何内容(默认为 1,不透明)。然后在绘制图像后重置它。这个 URL 可能也会有所帮助https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Compositing。

