如何使用globalCompositeOperation ='destination-out'擦除画布中的笔触?

时间:2018-08-13 21:57:28

标签: javascript html html5 canvas html5-canvas

我正在尝试使用Canvas 2D API的CanvasRenderingContext2D.globalCompositeOperation属性来擦除画布中的笔画,但是它不起作用。

这是我测试过的内容:CodePen

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

ctx.moveTo(0, 0);
ctx.lineTo(200, 100);
ctx.stroke();

ctx.save();

ctx.globalCompositeOperation = 'destination-out';
ctx.strokeStyle = "rgba(0,0,0,1)";

ctx.moveTo(0, 0);
ctx.lineTo(200, 100);
ctx.stroke();

ctx.restore();
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

(仅当我将第二个ctx.stroke();乘以几次时,笔划才会消失)。

您能帮助我使它正常工作还是实现我的最初目标吗?

  • 上下文:
    • 我在javascript对象中有一些“形状”
    • 这些“形状”是在画布上绘制的
  • 我的目标是在javascript对象中添加/删除形状后立即隐藏/显示形状

谢谢您的帮助。

1 个答案:

答案 0 :(得分:0)

根据要求,这是一个使用canvas层作为缓冲区的绘图示例。基本上,您可以使用随机颜色在每个图层上进行绘制,并且它们将被绘制到中央画布中,您可以检查图层的开和关以查看发生了什么。希望对您有所帮助。

var layers = document.getElementById( 'layers' );
var output = document.querySelector( '#output canvas' );
var add = document.getElementById( 'add' );
var id = 0;
var selected;

add.addEventListener( 'click', event => {
  
  event.preventDefault();
  
  let li = document.createElement( 'li' );
  let canvas = document.createElement( 'canvas' );;
  let checkbox = document.createElement( 'input' );
  
  checkbox.checked = true;
  checkbox.type = 'checkbox';
  checkbox.addEventListener( 'change', event => {
    
    li.classList.toggle( 'visible' );
    
  });
  
  li.canvas = canvas;
  li.textContent = 'Layer #' + (++id);
  li.classList.add( 'visible' );
  li.addEventListener( 'click', event => {
    
    layers.querySelectorAll( '.selected' ).forEach(child => {
      child.classList.remove( 'selected' );
    });
    li.classList.add( 'selected' );
    selected = li.canvas;
    
  });
  li.insertBefore( checkbox, li.childNodes[ 0 ] );
  
  layers.appendChild( li );
  
});

var color;

output.addEventListener( 'mousedown', event => {
  
  let r = Math.floor( Math.random() * 255 );
  let g = Math.floor( Math.random() * 255 );
  let b = Math.floor( Math.random() * 255 );
  
  color = `rgb(${r},${g},${b})`;
  
});
output.addEventListener( 'mouseup', event => {
  
  color = null;
  
});
output.addEventListener( 'mousemove', event => {
  
  if( color && selected ){
    
    let ctx = selected.getContext( '2d' );

    ctx.fillStyle = color;
    ctx.fillRect( event.offsetX - 5, event.offsetY - 5, 10, 10 );

  }
  
});

function draw(){

  let ctx = output.getContext( '2d' );
  output.width = output.width;
  output.height = output.height;
  
  [ ...layers.childNodes ].forEach(child => {
    
    if( child.tagName && child.classList.contains( 'visible' ) ){
    
      ctx.drawImage( child.canvas, 0, 0, child.canvas.width, child.canvas.height );
      
    }
    
  })
  
  window.requestAnimationFrame( draw );
  
}

draw();
html, body {
  height: 100%;
}
#layers {
  position: absolute;
  left: 0;
  top: 0;
  width: 200px;
  height: 100%;
  background: #666;
  margin: 0;
  padding: 0;
}
#layers li {
  color: white;
}
#layers li.selected {
  background: rgba( 255,255,255,.5);
  color: black;
 }

#output {
  position: absolute;
  left: 200px;
  top: 0;
  width: calc(100% - 200px);
  height: 100%;
  display: flex;
  background: #ececec;
}
#output canvas {
  max-width: 90%;
  max-height: 90%;
  margin: auto;
  box-shadow: 0 0 50px #888;
}
<ul id="layers">
  <li id="add">Add Layer</li>
</ul>
<div id="output">
  <canvas></canvas>
</div>