Responding to light conditions

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! :)

Document Tags and Contributors

 Contributors to this page: chrisdavidmills, franciov
 Last updated by: chrisdavidmills,