Using the canvas globalCompositeOperation setting to achieve background and foreground layers

  Read comments... Posted on 4th May 2013

Summary
HTML5 canvas doesn't support layers. But by using the canvas globalCompositeOperation setting you can achieve a limited foreground/background layering effect.

When working with canvas one thing that you need to understand is that there's no concept of layers. You'd do well to imagine the canvas as a piece of paper on to which you can draw - and once you've drawn on to it that drawing is mixed in with what was already on the canvas and a reference to it is not kept.

There is a way to draw something "behind" what is already on the canvas however by using the globalCompositeOperation option. This property defaults to "source-over" - which means that new drawings are placed over the existing content - just like drawing on paper.

You can change this however to "destination-over" so that new drawings are placed "behind" any existing content. The canvas below starts with a Bar chart being drawn - and then when the button is pressed a shape is drawn behind the chart. The source code for it is shown below.

[No canvas support]

<script>
    window.onload = function (e)
    {
        /**
        * Draw the bar chart
        */
        var bar = new RGraph.Bar({
            id: 'cvs',
            data: [4,8,6,3,5,4,2],
            options: {
                labels: ['John','Luis','Pete','Olga','Mabel','Mark','Luis'],
                textAccessible: true
            }
        }).draw();
        
        /**
        * This is the function that is triggered when the button is pressed. It sets the globalCompositeOperation
        * and draws the gray polygon
        */
        drawBackgroundImage = function ()
        {
            var context = bar.context;

            context.globalCompositeOperation = 'destination-over';
            
            context.beginPath();
            context.strokeStyle = '#ccc';
            context.fillStyle = '#efefef';
            
            context.moveTo(50,50);
            context.lineTo(50,200);
            context.lineTo(450,200);
            context.lineTo(450,50);
            context.lineTo(250,100);
            context.closePath();
            
            context.stroke()
            context.fill()
            
            // Reset the composite operation back to the default
            context.globalCompositeOperation = 'source-over';
        }
    }
        
</script>

<button onclick="drawBackgroundImage()">Draw a shape behind the chart</button>
Share RGraph...
X

Comments