簡體   English   中英

如何在具有一致不透明度的畫布中繪制?

[英]how do i draw in a canvas with consistent opacity?

我想在我的繪畫程序/應用程序中為畫筆添加不透明度,所以我通過ctx.globalAlpha降低了不透明度,順便說一句,我正在使用路徑進行繪制。 我得到了這樣的東西:

片段(無繪圖功能);

 //context c = document.getElementById('c').getContext("2d"); //set opacity/alpha c.globalAlpha = 0.5 //draw lines c.beginPath(); c.lineWidth = 20; c.lineCap = 'round'; c.moveTo(20,20); c.lineTo(60,20); c.stroke(); c.beginPath(); c.moveTo(60,20); c.lineTo(70,50); c.stroke();
 <canvas id='c'></canvas> <style> canvas { border: 1px solid black; } </style>

這是照片

如您所見,它不是純透明的顏色,您可以看到黑點(不好)。 那么我該如何解決呢?

透明度是一致的,但是這個地方你應用了兩次,所以它會累積。 如果你只在一個路徑有問題,你應該重復調用 moveTo/lineTo 並且只在最后撫摸。

不過我想你想要的不止這些。 解決方案是在屏幕外畫布上繪制。 像這樣初始化:

// your main canvas
var canvas = document.getElementById('c');
var c = canvas.getContext("2d");

// create an offscreen canvas: this canvas is not shown on screen
var offscreenCanvas = document.createElement('canvas');
offscreenCanvas.width = canvas.width;
offscreenCanvas.height = canvas.height;
var oc = offscreenCanvas.getContext("2d");

然后像這樣繪制/更新:

// you are drawing to the offscreen canvas
oc.beginPath();
oc.lineWidth = 20;
oc.lineCap = 'round';
oc.moveTo(20,20);
oc.lineTo(60,20);
oc.stroke();
oc.beginPath();
oc.moveTo(60,20);
oc.lineTo(70,50);
oc.stroke();

// and then copy the offscreen canvas onto your main canvas with opacity
c.globalAlpha = 0.5;
c.drawImage(offscreenCanvas, 0, 0);

當您完成用戶操作時(例如,在中風后或您需要的任何操作后),您可以清除oc並開始新的操作。

這也是將同一圖形的多個實例繪制到一個畫布上的推薦方法:在屏幕外畫布上繪制一次,然后多次復制到主畫布。

更新:由於您要求“具有繪圖功能”,因此我使用另一個屏幕外畫布創建了一個工作繪圖示例來存儲用戶操作之間的狀態:

 var canvas = document.getElementById('c'); var c = canvas.getContext("2d"); // create an offscreen canvas: this canvas is not shown on screen var offscreenCanvas = document.createElement('canvas'); offscreenCanvas.width = canvas.width; offscreenCanvas.height = canvas.height; var oc = offscreenCanvas.getContext("2d"); // create another offscreen "freeze canvas" var freezeCanvas = document.createElement('canvas'); freezeCanvas.width = canvas.width; freezeCanvas.height = canvas.height; var fc = freezeCanvas.getContext("2d"); // for visualisation purposes you can also show these canvases //canvas.parentNode.appendChild(offscreenCanvas); //canvas.parentNode.appendChild(freezeCanvas); var w = 10; var le = null; canvas.addEventListener("mousedown", e => { le = e; sw = w; // at the start of a stroke clear the offscreen canvas oc.clearRect(0, 0, canvas.width, canvas.height); }, false); canvas.addEventListener("mousemove", e => { if (!le) return; // some primitive dynamic stroke width calculation var dx = e.offsetX - le.offsetX; var dy = e.offsetY - le.offsetY; var d = Math.max(1, Math.sqrt(dx*dx+dy*dy)); sw = sw * 0.9 + (w * 4 / d) * 0.1; // add to your stroke image oc.beginPath(); oc.lineWidth = sw; oc.lineCap = 'round'; oc.moveTo(le.offsetX, le.offsetY); oc.lineTo(e.offsetX, e.offsetY); oc.stroke(); le = e; // and then combine the frozen contents with the stroke c.clearRect(0, 0, canvas.width, canvas.height); c.globalAlpha = 1; c.drawImage(freezeCanvas, 0, 0); c.globalAlpha = 0.5; c.drawImage(offscreenCanvas, 0, 0); }, false); canvas.addEventListener("mouseup", e => { le = null; // and freeze the main canvas fc.clearRect(0, 0, canvas.width, canvas.height); fc.drawImage(canvas, 0, 0); }, false);
 <canvas id='c'></canvas> <style>canvas { border: 1px solid black; }</style>

每次移動后不要撫摸,這是一個工作示例: https : //codesandbox.io/s/nameless-shadow-rql9q

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM