Introducing the Proximity API
Smartphones and mobile devices have gained a lot of importance in our life and it seems increasingly that we cannot live without them.
When used properly and with moderation they are valuable tools that can help us in achieving common tasks such as knowing the next bus, locating the nearest tube, searching for an Italian restaurant and so on.
They have also opened a whole new world to web developers. In fact, thanks to the rise of needs derived from the use of mobile devices, a set of new APIs specifically created for them has been standardized.
In the last months I’ve introduced you to several APIs, such as the Web Notifications API and the Web Speech API. In this article I’ll describe a simple, yet useful API called Proximity API.
Introduction
The Proximity API defines events that provide information about the distance between a device and an object, as measured by a proximity sensor. This API was initially part of the the Sensor API, later split and become an independent API. The specifications of the Proximity API are considered stable because it reached the status of W3C Candidate Recommendation as of 1st October 2013.
If you’ve ever had or used a smartphone, which I assume you have, you’ve already seen this API in action.
Want an example? Think of your last phone call and what you did. You unlocked your smartphone, typed the number you wanted to call, and then tapped the “Call” button. Once done, you placed the smartphone near your ear and suddenly something magic happened, the screen turned off.
This is an action many smartphones perform to safe your battery, but what powered this feature was the Proximity API. When you place your mobile device near enough to your ear, the proximity sensor fires an event that is listened to by your smartphone, which in turn shuts off the screen.
On the web, we have other interesting use cases. Have you ever been driving while listening to music using a web service and had to stop it?
How painful was it to take your device and then manually stop the player? I guess the answer is “A lot!”. Thanks to this API, web developers can now add a feature so that if an object (the hand in this case) is close to the device the player will pause.
Now that we know what the Proximity API is and its use cases, we can dive into the events it exposes.
Events
The Proximity API defines two events that we can listen to and react to based on the proximity of an object. The first event is deviceproximity
and provides information about the distance between the hosting device and a nearby object. The second event is userproximity
and specifies if the device has sensed a nearby object. Both fire on the window
object, so to listen to them we attach a handler to it.
An example of how to attach a handler for the deviceproximity
event is below:
window.addEventListener('deviceproximity', function(event) {
console.log('An object is ' + event.value + ' centimeters far away');
});
The handler attached receives an object as its first parameter containing the info we need. The object passed by the deviceproximity
event offers three properties: value
, min
, and max
. value
is a number that represents the proximity of the device to an object in centimeters. The min
and max
properties describe the minimum and the maximum distance the sensor can detect, in centimeters. The object passed by the userproximity
event exposes the near
property. It’s a boolean that specifies if an object is close enough to the device (true
) or not (false
). In this case close enough means the object is within the detectable range for the specific device.
Excited about this API? Not so fast…
Browser Compatibility
The support for the Proximity API is very low at the moment. The only browser that supports it is Firefox, both on desktop and mobile, starting from version 15. This is strange considering that it has already reached the status of W3C Candidate Recommendation but this is what we have for now.
Because this API has been implemented only in Firefox, knowing how to test for its support is crucial. We can do that using a well-known method that you may have encountered when dealing with other APIs. This method is shown below:
if ('ondeviceproximity' in window) {
// API supported. Don't get too close, I can feel you
} else {
// API not supported
}
As shown above, we can test the support of the userproximity
event. At this point, we know what the Proximity API is and what events it exposes. To complete our journey, we’ll develop a simple demo to see it in action.
Demo
The demo we’ll build in this section attaches a handler to the deviceproximity
and userproximity
event and shows the value returned on the screen. To show the values, we’ll use an unordered list. Also, we’ll place two span
tags at the beginning of the page to specify if a given event is not supported. By default they are hidden but if the browser doesn’t support an event they will be shown.
The JavaScript code is also simple. Firstly we test the browser to see if it supports the Proximity API. Because the latter comprises of two independent events, we’ll test them once at a time. If a given event isn’t supported, we show the relevant message to the user using the associated . Otherwise, we attach a handler so that we can retrieve and then show the values returned.
The source code of the demo is below, but you can also play with a live demo. This API is part of my HTML5 API demos repository, a collection of demos that allows you to play with dozens of APIs introduced by HTML5 and the related technologies.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="author" content="Aurelio De Rosa">
<title>Proximity API Demo by Aurelio De Rosa</title>
<style>
*
{
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body
{
max-width: 500px;
margin: 2em auto;
padding: 0 0.5em;
font-size: 20px;
}
h1
{
text-align: center;
}
.api-support
{
display: block;
}
.hidden
{
display: none;
}
.value
{
font-weight: bold;
}
.author
{
display: block;
margin-top: 1em;
}
</style>
</head>
<body>
<h1>Proximity API</h1>
<span id="dp-unsupported" class="api-support hidden">deviceproximity event not supported</span>
<span id="up-unsupported" class="api-support hidden">userproximity event not supported</span>
<ul>
<li>
An object is at a distance of <span id="dp-value" class="value">null</span> centimeters
(within a detectable range of <span id="dp-min" class="value">null</span> -
<span id="dp-max" class="value">null</span> centimeters).
</li>
<li>
Object close to the device? <span id="up-value" class="value">unavailable</span>
</li>
</ul>
<small class="author">
Demo created by <a href="http://www.audero.it">Aurelio De Rosa</a>
(<a href="https://twitter.com/AurelioDeRosa">@AurelioDeRosa</a>).<br />
This demo is part of the <a href="https://github.com/AurelioDeRosa/HTML5-API-demos">HTML5 API demos repository</a>.
</small>
<script>
if (!('ondeviceproximity' in window)) {
document.getElementById('dp-unsupported').classList.remove('hidden');
} else {
var proximityValue = document.getElementById('dp-value');
var proximityMax = document.getElementById('dp-max');
var proximityMin = document.getElementById('dp-min');
window.addEventListener('deviceproximity', function(event) {
proximityValue.innerHTML = event.value;
proximityMax.innerHTML = event.max;
proximityMin.innerHTML = event.min;
});
}
if (!('onuserproximity' in window)) {
document.getElementById('up-unsupported').classList.remove('hidden');
} else {
var inProximity = document.getElementById('up-value');
window.addEventListener('userproximity', function(event) {
inProximity.innerHTML = event.near;
});
}
</script>
</body>
</html>
Conclusions
In this article I introduced you to the Proximity API. We’ve seen what this API does and its use cases. We’ve discussed the events provided and how we can use them to adapt the behaviour of a web application based on the presence of an object near a device. Unfortunately, this API is only supported by Firefox so it may not be the time to use it yet.
What do you think about this API? Do you find it useful? Will you employ it in your next project?