Search code examples
javascriptcanvashtml5-canvaseraseglobal-object

Any insights on how to make a canvas drawing not go on top on the other?


It's a preety straight up and basic question. I think that because that must be a often action there must be made function, but I can't find it? Is there one? If there isn't does anybody know how to do it?


Solution

  • three ways (at least) :

    • you can clip your canvas : only the non clipped part will be drawn.

    to clip you build a path with beginPath, moveTo, lineTo, arcTo, ... arc, (any path building function) then you call clip() : the part inside the path is the clipped-in part.

    do not forget to save the context before and to restore it after (unless you want a permanent clip).

    clipping expl

    snippet :

    http://jsbin.com/oSoSugAZ/1/

     var context=document.getElementById('cv').getContext('2d');
    
     context.fillStyle='#F66';
     context.fillRect(150,150, 500,500); // draw big rect in red 
    
     context.save();
     context.lineWidth=0; // to have precise clip
     context.beginPath();
     context.moveTo(100,100);
     context.lineTo(200,100);
     context.lineTo(200,200);
     context.lineTo(100,200);
     context.closePath();
     context.clip();
     // here we can only draw within the rect (100,100) (200,200)
     context.fillStyle='#FCE'; // pink
     context.fillRect(150,150, 500,500); // will get clipped
     context.beginPath();
     context.fillStyle = '#AAF';
     context.arc(150,150, 30, 0,6.2);
     context.fill();    // won't get clipped
    
     // do not forget to restore !
     context.restore();
    
    • you might use globalCompositeOperation to choose a way the pixel you draw interact with existing ones It works for both drawing paths or images. There are too many options to discuss here, it all depend on your needs.

    a full example is here :

    https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html

    Note that darker does not work (but it's not usefull anyway, just use normal mode = source-over with low opacity (0.2) and fillRect in black).

    • another option is to use temporary canvas to make your draws. It's very easy, especially if you make small helper functions.

      function createCanvas(w,h){
      var cv = document.createElement('canvas');
      cv.width; cv.height = height;
      return cv;
      }

    ( in any case you're interested, you can have a look at my small lib to ease working with a canvas : https://github.com/gamealchemist/CanvasLib/blob/master/canvasLib.js )