Search code examples
javascripthtml5-canvastransparency

Draw rgba colors on canvas instead of drawing transparently


Is there a way to draw on an HTML canvas such that the resulting image is transparent?

I know you can set globalAlpha, but that will only affect how subsequent drawing operations work: setting globalAlpha=.5, then drawing black on red results in a dark red, not a transparent black.

I know you can canvas.fillStyle='rgba(0,0,0,0.5)', but again, that will only affect the drawing operation, not the color that is drawn (see this fiddle). I find this incredibly counter-intuitive.

When I draw in rgba(0, 0, 0, 0.5) at a point where the canvas was previously red, I want the canvas to be gray at that point and transparent. The reason I want this is that I want to upload the image and get a partially transparent image.

Is there any way to do that?


Solution

  • The easiest is probably to draw your semi-transparent part in two passes:

    • first as a cut-out, with an opaque fillStyle,
    • then as an actual paint, with the semi-transparent fillStyle

    We can't do a single pass because apart from "clear" all composite modes do take the alpha channel into consideration, so by applying such compositing with a semi-transparent paint, the previous drawing will still be "semi" visible.

    const canvas = document.getElementById('some_canvas');
    const ctx = canvas.getContext('2d');
    
    ctx.setTransform( 2, 0, 0, 2, -50, -50 );
    
    ctx.beginPath();
    ctx.arc(50,50,15,0, 2*Math.PI, true);
    ctx.fillStyle='red';
    ctx.fill();
    
    ctx.beginPath();
    ctx.arc(50,50,10,0, 2*Math.PI, true);
    // first pass to clear behind the to-be-painted shape
    // notice we keep the fillStyle opaque (the color doesn't matter)
    ctx.globalCompositeOperation = "destination-out";
    ctx.fill();
    // second pass, the actual painting, with the desired color
    ctx.globalCompositeOperation = "source-over";
    ctx.fillStyle='rgba(0,0,0,0.5)';
    ctx.fill();
    /* CSS checkerboard stolen from https://drafts.csswg.org/css-images-4/#example-2de97f53 */
    canvas {
        background: repeating-conic-gradient(rgba(0,0,0,0.1) 0deg 25%, white 0deg 50%);
        background-size: 2em 2em;
    }
    <canvas id="some_canvas" width="100" height="100"></canvas>