javascriptcanvasshadowglobalcompositeoperation

HTML Canvas: inner shadow for circle shapes (planets)


my intention is to draw semi-circular inner shadows inside circular shapes that represent planets moving around a star (this is part of an educational program I'm working on).

After many approaches, this was the one that almost worked for me:

  1. Draw a circular shape (planet) and over it, stroke a larger circle that contains the actual shadow.

Each planet as a circle that will paint the shadow over it 2. Using the composition option "ctx.globalCompositeOperation='source-atop';" to draw the bigger circle it will only paint the portion that overlaps the existing content:

Only the area that overlaps content will be painted

But the problem is that any planet will overlap any shadow circle, so, as you can see, when a planet overlaps the bigger shadow it turns totally dark.

Is there any way to make it draw the overlap area of a specific content (shape)?

Or, do you know a better way to do this? Remember I must paint the shadow in the specific angle from the planet to the light source.

Thanks in advance!


Solution

  • Try to call clip method (and related codes) before drawing "shadow" onto planet like this.

    const ctx = canvas.getContext("2d");
    
    //draw planet
    ctx.beginPath();
    ctx.arc(100, 100, 80, 0, Math.PI*2);
    ctx.fillStyle = "aqua";
    ctx.fill();
    //save non-clipped state.
    ctx.save();
    //clip range by planet area.
    ctx.clip();
    //draw shadow
    ctx.beginPath();
    ctx.arc(200, 200, 200, 0, Math.PI*2);
    ctx.lineWidth = 100;
    ctx.stroke();
    //dispose clip range.
    ctx.restore();
    <canvas id="canvas" width="200" height="200"></canvas>