title: Canvas - Fill a rectangle in all areas that are fully transparent
body: <p>I'm writing a simple 2D game engine using the HTML5 canvas. I've come to adding a lighting engine. Each light source has a radius value and an intensity value (0-1, eg 1 would be very bright). There's also an ambient light value that is used to light everything else in the world that isn't  near a light source (0-1, eg 0.1 would be moonlight). The process of lighting is done on a separate canvas above the main canvas:</p>
  
  <ol>
  <li>For each light source, a radial gradient is drawn at that position with the same radius as the light source. The gradient is given two stops: the center is black with an alpha of 1-intensity of the light and the end/edge is black with alpha of 1-ambient light value. That all works fine.</li>
  <li>This is where it goes wrong :/ I need to fill the whole canvas with black with and alpha of 1-ambient light value and at the moment I do this by setting the context.globalCompositeOperation to source-out then fillRecting the whole canvas. </li>
  </ol>
  
  <p>My code for this stuff is:</p>
  
  <pre><code>var amb = 'rgba(0,0,0,' + (1-f.ambientLight) + ')';
  for(i in f.entities) {
      var e = f.entities[i], p = f.toScreenPoint(e.position.x, e.position.y), radius = e.light.radius;
  
      if(radius &gt; 0) {
          var g = cxLighting.createRadialGradient(p.x, p.y, 0, p.x, p.y, radius);
          g.addColorStop(0, 'rgba(0,0,0,' + (1-e.light.intensity) + ')');
          g.addColorStop(1, amb);
  
          cxLighting.fillStyle = g;
          cxLighting.beginPath();
          cxLighting.arc(p.x, p.y, radius, 0, Math.PI*2, true);
          cxLighting.closePath();
          cxLighting.fill();
      }
  }
  //Ambient light
  cxLighting.globalCompositeOperation = 'source-out';
  cxLighting.fillStyle = amb;
  cxLighting.fillRect(0, 0, f.width, f.height);
  cxLighting.globalCompositeOperation = 'source-over';
  </code></pre>
  
  <p>However instead of getting what I wan't out of the engine (left) I get a kind of reversed gradient (right). I think this is because when I draw the rectangle with the <code>source-out</code> composite operation it affects the colours of the gradient itself because they are semi-transparent.<br /><br />
  <img src="https://i.stack.imgur.com/T6fsx.png" alt="Desired lighting effect">
  <img src="https://i.stack.imgur.com/u6itZ.png" alt="I get this"></p>
  
  <p>Is there a way to do this differently or better? Using clipping maybe, or drawing the rect over everything first?</p>
  
  <p>Also, I modified the Mozila Dev Centre's <a href="https://developer.mozilla.org/en/Canvas_tutorial/Compositing" rel="noreferrer">example</a> on composting to replicate what I need to do and none of the composite modes seemed to work, <a href="http://chopapp.com/#1b0f6c3e" rel="noreferrer">check that out</a> if it would help.</p>
  
  <p>Thanks very much, any answer would be great :)</p>