javascript - How do you draw with alpha = 0 in an html5 canvas to 'erase' - Stack Overflow

How do you draw with alpha = 0 to an HTML5 Canvas? Imagine I'm making a photoshop clone, I have a

How do you draw with alpha = 0 to an HTML5 Canvas? Imagine I'm making a photoshop clone, I have a layer that's solid red. I pick the eraser tool and draw with. It draws in rgba(0,0,0,0) letting me see through to the background. How do I do this in HTML5 Canvas?

Here's some code.

var rand = function(v) {
    return Math.random() * v;
};

var canvas = document.getElementsByTagName("canvas")[0];
var ctx = canvas.getContext("2d");

// fill the canvas with black
ctx.fillStyle = "red";
ctx.fillRect(0, 0, canvas.width, canvas.height);

// Erase some circles (draw them in 0,0,0,0);
ctx.fillStyle = "rgba(0,0,0,0)";
ctx.globalCompositeOperation = "copy";
for (var ii = 0; ii < 5; ++ii) {
    ctx.beginPath();
    ctx.arc(rand(canvas.width), rand(canvas.height), 
            rand(50) + 20, 0, 360, false);
    ctx.fill();
}

/*
source-over    
source-in    
source-out    
source-atop

destination-over    
destination-in    
destination-out    
destination-atop

lighter    
darker    
copy    
xor
*/
canvas {
    margin: 10px;
    border: 1px solid black;
    background-color: yellow;
}
<div>Want red with yellow circles</div>
<canvas></canvas>

How do you draw with alpha = 0 to an HTML5 Canvas? Imagine I'm making a photoshop clone, I have a layer that's solid red. I pick the eraser tool and draw with. It draws in rgba(0,0,0,0) letting me see through to the background. How do I do this in HTML5 Canvas?

Here's some code.

var rand = function(v) {
    return Math.random() * v;
};

var canvas = document.getElementsByTagName("canvas")[0];
var ctx = canvas.getContext("2d");

// fill the canvas with black
ctx.fillStyle = "red";
ctx.fillRect(0, 0, canvas.width, canvas.height);

// Erase some circles (draw them in 0,0,0,0);
ctx.fillStyle = "rgba(0,0,0,0)";
ctx.globalCompositeOperation = "copy";
for (var ii = 0; ii < 5; ++ii) {
    ctx.beginPath();
    ctx.arc(rand(canvas.width), rand(canvas.height), 
            rand(50) + 20, 0, 360, false);
    ctx.fill();
}

/*
source-over    
source-in    
source-out    
source-atop

destination-over    
destination-in    
destination-out    
destination-atop

lighter    
darker    
copy    
xor
*/
canvas {
    margin: 10px;
    border: 1px solid black;
    background-color: yellow;
}
<div>Want red with yellow circles</div>
<canvas></canvas>

This doesn't work. All canvas operations are considered to be infinitely large which means drawing each circle (arc) with globalCompositeOperation set to "copy" effectively erases everything outside of each circle.

I might be able to setup clipping to match the circle but ideally I'd like to be able to erase with an anti-aliased circle, same as a photoshop brush.

Share Improve this question edited Mar 17, 2017 at 7:38 asked Dec 28, 2012 at 8:02 user128511user128511
Add a ment  | 

3 Answers 3

Reset to default 5

You'll want to use:

ctx.fillStyle = "rgba(0,0,0,1)"; // (Drawing with 0 alpha pretty much means doing nothing)
ctx.globalCompositeOperation = "destination-out";

Working Example

Keep in mind to save the previous globalCompositeOperation and restore it, or transparency won't work properly, later on.

The problem is that "Drawing with alpha=0 on a canvas just overlays a invisible layer of "ink", by default.

If you have to erase fluently, so when the mouse was clicked and moved this line should be erased, this might be a solution:

var canvas = document.getElementById("myCanvas");
var eraseWidth = 5;

$("#myCanvas").mousedown(function(canvas){          //the mousedown (writing) handler, this handler does not draw, it detects if the mouse is down (see mousemove)
    x = canvas.pageX-this.offsetLeft;
    y = canvas.pageY-this.offsetTop;
});

$("#myCanvas").mousemove(function(canvas){
    context.beginPath();
    var x2 = x-(eraseWidth/2);          //x2 is used to center the erased rectangle at the mouse point
    var y2 = y-(eraseWidth/2);          //y2 is used to center the erased rectangle at the mouse point
    context.clearRect(x2, y2, eraseWidth, eraseWidth);              //clear the rectangle at the mouse point (x2 and y2)
    context.closePath();
};

basically what this does is clear a rectangle when the mouse is moved, everytime the mousehandler sends a mousemove event and uses the x and y coordinates for the center of the canvas to clear the recangle. the result is a cleared (erased) line.

ok, you can see the rectangles if you move too fast, but my project was a concept, so it did the trick for me ;)

If you're working on something akin to a photoshop clone, then it's probably best for you to create a canvas for each layer. I think that would greatly simplify everything for you, while giving you better performance in return.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745451141a4628274.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信