HTML5 canvas globalAlpha不起作用

时间:2015-02-04 12:36:26

标签: javascript html5 canvas

我需要使用透明而不是clearRect方法创建平滑的绘制线我尝试使用:globalAlphastrokeStyle使用rgba,如下所示:

ctx.strokeStyle = "rgba( redChannel, greenChannel, blueChannel, AlphaChannel )";

但两种方法都不起作用。如何在没有clearRect方法的情况下绘制透明线条。虽然我在每张图clearRect之前使用globalAlpha,但我需要在没有它的情况下工作。

我的代码示例:



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;
};
&#13;
canvas { border: 1px solid #ccc }
&#13;
<canvas id="c" width="500" height="300"></canvas>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:2)

每次鼠标移动时,您都在重绘整个路径,因此即使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>

答案 1 :(得分:1)

选项3 :使用两个画布,在主画面上 - 仅在鼠标释放时绘制,在第二个预览画布上,只显示进度,因此即使在鼠标移动时也可以看到绘图。另外,对于预览画布,我们需要做一些技巧,比如干净的前一个线段,所以一切看起来都不错。

//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>