我在畫布上繪製半透明顏色(例如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