Saturday, June 15, 2013

A simple javascript timer (using Web Workers in HTML5)

A Web Worker is a JavaScript that runs in the background without affecting the performance of the page you are visiting. In this post, we will show how to implement a simple timer, using Web Workers in HTML5. Without any further introduction, let's jump in the code. The results (and the source code) can be seen at frenetic.be/tricks/simple-timer.php
Let's start with a standard HTML5 document:

<!DOCTYPE html>
<html lang="en">


Let's add a title and a few css definitions to make it all look good:



<head>
<meta charset="utf-8" />
<title>Timer</title>

    <link href='http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,300,400' rel='stylesheet' type='text/css'>
<style type="text/css">

        .header
        {
            width:280px;
            margin-left:auto;
            margin-right: auto;
            margin-top: 50px;
                        
            font-family: 'Open Sans', sans-serif, Palatino;
            font-size: 24px;
            font-weight: 300;
            text-align: left;
            text-decoration: none;
            letter-spacing: 1px;
            color: gray;

        }

        .timer
        {
            width:200px;
            margin-left:auto;
            margin-right: auto;
            margin-top: 10px;
            padding: 40px;
            border:1px dotted gray;
                        
            font-family: 'Open Sans', sans-serif, Palatino;
            font-size: 32px;
            font-weight: 300;
            text-align: center;
            text-decoration: none;
            letter-spacing: 1px;
            color: gray;

        }

        .buttons
        {
            width:280px;
            margin-left:auto;
            margin-right: auto;
            margin-top: 20px;
        }
        
        button
        {
            width:100px;
        
            font-family: 'Open Sans', sans-serif, Palatino;
            font-size: 18px;
            font-weight: 300;
            text-align: center;
            text-decoration: none;
            letter-spacing: 1px;
            color: gray;            
        }
        
        #button1
        {
            float:left;
            margin-left: 25px;
        }
        
        #button2
        {
            float:right;
            margin-right:25px;
        }        

</style>

</head>

The body of the page is simple: a title, the timer, a start and a stop button:


<body>

    <div class="header">A simple timer:</div>

    <div class="timer" id="timer">00:00</div>   
    <div class="buttons">
        <button onclick="startTimer()" id="button1">Start</button>
        <button onclick="stopTimer()" id = "button2">Stop</button>
    </div>

</body>

And then let's create the Web Worker:


<script>

var w = null; // initialize variable

// function to start the timer
function startTimer()
{
    // First check whether Web Workers are supported
    if (typeof(Worker)!=="undefined"){
        // Check whether Web Worker has been created. If not, create a new Web Worker based on the Javascript file simpletimer.js
        if (w==null){
            w = new Worker("simpletimer.js");
        }
        // Update timer div with output from Web Worker
        w.onmessage = function (event) {
            document.getElementById("timer").innerHTML = event.data;
        };
    } else {
        // Web workers are not supported by your browser
        document.getElementById("timer").innerHTML = "Sorry, your browser does not support Web Workers ...";
    }
}

// function to stop the timer
function stopTimer()
{
    w.terminate();
    timerStart = true;
    w = null;
}
</script>

</html>

Finally, one piece is missing: the script run by the Web Worker. In this case, 'simpletimer.js':


// Should the timer start or not (has it been started already?)

var timerStart = true;

function myTimer(d0)
{
   
// get current time
    var d=(new Date()).valueOf();
   
// calculate time difference between now and initial time
    var diff = d-d0;
   
// calculate number of minutes
    var minutes = Math.floor(diff/1000/60);
   
// calculate number of seconds
    var seconds = Math.floor(diff/1000)-minutes*60;
    var myVar = null;
   
// if number of minutes less than 10, add a leading "0"
    minutes = minutes.toString();
    if (minutes.length == 1){
    minutes = "0"+minutes;
    }
   
// if number of seconds less than 10, add a leading "0"
    seconds = seconds.toString();
    if (seconds.length == 1){
    seconds = "0"+seconds;
    }

   
// return output to Web Worker
    postMessage(minutes+":"+seconds);
}
                   
