Прозрачность постоянна, но в этом месте вы применяете ее дважды, поэтому она накапливается. Если у вас есть проблема только в одном пути, вы должны повторно вызывать 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>