Ambient light sensors detect the presence and intensity of visible light. If used in a smart way, ambient light sensing optimizes visibility and battery life of portable devices such as tablets, smartphones, and laptops. This article looks at one way to respond to light conditions in the context of Open Web Apps: The Ambient Light API. Using this we can get information on the ambient light level and take actions to improve readability or create special effects dependant on light conditions. And even better, this article is rounded off with a nice Christmas-themed demo!
Ambient Light Sensors
Ambient light sensors are used in a variety of functions such as adjusting display brightness to a comfortable level.
In the context of smart houses, ambient light sensors can be used to turn on room lights when it gets too dim for human eyes and turn off unneeded lights when room brightness is adequate, or for video surveillance applications that detect motion via ambient light level changes.
In the context of Open Web Apps, consider for example an e-book reader app that automatically adjusts brightness in different light conditiions to improve readability.
Ambient Light API
The Ambient Light API gives web developers a tool to get information from available photo sensors (or similiar detectors) about the ambient light level. The W3C Specification defines the DeviceLightEvent
, explained in this MDN page.
The LightLevelEvent
was removed from the W3C specification on June 2014.
Demo: XMAS Tales
XMAS Tales is an e-book reader app for kids that uses the Ambient Light API to respond to different light conditions with special effects, to impress children with the magic of Christmas. The demo is published here and you can also grab the source code on Github to play with.
Notes:
- Currently the Ambient Light API is supported only by Firefox and Firefox for Android. You should test it here first.
- Portable devices such as MacBooks and Android tablets usually have an ambient light sensor.
- The demo does not support small resolutions very well at present.
Let’s have a look at the code, starting with the HTML & CSS and then exploring the JavaScript, and how the demo used the Ambient Light API.
HTML & CSS
The Ambient Light API is a Javascript API, so showing the HTML and CSS might be considered out of scope here, but I think it is crucial to understand at least the elements composing the page on which JavaScript operates.
The main elements are:
- The Book
- The Christmas Tree
- The Ambience
The Book
This is the book cover:
And this is the HTML structure:
<div class="book"> <div class="cover">...</div> <div class="page1">...</div> <div class="page2"> <div> <div class="sky"> ... <div class="tree">...</div> <div id="ambient-light-info"> <p>Ambient Light<br/><span id="lux">unknown</span> lux</p> </div> ... </div> </div> </div> </div>
The book cover and rather nifty page flip motion is all done using CSS, including some complex CSS transform and transition action. You can find the CSS code for the book in the book.css file.
The Christmas Tree
Here is the Christmas Tree inside the book:
This is the HTML:
<div class="tree"> <div class="branch"></div> <div class="branch"></div> <div class="branch"></div> <div class="branch"></div> <div class="branch"></div> <div class="branch"></div> <ul class="bauble-container"> <li><div class="pink bauble"></div></li> <li><div class="red bauble"></div></li> <li><div class="blue bauble"></div></li> <li><div class="yellow bauble"></div></li> <li><div class="green bauble"></div></li> </ul> </div>
The tree and bauble are all created using CSS, with some crafty use of borders and border radius for the "branches", and border-radius and gradients for the Christmas baubles. You can find the CSS code for the Christmas Tree in the christmas-tree.css file.
The Ambience
The book is contained inside an ambience
div
<div class="snow ambience"> <div class="book">...</div> </div>
This way, depending on the mood class associated with it (snow
, morning
, evening
or night
), the book and the Christmas Tree have a different ambience projected over the top of them.
The most important thing to understand here is that, when the mood class on the ambience
div is set to night
, the sky
becomes darker and it starts snowing. This is achieved via the following CSS:
.night.ambience .sky { color: whitesmoke!important; background-color: #080A38!important; background-image: url('../images/snow.png'), url('../images/snow3.png'), url('../images/snow2.png')!important; animation: snow 20s linear infinite; }
At the same time, the baubles are switched on:
.night.ambience .bauble.on:after { … }
And the "Merry Christmas" message becomes visible:
.night.ambience .message { visibility: visible; }
Finally, some of the words of the story on page 1 change color:
.night.ambience .book .page1 span { font-weight: bold; font-size: 1.2em; color: #00a1ee; }
You can find the CSS code for the Christmas Tree in the ambience.css file.
Javascript and Ambient Light Events
XMAS Tales implements the following JavaScript files:
<script src="scripts/book.js"></script> <script src="scripts/christmas-tree.js"></script> <script src="scripts/ambient-light-manager.js"></script> <script src="scripts/app.js"></script> <script src="scripts/start.js"></script>
This demo is built using Object Oriented Programming. For an introduction to Object Oriented Javascript have a look at this MDN page.
Each JavaScript file represents a component that executes specific tasks in the application. The AmbientLightManager
is the component that uses Ambient Light Events so the most interesting code for the purposes of this tutorial is inside AmbientLightManager.js. However, in order to understand how the app works, we’ll briefly have a look at all the JavaScript files. Feel free to skip to the Ambient LightManager section if you are mainly interested in the Ambient Light API.
Start
The app.js file contains the initializations of the Javascript Objects which the XMAS Tales web app needs to work.
Book.init(); ChristmasTree.init(); AmbientLightManager.init();
This is done when the window
object is loaded.
Install
When Mozilla launches the first Firefox OS tablet, we can easily add an install button. Watch this video in the meantime.
If you are not familiar with building web apps for Firefox OS, please have a look at our Quickstart app tutorial.
The Book
Surprise! To flip the cover of the book we don’t need JavaScript: it’s all made with CSS transitions defined in book.css. We currently only have a single page, but a javascript object can be helpful if you want to add more pages and include a navigation bar.
The Christmas Tree
The Christmas Tree has 5 baubles:
this.pinkBauble = document.querySelector('.pink.bauble'); this.redBauble = document.querySelector('.red.bauble'); this.blueBauble = document.querySelector('.blue.bauble'); this.yellowBauble = document.querySelector('.yellow.bauble'); this.greenBauble = document.querySelector('.green.bauble');
which blink randomly:
this.blinkRandomly();
The blinkRandomly
method repeatedly adds the on class and removes it after a while. This is done by executing a code snippet repeatedly, with a random time delay between each call to that function:
window.setInterval(function() { _self.pinkBauble.classList.add('on'); window.setTimeout(function() { _self.pinkBauble.classList.remove('on'); }, Math.random() * 8000); }, Math.random() * 11000);
Have a look at the MDN pages for window.setInterval, window.setTimeout and Math.random if you need some more background information about these functions.
Although the blinkRandomly
method is called by the ChristmasTree
constructor, Christmas lights will be visible only when it’s dark, i.e. when the Christmas Tree's ambience container has .night.ambience
classes set on it.
Have a look at the christmas-tree.js for more details.
The AmbientLightManager
The AmbientLightManager
uses the Ambient Light API to manage the following DOM Objects:
this.ambience = document.querySelector('.ambience'); this.lux = document.querySelector('#lux');
The constructor adds a listener to the devicelight
event:
/* Ambient Light Events */ window.addEventListener('devicelight', function(deviceLightEvent) { /* Ambient light level (lux) to screen */ _self.printLux(deviceLightEvent.value); /* Check ambient light status */ if (deviceLightEvent.value > 500) { // snow _self.setSnow(); } else if (deviceLightEvent.value > 100) { // morning _self.setMorning(); } else if (deviceLightEvent.value > 10) { // evening _self.setEvening(); } else { // night _self.setNight(); } });
The printLux
method prints the level of ambient light (measured in lux) to the bottom right of page 2, just below the Christmas Tree.
The setSnow
, setMorning
, setEvening
and setNight
methods just put the related classes alongside the ambience class on the ambience
div. For example, this is the setNight
method:
setNight: function() { this.ambience.classList.remove('evening'); this.ambience.classList.remove('morning'); this.ambience.classList.remove('snow'); this.ambience.classList.add('night'); }
And thanks to ambience.css, this is the final result:
Merry Christmas! :)