if (timerStart){
   
// get current time
   var d0=(new Date()).valueOf();
   
// repeat myTimer(d0) every 100 ms
   myVar=setInterval(function(){myTimer(d0)},100);
   
// timer should not start anymore since it has been started
   timerStart = false;
}




In summary, there should be two files:

1) simpletimer.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Timer</title>
    <link href='http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,300,400' rel='stylesheet' type='text/css'>
<style type="text/css">

        .header
        {
            width:280px;
            margin-left:auto;
            margin-right: auto;
            margin-top: 50px;
                        
            font-family: 'Open Sans', sans-serif, Palatino;
            font-size: 24px;
            font-weight: 300;
            text-align: left;
            text-decoration: none;
            letter-spacing: 1px;
            color: gray;

        }

        .timer
        {
            width:200px;
            margin-left:auto;
            margin-right: auto;
            margin-top: 10px;
            padding: 40px;
            border:1px dotted gray;
                        
            font-family: 'Open Sans', sans-serif, Palatino;
            font-size: 32px;
            font-weight: 300;
            text-align: center;
            text-decoration: none;
            letter-spacing: 1px;
            color: gray;

        }

        .buttons
        {
            width:280px;
            margin-left:auto;
            margin-right: auto;
            margin-top: 20px;
        }
        
        button
        {
            width:100px;
        
            font-family: 'Open Sans', sans-serif, Palatino;
            font-size: 18px;
            font-weight: 300;
            text-align: center;
            text-decoration: none;
            letter-spacing: 1px;
            color: gray;            
        }
        
        #button1
        {
            float:left;
            margin-left: 25px;
        }
        
        #button2
        {
            float:right;
            margin-right:25px;
        }        
</style>
</head>
<body>

    <div class="header">A simple timer:</div>

    <div class="timer" id="timer">00:00</div>   
    <div class="buttons">
        <button onclick="startTimer()" id="button1">Start</button>
        <button onclick="stopTimer()" id = "button2">Stop</button>
    </div>

</body>

<script>

var w = null; // initialize variable

// function to start the timer
function startTimer()
{
    // First check whether Web Workers are supported
    if (typeof(Worker)!=="undefined"){
        // Check whether Web Worker has been created. If not, create a new Web Worker based on the Javascript file simpletimer.js
        if (w==null){
            w = new Worker("simpletimer.js");
        }
        // Update timer div with output from Web Worker
        w.onmessage = function (event) {
            document.getElementById("timer").innerHTML = event.data;
        };
    } else {
        // Web workers are not supported by your browser
        document.getElementById("timer").innerHTML = "Sorry, your browser does not support Web Workers ...";
    }
}

// function to stop the timer
function stopTimer()
{
    w.terminate();
    timerStart = true;
    w = null;
}
</script>

</html>




2) simpletimer.js

// Should the timer start or not (has it been started already?)
var timerStart = true;

function myTimer(d0)
{
    // get current time
    var d=(new Date()).valueOf();
    // calculate time difference between now and initial time
    var diff = d-d0;
    // calculate number of minutes
    var minutes = Math.floor(diff/1000/60);
    // calculate number of seconds
    var seconds = Math.floor(diff/1000)-minutes*60;
    var myVar = null;
    // if number of minutes less than 10, add a leading "0"
    minutes = minutes.toString();
    if (minutes.length == 1){
    minutes = "0"+minutes;
    }
    // if number of seconds less than 10, add a leading "0"
    seconds = seconds.toString();
    if (seconds.length == 1){
    seconds = "0"+seconds;
    }

    // return output to Web Worker
    postMessage(minutes+":"+seconds);
}
                   
if (timerStart){
   // get current time
   var d0=(new Date()).valueOf();
   // repeat myTimer(d0) every 100 ms
   myVar=setInterval(function(){myTimer(d0)},100);
   // timer should not start anymore since it has been started
   timerStart = false;
}


Check out frenetic.be/tricks/simple-timer.php to see it in action. Enjoy!!!

No comments:

Post a Comment