The canvas v5 specification
Written by Richard Heyes, RGraph author, on 31st October 2012
As of March 2012, several new features to the canvas
api
were announced. These features will make
using the canvas
tag much easier - particularly reading mouse events, and will also make for more
concise code. In turn, this will mean
more efficient code, smaller libraries and faster downloads.
- Hit regions
- Automatic cursor control
- Path object
- Dashed lines
- Ellipses
- Text on a path
- Support for SVG path syntax
- Other new features
- Summary
Hit regions
Hit regions are possibly the most exciting of all the features. They provide a way for you to define an area
of your canvas
(and add an id:
property to it) and then you can check the event.region
property (on the
event object provided by the canvas
tag event) to see if it matches that id:
. No more working
out whether the mouse coordinates are within a particular area - which can range from being a chore to being entirely
impractical. It will mean that significant amounts of click-detection code could be eliminated from libraries that use
canvas
and that means faster, smaller downloads and more efficient and readable code. Also, it will mean that click
detection
becomes much easier for complex shapes.
<script> context.beginPath(); context.rect(10,10,100,100); context.fill(); context.addHitRegion({ id: 'The First Button' }); context.beginPath(); context.rect(120,10,100,100); context.fill(); context.addHitRegion({ id: 'The Second Button' }); canvas.onclick = function (event) { if (event.region) { alert('You clicked ' + event.region); } } <script>
This odd shape would be non-trivial to test for clicks - not impossible - but
certainly not straightforward. With hit testing and the new Path
object
described below, this becomes much easier. Currently, you would have to keep the coordinates to
hand and then recreate the
path and use isPointinPath
. With the new Path
objects, you could just
keep the object around. With hit regions, you wouldn't have to
even do that - just define a hit region for a particular path and it's done for you.
The javascript
code for this example using the isPointInPath
function is this:
<script src="RGraph.common.core.js"></script> <script> canvas = document.getElementById("cvs"); context = canvas.getContext('2d'); context.beginPath(); context.fillStyle = 'red'; context.moveTo(50,50); context.quadraticCurveTo(150,25,200,150); context.lineTo(100,245); context.lineTo(50,125); context.lineTo(100,50); context.closePath(); context.stroke(); context.fill(); canvas.onmousemove = function (e) { var coords = RGraph.getMouseXY(e); if (context.isPointInPath(coords[0], coords[1])) { var text = 'YES'; var cursor = 'pointer'; } else { var text = 'NO'; var cursor = 'default'; } document.getElementById("out").value = 'Is point in path: ' + text; canvas.style.cursor = cursor; } </script>
Automatic cursor control
You can also associate a cursor type to a hit region
meaning that when the mouse is moved into
that region the mouse
cursor is automatically changed.
<script> context.addHitRegion({ path: new Path('M 10 10 h 20 v 20 h -20 z'), cursor: 'url(fight.png)', }); context.addHitRegion({ path: new Path('M 50 30 h 20 v 20 h -20 z'), cursor: 'url(quaff.png)', }); </script>
Path object
The new Path
object is really promising. It will bring a slight air of Object Orientation to canvas
in that you can draw a path as usual -
but unlike at present - you can then save it for later use. So you will be able to test for mouse clicks (with the isPointInPath
method) or draw the
path again with different colors to add highlighting.
Some sample code:
<script> var myPath = new Path(); myPath.rect(0, 0, 100, 100); context.fill(myPath); // At this point you can retain or throw away the myPath object </script>
Dashed lines
RGraph currently has support for dashed lines with the RGraph.dashedLine
function, however, the addition of native dashed
lines will be faster and mean that curved dashed/dotted lines will be feasible.
Update January 2013: Dashed lines are now implemented in Google Chrome and
there's an article about them here.
Ellipses
Similar to the context.arc
method, the context.ellipse
method adds an ellipse to the canvas
. Indeed if the radiusX
and radiusY
arguments are equal and the rotation argument is zero then this performs exactly like the arc
function.
<script> context.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise); </script>
Text on a path
Previously supported by Firefox only, this allows you to add text to a path and that text will follow the path. This allows for text following a curved line or going around a circle (potentially animated too).
Support for SVG path syntax
The svg
path syntax is much less verbose. In addition, having paths laid out in a string allows
you to easily pass them around. An example is:
<script> myPath = new Path('M 100,100 h 50 v 50 h 50'); context.stroke(myPath); </script>
Along with
the new Path
object this allows for easier retention of the shapes you have drawn on the canvas
and subsequent testing
for click
events. In the example the M
translates to moveTo
and
the h
is a horizontal line (hence
only the x-axis
coordinate is given and it's drawn relative to the current position).
Other new features
- APIs that take
SVGMatrix
objects for transforms - Many more metrics from the
measureText
function - Ability to transform a pattern
- Reset the clip region:
context.resetClip
- Reset the transform:
context.resetTransform
Summary
When you look at each individual feature listed above then they look good, but when you take
them all into account together
they are no less than superb. When browsers have support
for them they will make working with
the canvas
tag much easier, mean that
you'll have to write less code and increase the
accessibility to users who need it.