简体   繁体   中英

How to erase a stroke in canvas with globalCompositeOperation = 'destination-out'?

I am trying to erase a stroke in a canvas by using the CanvasRenderingContext2D.globalCompositeOperation property of the Canvas 2D API but it doesn't work.

Here is what I've tested : 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> 

(The stroke disappear only if I multiply the second ctx.stroke(); several times).

Can you help me to get it work OR achieve my initial goal?

  • Context:
    • I have some "shapes" within a javascript object
    • These "shapes" are drawn in the canvas
  • my goal is to hide/show a shape as soon as added/deleted in the javascript object

Thank you for your help.

At request, here is an example of drawing with layers of canvas as buffers. Basically, you can draw on every layer with a random color and they will be drawn into the central canvas, you can check the layers on and off to see whats going on. Hope it helps.

 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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM