我在画布上绘制半透明颜色(例如rgba(255,0,0,0.5)
)。当我再次绘制相同的区域时,透明度值似乎相加,导致不透明的颜色。有没有办法保持源的透明度值(我用来绘制半透明颜色)?如何在HTML画布上绘制重叠内容时重置透明度?
回答
使用alpha = 1
绘制到屏幕外画布。然后,将屏幕画布呈现在显示画布上,并将ctx.globalAlpha
设置为您希望的值。这样,你可以绘制,直到太阳下山,而不需要添加任何东西到阿尔法。如果需要绘制,在绘制后也很容易。
附记
如果已经包括在图像中的其他内容,你将不得不继续其在另一层,以及因为这种方法依赖屏幕上的画布上被复位到期望的起始状态为每个更新。在这段代码中,这只是一个clearRect
调用。但也可以用另一个现有图层或其组合替换。
浏览器可以很容易地处理很多屏幕画布,我刚刚完成了一个有60个全屏幕帆布堆叠在一起的作业(注意你的GPU需要RAM来存放图像或它太慢)和Chrome甚至没有眨眼。 Firefox和IE的功能一样。
UPDATE
我添加了一个片断来证明我的意思。底部有关代码的评论详情。只是一个简单的绘图界面。
// get canvas set up mouse and do the other things
var canvas = document.getElementById("canV");
var ctx = canvas.getContext("2d");
var w = canvas.width;
var h = canvas.height;
var mouse = {
x:0,
y:0,
buttonLastRaw:0, // user modified value
buttonRaw:0,
over:false,
};
function mouseMove(event){
mouse.x = event.offsetX; mouse.y = event.offsetY;
if(mouse.x === undefined){ mouse.x = event.clientX; mouse.y = event.clientY;}
if(event.type === "mousedown"){ mouse.buttonRaw = 1;
}else if(event.type === "mouseup"){mouse.buttonRaw = 0;
}else if(event.type === "mouseout"){ mouse.buttonRaw = 0; mouse.over = false;
}else if(event.type === "mouseover"){ mouse.over = true; }
event.preventDefault();
}
canvas.addEventListener('mousemove',mouseMove);
canvas.addEventListener('mousedown',mouseMove);
canvas.addEventListener('mouseup' ,mouseMove);
canvas.addEventListener('mouseout' ,mouseMove);
canvas.addEventListener('mouseover' ,mouseMove);
canvas.addEventListener("contextmenu", function(e){ canvas.preventDefault();}, false);
// create off screen layer that we will draw to
var layer1 = document.createElement("canvas");
layer1.width = w; // same size as the onscreen canvas
layer1.height = h;
layer1.ctx = layer1.getContext("2d");
// set up drawing settings
layer1.ctx.lineCap = "round";
layer1.ctx.lineJoin = "round";
layer1.ctx.lineWidth = 16;
layer1.ctx.globalAlpha = 1; // draw to this layer with alpha set to 1;
// set up onscreen canvas
ctx.globalAlpha = 1;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.font = "24px Arial black";
var instructions = true;
// colours to show that different layer are overwriting each other
var colours = "#F00,#FF0,#0F0,#0FF,#00F,#F0F".split(",");
var currentCol = 0;
// update on animation frame
function update(){
ctx.clearRect(0,0,w,h); // clear onscreen
var c = layer1.ctx; // short cut to the later1 context
if(mouse.buttonRaw){ // if mouse down
if(mouse.lastx === undefined){ // is this start of drawing stroke
mouse.lastx = mouse.x; // set up drawing stroke
mouse.lasty = mouse.y;
\t c.strokeStyle = colours[currentCol % colours.length];
currentCol += 1;
instructions = false; // tuen of the instructions as they have worked it out
ctx.globalAlpha = 0.6; // should do this near layering but lasy
}
// draw the dragged stroke to the offscreen layer
c.beginPath();
c.moveTo(mouse.lastx,mouse.lasty);
c.lineTo(mouse.x,mouse.y);
c.stroke();
mouse.lastx = mouse.x;
mouse.lasty = mouse.y;
}else{ // if the mouse button up show drawing brush and instructions if
// nothing has happened yet
mouse.lastx = undefined; // using this as a semaphore for drag start
ctx.fillStyle = colours[currentCol%colours.length];
ctx.globalAlpha = 0.6; // the brush will compound the alpha
// this can be avoided by drawing it onto
// the offscreen layer, but you will need
// another layer or some temp store to
// protect the offscreen layer. Again I am
// to lazy to implement that right now.
ctx.beginPath();
ctx.arc(mouse.x,mouse.y,8,0,Math.PI*2);
ctx.fill();
if(instructions){ // show instructions if needed
ctx.fillStyle = "blue";
ctx.globalAlpha = 1;
ctx.fillText("Click drag mouse to draw",250,60);
}
}
// draw the offscreen layer onto the onscreen canvas at the alpha wanted
ctx.drawImage(layer1,0,0);
requestAnimationFrame(update); // do it all again.
}
mouse.lastx; // needed to draw lines.
mouse.lasty;
update()
body { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAlUlEQVRYR+2WsQ0EIQwEbXpAopbrAZESUhQ1AAkBXVEDAb6jBRP8B0s+yJpklnvvstYizRMRyjmTtVaD096buNYqzjnVB3NOaq3RGEPFhxBwAAzAAAzAAAz8gYFSijCzqmYH+ngyxqj4k3N+nkduep5Sops9wV+T5abnMUa62RM4AAZgAAZgAAZ+b8B7Lzc9PzW82RMvg0g+JLdy9xIAAAAASUVORK5CYII=');
background-size: 32px 32px;
background-repeat: repeat;
}
.canC { width:500px; height:600px;}
<canvas class="canC" id="canV" width=500 height=600></canvas>
听起来很有希望..但只有所有的alpha都相同。 – markE
60个同步全屏效果图 - 哇!只是好奇...什么是需要这么多覆盖的应用程序? – markE
某些显微镜图像的非常深的(层)视差图像视图。 – Blindman67
- 1. 在画布上绘制位图重叠
- 2. 是否可以在WebGL内容上绘制透明画布?
- 3. 在画布中,如何绘制2个半透明重叠圆圈
- 4. 在画布上重新绘制透明背景
- 5. 在画布上绘制透明形状
- 6. UITabBar不透明和重叠内容
- 7. 在UIView上透明重绘
- 8. 如何在透明窗口中绘制透明的DirectX内容?
- 9. AlphaComposite带重绘透明度重叠为黑色
- 10. 如何在Firefox的画布上绘制透明的PNG?
- 11. 更改不透明度时重绘窗口不透明度
- 12. 在透明窗口上绘制非透明内容
- 13. C#NET - 在不透明度设置的窗体上绘制不透明画笔
- 14. 如何在画布上或布局上放置重叠图像
- 15. 重叠可绘制动画
- 16. 透明度问题重叠PictureBox在C#
- 17. HTML 5个画布上重叠
- 18. 如何在重叠时颜色变得更强的地方绘制透明线?
- 19. android如何绘制半透明的画布上的位图
- 20. Javascript HTML5画布绘制透明圆圈
- 21. 堆叠画布删除默认的透明度HTML
- 22. 使用透明背景时Android Webview内容重叠
- 23. 页脚在低分辨率画布上重叠内容
- 24. 如何在画布上绘制画布
- 25. 重叠绘制重叠的半透明线条而没有变暗
- 26. html5画布绘制多重图像和重叠
- 27. Admob重叠布局内容
- 28. 重叠视图的透明度
- 29. 重叠项目的Flash透明度
- 30. 使用透明度重叠网格
'ctx.clearRect(0,0,canvas.width,canvas.height)'然后重绘? – Kaiido
@Kaiido。不,**这是一个比'clearRect'问题更有趣的问题**! ;-)他们想绘制半透明填充,然后部分覆盖另一个半透明填充 - 但重叠区域应该只有第二个填充(不是2个alpha填充的混合)。经过短暂的思考,我想不出合成解决方案,因为合成尊重alpha。它可能归结为'.getImageData'解决方案。 – markE
@markE,但它对我来说似乎是违反直觉的:如果我用半透明颜色绘制多次,它变得越来越不透明似乎是正常的。如果OP要始终使用相同的字母,可能会考虑'globalAlpha'属性,或仅在将要重绘的像素上使用'clearRect()'。但不清楚'rgba(0,255,0,0.5)'+'rgba(0,0,255,0.5)'应该返回什么。 'rgba(0,107,147,0.5)'就好像两个alpha颜色都是'.25'一样? – Kaiido