Android & iOS applications are really powerful when it comes to user experience. You can use many hardware tools that come with your user's devices to play with — for instance — the camera, the accelerometer, or even the vibration.
But as the Web grows, so do the APIs that can communicate with those pieces of hardware.
Today, I'm going to show you how you can add vibration to enhance the user experience of your web applications using the Vibration API.
Goal
Our goal today is to create a function that will handle the vibration of the device used to display our application.
Since all devices are not equal in support, and some do not have a vibration chip at all like desktops, we should account for the case when the Vibration API is not supported. In our case, we won't throw any error or do anything special since I consider vibration as a bonus feature, not a requirement for using the application.
Let's code!
"use strict";
function vibrate() {
if (!window) {
return;
}
}
Since it is written in JavaScript, and that JavaScript can be run on the client but also on the server thanks to Node.js, we should account for the case when our script is run outside of a browser (by mistake I assume).
"use strict";
function vibrate() {
if (!window) {
return;
}
if (!window.navigator) {
return;
}
}
If the navigator
object is not available in the window
global object, this means we are in serious trouble. But anyway, better be sure it is there before getting weird error messages.
"use strict";
function vibrate() {
if (!window) {
return;
}
if (!window.navigator) {
return;
}
if (!window.navigator.vibrate) {
return;
}
}
Here, we check that the Vibration API is available. If it is not available, it is totally okay! This only means that the device does not have vibration capability. Since most of the time, this is not a big deal (except if you are trully relying on that feature for your application to work), we can simply stop the execution of our function if it is not available.
"use strict";
function vibrate() {
if (!window) {
return;
}
if (!window.navigator) {
return;
}
if (!window.navigator.vibrate) {
return;
}
window.navigator.vibrate(100);
}
And there it is! The Vibration API in action. This is how we can tell the browser to vibrate the device for 100 milliseconds. You can even specify an array instead of a single value to create a vibration pattern.
For instance, if we need to vibrate two times for 200 milliseconds, separated by a 100 milliseconds interval, we can do that instead.
"use strict";
function vibrate() {
if (!window) {
return;
}
if (!window.navigator) {
return;
}
if (!window.navigator.vibrate) {
return;
}
window.navigator.vibrate([200, 100, 200]);
}
See? That easy!
Parameterizing
You may want to customize the way the vibration happens in your application. Perhaps considering the user doing a specific action means a specific vibration. We should enable parameters for our function to make it more versatile.
"use strict";
function vibrate(options = { duration: 100, interval: 100, count: 1 }) {
if (!window) {
return;
}
if (!window.navigator) {
return;
}
if (!window.navigator.vibrate) {
return;
}
const pattern = [];
for (let index = 0; index < options.count; index++) {
pattern.push(options.duration);
pattern.push(options.interval);
}
window.navigator.vibrate(pattern);
}
That way, we can call our vibrate
function like so.
<button
onclick="vibrate({ duration: 200, interval: 150, count: 3 })">
vibrate
</button>
Hitting the button will trigger three vibrations of 200 milliseconds of duration separated by an interval of 150 milliseconds. Cool, huh?
Cleanup
That's it! Our function is now complete and we got the API we wanted. Now, as for any JavaScript function, we should make it more secure by adding some guards with some runtime type checking.
function vibrate(options = { duration: 100, interval: 100, count: 1 }) {
if (arguments.length !== 1) {
throw new Error("Expected exactly one argument.");
}
if (Object.prototype.toString.call(options) !== "[object Object]") {
throw new TypeError("Expected first argument to be an object.");
}
if (typeof options.duration !== "number" || !Number.isInteger(options.duration)) {
throw new TypeError("Expected options.duration to be an integer.");
}
if (typeof options.interval !== "number" || !Number.isInteger(options.interval)) {
throw new TypeError("Expected options.interval to be an integer.");
}
if (typeof options.count !== "number" || !Number.isInteger(options.count)) {
throw new TypeError("Expected options.count to be an integer.");
}
if (options.duration < 0) {
throw new RangeError("Expected options.duration to be greater or equal to zero.");
}
if (options.interval < 0) {
throw new RangeError("Expected options.interval to be greater or equal to zero.");
}
if (options.count < 0) {
throw new RangeError("Expected options.count to be greater or equal to zero.");
}
if (!window) {
return;
}
if (!window.navigator) {
return;
}
if (!window.navigator.vibrate) {
return;
}
const pattern = [];
for (let index = 0; index < options.count; index++) {
pattern.push(options.duration);
pattern.push(options.interval);
}
window.navigator.vibrate(pattern);
}
Yeah... It is a "little bit" longer. But what we are trying to do here is making sure the function gets called correctly, has the proper types for each one of the options and that they are all positive integers. If you don't like this type of programming habit, you can skip it and go back to our previous definition of the function but it is a good habit to have some runtime type checking since the developer-user can make mistakes (and so do we).
Conclusion
Yesterday, it was really hard to compete with native Android & iOS applications since the Web had little to no tools to communicate with the hardware, but it is a thing from the past.
Day after day, the browser's development team are working hard to bring those tools for the Web and we can now enjoy manipulating the Vibration API of the device right through our web applications.
Here is an example application to see if your device supports vibration.
Top comments (14)
Please note that this does not work on iOS devices.
Noted! They'll eventually support that feature but it is a shame that it gets its support later than the other platforms. 😞
But what is cool about that code is that you can use it today even if there's no support now because when it does you'll have literally nothing to do. It will just work!
Actually, WebKit had support in 2012 or so. They removed it, no plans to bring it back. See this thread on tw for some of the reasoning:
twitter.com/grorgwork/status/86283...
So does that mean if you want to try it, you'd have to find an Android phone to do it? (the only device that can do it is Android phone)
For now this is the case. I haven't any information about when will the Apple Dev Team (and other OEM) will decide to introduce this feature but one can say that this won't take long since this isn't an experimental feature anymore.
As for gaming platforms (Playstations, XBox, Steam) this may take even longer because they may not have the same roadmap for Web support than the other OEM.
it is possible to condense it to
Or with optional chaining even better to
Beware that this is still in experimental support! So if the browser does not support this syntax this will throw an error.
But I would of course use this syntax if I was using a transpirer for instance. Really shorten the syntax and looks nice!
Sure, then again the browsers that support vibrate and actually vibrate support it so for the most part it's harmless
Yes absolutely. From now I guess it's a matter of development practice. But this would work as well (I haven't test it though but it seems working to me).
I was so sad to find out that vibration was for mobile devices and not for Xbox controllers.
Oh shoot! I didn't know that one. Maybe Microsoft will push the support now that they decided to go on the path of choosing Chromium as their base for Edge. That's not impossible to see a better browser for the XBox in a near future.
I have hope!
I can't get this to vibrate on my android. I don't get it. Is there a setting I need on?
There can be multiple reasons but this would mean that either your browser at this particular version does not support vibration or your device is not supported for this current version.
Try updating or changing your browser and try and check to see if there is an update for your device.
If you don't get it to work even after all of these steps then it must probably be that your device is not supported.