HTML5 canvas globalAlpha 不工作
HTML5 canvas globalAlpha not working
我需要在没有 clearRect
的情况下创建平滑的透明绘图线 我尝试使用:globalAlpha
和 strokeStyle
与 rgba 像这样:
ctx.strokeStyle = "rgba( redChannel, greenChannel, blueChannel,
AlphaChannel
)";
但这两种方法都不起作用。我如何在没有 clearRect
方法的情况下绘制透明线。虽然我在每张图 globalAlpha
工作之前使用 clearRect
,但我需要在没有它的情况下工作。
我的代码示例:
var el = document.getElementById('c');
var ctx = el.getContext('2d');
ctx.lineWidth = 10;
ctx.lineJoin = ctx.lineCap = 'round';
ctx.globalAlpha = "0.2";
//ctx.strokeStyle = "rgba(255, 0, 0, 150)";
ctx.strokeStyle = "red";
var isDrawing, points = [ ];
el.onmousedown = function(e) {
isDrawing = true;
points.push({ x: e.clientX, y: e.clientY });
};
el.onmousemove = function(e) {
if (!isDrawing) return;
//ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
points.push({ x: e.clientX, y: e.clientY });
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
for (var i = 1; i < points.length; i++) {
ctx.lineTo(points[i].x, points[i].y);
}
ctx.stroke();
ctx.closePath();
};
el.onmouseup = function() {
isDrawing = false;
points.length = 0;
};
canvas { border: 1px solid #ccc }
<canvas id="c" width="500" height="300"></canvas>
每次鼠标移动时都会重新绘制整个路径,因此即使 globalAlpha
值设置为 0.2,分层效果也会使线条看起来很实。
选项 1:
使用 clearRect
清除路径 onmousemove
然后重绘;
选项 2:
只绘制路径的最后一段,但重叠是可见的:
var el = document.getElementById('c');
var ctx = el.getContext('2d');
ctx.lineWidth = 10;
ctx.lineJoin = ctx.lineCap = 'round';
ctx.globalAlpha = "0.2";
//ctx.strokeStyle = "rgba(255, 0, 0, 150)";
ctx.strokeStyle = "red";
var isDrawing, points = [ ];
el.onmousedown = function(e) {
isDrawing = true;
points.push({ x: e.clientX, y: e.clientY });
};
el.onmousemove = function(e) {
if (!isDrawing) return;
//ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
points.push({ x: e.clientX, y: e.clientY });
ctx.beginPath();
//draw just the last segment
if(points.length>1) {
ctx.moveTo(points[points.length-2].x, points[points.length-2].y);
ctx.lineTo(points[points.length-1].x, points[points.length-1].y);
}
ctx.stroke();
ctx.closePath();
};
el.onmouseup = function() {
isDrawing = false;
points.length = 0;
};
canvas { border: 1px solid #ccc }
<canvas id="c" width="500" height="300"></canvas>
选项 3:
设置 canvas
元素的不透明度
var el = document.getElementById('c');
var ctx = el.getContext('2d');
ctx.lineWidth = 10;
ctx.lineJoin = ctx.lineCap = 'round';
//ctx.globalAlpha = "0.2";
//ctx.strokeStyle = "rgba(255, 0, 0, 150)";
ctx.strokeStyle = "red";
var isDrawing, points = [ ];
el.onmousedown = function(e) {
isDrawing = true;
points.push({ x: e.clientX, y: e.clientY });
};
el.onmousemove = function(e) {
if (!isDrawing) return;
//ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
points.push({ x: e.clientX, y: e.clientY });
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
for (var i = 1; i < points.length; i++) {
ctx.lineTo(points[i].x, points[i].y);
}
ctx.stroke();
ctx.closePath();
};
el.onmouseup = function() {
isDrawing = false;
points.length = 0;
};
canvas { border: 1px solid #ccc; opacity:0.2; }
<canvas id="c" width="500" height="300"></canvas>
选项 3:使用两个 canvas,在 main 上 - 仅在鼠标释放时绘制,在第二个预览 canvas 上,只显示进度,所以即使在鼠标移动时绘图也将可见。同样对于预览 canvas 我们需要做一些技巧,比如清理之前的线段,所以一切看起来都不错。
//main canvas
var el = document.getElementById('c');
var ctx = el.getContext('2d');
//preview
var el2 = document.getElementById('c2');
var ctx2 = el2.getContext('2d');
ctx.lineWidth = 10;
ctx2.lineWidth = 10;
ctx.lineJoin = ctx.lineCap = 'round';
ctx2.lineJoin = ctx2.lineCap = 'round';
ctx.strokeStyle = "rgba(255, 0, 0, 0.5)";
ctx2.strokeStyle = "rgba(255, 0, 0, 0.5)";
var isDrawing, points = [ ];
el2.onmousedown = function(e) {
isDrawing = true;
points.push({ x: e.clientX, y: e.clientY });
ctx.beginPath();
ctx2.beginPath();
};
el2.onmousemove = function(e) {
if (!isDrawing) return;
points.push({ x: e.clientX, y: e.clientY });
//draw just the last segment
if(points.length>1) {
ctx.moveTo(points[points.length-2].x, points[points.length-2].y);
ctx.lineTo(points[points.length-1].x, points[points.length-1].y);
//start preview
ctx2.beginPath();
//clean from last line
ctx2.globalCompositeOperation = "destination-out";
ctx2.strokeStyle = "rgba(255, 0, 0, 1)";
ctx2.moveTo(points[points.length-2].x, points[points.length-2].y);
ctx2.lineTo(points[points.length-1].x, points[points.length-1].y);
ctx2.stroke();
//rest
ctx2.strokeStyle = "rgba(255, 0, 0, 0.5)";
ctx2.globalCompositeOperation = "source-over";
//draw new line segment
ctx2.moveTo(points[points.length-2].x, points[points.length-2].y);
ctx2.lineTo(points[points.length-1].x, points[points.length-1].y);
ctx2.stroke();
}
};
el2.onmouseup = function() {
ctx2.clearRect(0, 0, ctx2.canvas.width, ctx2.canvas.height);
ctx.stroke();
isDrawing = false;
points.length = 0;
};
canvas {
border: 1px solid #ccc;
position:absolute;
}
<canvas id="c" width="500" height="200"></canvas>
<canvas id="c2" width="500" height="200"></canvas>
我需要在没有 clearRect
的情况下创建平滑的透明绘图线 我尝试使用:globalAlpha
和 strokeStyle
与 rgba 像这样:
ctx.strokeStyle = "rgba( redChannel, greenChannel, blueChannel,
AlphaChannel
)";
但这两种方法都不起作用。我如何在没有 clearRect
方法的情况下绘制透明线。虽然我在每张图 globalAlpha
工作之前使用 clearRect
,但我需要在没有它的情况下工作。
我的代码示例:
var el = document.getElementById('c');
var ctx = el.getContext('2d');
ctx.lineWidth = 10;
ctx.lineJoin = ctx.lineCap = 'round';
ctx.globalAlpha = "0.2";
//ctx.strokeStyle = "rgba(255, 0, 0, 150)";
ctx.strokeStyle = "red";
var isDrawing, points = [ ];
el.onmousedown = function(e) {
isDrawing = true;
points.push({ x: e.clientX, y: e.clientY });
};
el.onmousemove = function(e) {
if (!isDrawing) return;
//ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
points.push({ x: e.clientX, y: e.clientY });
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
for (var i = 1; i < points.length; i++) {
ctx.lineTo(points[i].x, points[i].y);
}
ctx.stroke();
ctx.closePath();
};
el.onmouseup = function() {
isDrawing = false;
points.length = 0;
};
canvas { border: 1px solid #ccc }
<canvas id="c" width="500" height="300"></canvas>
每次鼠标移动时都会重新绘制整个路径,因此即使 globalAlpha
值设置为 0.2,分层效果也会使线条看起来很实。
选项 1:
使用 clearRect
清除路径 onmousemove
然后重绘;
选项 2: 只绘制路径的最后一段,但重叠是可见的:
var el = document.getElementById('c');
var ctx = el.getContext('2d');
ctx.lineWidth = 10;
ctx.lineJoin = ctx.lineCap = 'round';
ctx.globalAlpha = "0.2";
//ctx.strokeStyle = "rgba(255, 0, 0, 150)";
ctx.strokeStyle = "red";
var isDrawing, points = [ ];
el.onmousedown = function(e) {
isDrawing = true;
points.push({ x: e.clientX, y: e.clientY });
};
el.onmousemove = function(e) {
if (!isDrawing) return;
//ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
points.push({ x: e.clientX, y: e.clientY });
ctx.beginPath();
//draw just the last segment
if(points.length>1) {
ctx.moveTo(points[points.length-2].x, points[points.length-2].y);
ctx.lineTo(points[points.length-1].x, points[points.length-1].y);
}
ctx.stroke();
ctx.closePath();
};
el.onmouseup = function() {
isDrawing = false;
points.length = 0;
};
canvas { border: 1px solid #ccc }
<canvas id="c" width="500" height="300"></canvas>
选项 3:
设置 canvas
元素的不透明度
var el = document.getElementById('c');
var ctx = el.getContext('2d');
ctx.lineWidth = 10;
ctx.lineJoin = ctx.lineCap = 'round';
//ctx.globalAlpha = "0.2";
//ctx.strokeStyle = "rgba(255, 0, 0, 150)";
ctx.strokeStyle = "red";
var isDrawing, points = [ ];
el.onmousedown = function(e) {
isDrawing = true;
points.push({ x: e.clientX, y: e.clientY });
};
el.onmousemove = function(e) {
if (!isDrawing) return;
//ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
points.push({ x: e.clientX, y: e.clientY });
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
for (var i = 1; i < points.length; i++) {
ctx.lineTo(points[i].x, points[i].y);
}
ctx.stroke();
ctx.closePath();
};
el.onmouseup = function() {
isDrawing = false;
points.length = 0;
};
canvas { border: 1px solid #ccc; opacity:0.2; }
<canvas id="c" width="500" height="300"></canvas>
选项 3:使用两个 canvas,在 main 上 - 仅在鼠标释放时绘制,在第二个预览 canvas 上,只显示进度,所以即使在鼠标移动时绘图也将可见。同样对于预览 canvas 我们需要做一些技巧,比如清理之前的线段,所以一切看起来都不错。
//main canvas
var el = document.getElementById('c');
var ctx = el.getContext('2d');
//preview
var el2 = document.getElementById('c2');
var ctx2 = el2.getContext('2d');
ctx.lineWidth = 10;
ctx2.lineWidth = 10;
ctx.lineJoin = ctx.lineCap = 'round';
ctx2.lineJoin = ctx2.lineCap = 'round';
ctx.strokeStyle = "rgba(255, 0, 0, 0.5)";
ctx2.strokeStyle = "rgba(255, 0, 0, 0.5)";
var isDrawing, points = [ ];
el2.onmousedown = function(e) {
isDrawing = true;
points.push({ x: e.clientX, y: e.clientY });
ctx.beginPath();
ctx2.beginPath();
};
el2.onmousemove = function(e) {
if (!isDrawing) return;
points.push({ x: e.clientX, y: e.clientY });
//draw just the last segment
if(points.length>1) {
ctx.moveTo(points[points.length-2].x, points[points.length-2].y);
ctx.lineTo(points[points.length-1].x, points[points.length-1].y);
//start preview
ctx2.beginPath();
//clean from last line
ctx2.globalCompositeOperation = "destination-out";
ctx2.strokeStyle = "rgba(255, 0, 0, 1)";
ctx2.moveTo(points[points.length-2].x, points[points.length-2].y);
ctx2.lineTo(points[points.length-1].x, points[points.length-1].y);
ctx2.stroke();
//rest
ctx2.strokeStyle = "rgba(255, 0, 0, 0.5)";
ctx2.globalCompositeOperation = "source-over";
//draw new line segment
ctx2.moveTo(points[points.length-2].x, points[points.length-2].y);
ctx2.lineTo(points[points.length-1].x, points[points.length-1].y);
ctx2.stroke();
}
};
el2.onmouseup = function() {
ctx2.clearRect(0, 0, ctx2.canvas.width, ctx2.canvas.height);
ctx.stroke();
isDrawing = false;
points.length = 0;
};
canvas {
border: 1px solid #ccc;
position:absolute;
}
<canvas id="c" width="500" height="200"></canvas>
<canvas id="c2" width="500" height="200"></canvas>