Using rotationAngle and touchRadius

A relatively small change to the Touch API in Chrome landed in Chrome 39, which introduced a working version of the webkitRotationAngle attribute on the TouchEvent object. Now in Chrome 45 (Beta in July 2015), it is unprefixed as rotationAngle, bringing our implementation more inline with the TouchEvent Spec and Firefox.

Although it's been around for a while, it is worth explaining what rotationAngle is as it opens up some more interesting usage of touch gestures especially on mobile devices.

Technically, the rotation angle is the number of degrees (between 0 and 90) of the contact area ellipse defined by Touch.radiusX and Touch.radiusY. Err, cool, right? (It should be noted that I only found out that Chrome on Android doesn't lock the radiusX and radiusY values to 64px but instead varies it depending on the contact size of the screen).

What does it actually mean?

Think of it as a way to accurately represent the size, shape and orientation of the user's finger on a screen. Users don't always tap the screen with the nib of their fingertip, but rather frequently press the screen like they are giving the police a fingerprint. Without the rotationAngle you would simple get how wide and how tall the touch gesture was. With the rotationAngle, you get 90 degrees of rotation (0 being vertical and 90 being horizontal). Why only 90 degrees? You only need the 90 degrees because as you move past those angles the radiusX and radiusY will change to accommodate.

Another cool thing about this is that the contact area of the user's finger changes as they vary the degree of pressure of their finger on the screen. It is not a direct replacement for force, but you can distinguish between light brushes on the screen because they will have a smaller surface area than a harder press.

How can I use it?

Firstly you need a device that can detect this. A Nexus 10 will work fine. A great example is to look directly at Rick Byers paint example. Not to be outdone though here is a way to use it without canvas.

var touchHandler = function(e) {
    var touches = e.changedTouches;
    var touch = touches[0]; // only concerned about first touch.
    var rotationAngle = touch.rotationAngle || touch.webkitRotationAngle || 0;
    var radiusX = touch.radiusX || touch.webkitRadiusX || 1;
    var radiusY = touch.radiusY || touch.webkitRadiusY || 1;
    var force = touch.force || touch.webkitForce || 0;
    // Use the rotationAngle to rotate the 'p' element. = radiusX * 2 + 'px'; = radiusY * 2 + 'px'; = "rotate(" + rotationAngle + "deg)";

document.documentElement.ontouchstart = touchHandler;
document.documentElement.ontouchend = touchHandler;
document.documentElement.ontouchmove = touchHandler;

Where would you use this in practice?

There are some obvious places where this would be an immediate benefit to the user:

  • Painting and image manipulation web apps for example could use this information to alter the stroke or effects applied to the canvas. You could use the touch radius to alter the size of the brush and you can combine in the rotationAngle to vary the angle of contact of the brush on the canvas.
  • Enhanced gesture recognition: If you understand the rotationAngle you can create a single finger gesture to make an object swivel.

Does every device support this?

No. It is not hugely common, yet. If you have a Nexus 10 you will see something like the following,

Touch angle rotation screenshot

Image credit to Rick Byers.

When a device can't understand angle of rotation of a touch, the rotationAngle will be 0 and the radiusX and radiusY values will be equal (but may vary depending on the current touch surface area).

Why bother?

Good question. Like many features on the web, this is an additive experience.
Touch events will work when supported, and if the radii and rotation values are available you can enhance your application to give the user a more capable experience. Not every user has a Wacom tablet but when present many painting applications will take advantage of it.

What about Pointer Events?

This is really just about making sure we have a fully fleshed out touch event API for the developers who rely on it. See how I dodged the question a bit... More seriously though, if you are interested in following along Blink's PointerEvent implementation you can star Issue 471824 and read Rick Byers' tracking doc.

See Also