Implementing an HTML5 Canvas screen overlay

Chris Griggs

Part of our Dev Camp project this year involves being able to annotate a presentation slide using a mouse, finger or stylus. We instantly looked to the HTML5 Canvas element to provide a bitmap drawing surface.

Chris' Canvas overlay being used for slide annotation
Chris’ Canvas overlay being used for slide annotation

Sizing and scaling the Canvas

When first trying to create a canvas that overlaid the screen I discovered that they had two height/width properties.

  • – CSS attributes
  • canvas.height/width – DOM properties

The CSS attributes can take percentage values (100% in our case), the DOM properties cannot. If you try this you end up with a canvas of dimensions 0, 0. The trick is to put the canvas in a div and set the size with JavaScript.

Scaling the canvas with the window can be done by setting the the style.width and style.height in an event handler. This thought makes the co-ordinates of the screen and that of the canvas out of sync so lines don’t appear under where you draw them. Unfortunately changing the DOM properties causes the canvas to clear itself, necessitating copying the canvas, resizing it, and copying back the content but rescaled.

An easiler solution was to fix the size to the canvas and only change the CSS attributes translating between the screen co-ordinates and those of the canvas, this gives rescaling for free and will also make matters easier when displaying the annotations on multiple screens with different resolutions.

To make the canvas appear in front of everything else it was given a-really-big-number™ for its z-index.

Annotating with pointer events

Annotating on the canvas was done by adding event listeners for mousedown, mousemove, and mouseup. This worked well on traditional devices with a mouse but not at all on newer touch-orientated devices. Rather than duplicating effort and coding for both mouse events and touch events (and possibly others; pen for example), pointer events were used.

Earlier in the year we had a lunchtime mini-conf video of Jacob Rossi’s W3Conf talk ‘Pointing-forward’ where he spoke about the proposed pointer events W3C specification from Microsoft for handling hardware agnostic pointer input. It is supported in IE10 with vendor prefixes and in IE11. Fortunately there’s a polyfil, hand.js, to enable support in other browsers.

One slight additional change required for touch devices is to disable the default behaviour of the events; dragging your finger over the device is usually mapped to scroll.

Hiding the canvas and disabling it to allow interaction with underlying content was easily achieved using two CSS attributes: visibilty (hidden/visible), and pointerEvents (none/auto).

We ended up with a canvas that could be shown and hidden, overlaying the slide and allowing the user to annotate on top without disturbing the content underneath. As well as being able to switch off annotation mode, so that you could then interact with the slide, but keep the annotation overlay visible.