如何使用全局复合操作="目的地输出"擦除画布中的笔触?



我试图通过使用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 对象中添加/删除后立即隐藏/显示形状

谢谢你的帮助。

根据要求,下面是使用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>

最新更新