finalImage

XBoxReveal HTML5 Windows Phone Sample

Over the past few months we have been doing a lot of Windows 8 development but using HTML5 and JavaScript instead of C# and XAML. Unfortunately Windows Phone does not have built in support for WinJS but what it does have the latest IE 10 browser on board plus we have the WebBrowser control available.

Recently, with the XBox announcement, we decided to build out a Windows Phone app that counts down to the reveal date which looks as follows. We have the app in certification as of May 3 2013 (submitted April 30), but is still going through the process. As I don’t expect it to pass because of the XBox logo usage, decided to make a tutorial out of it. But for all those enthusiast (and developers), you can grab the source and install on your Windows Phone.

1-720p

I decided to build it using HTML with an embedded webBrowser control and this is how we got it done. The app above took about 1hr to build and leveraged some existing JavaScript code found on the web. Thanks to RedBit’s graphics designer Kevin Carey for the graphics, he’s the reason the app looks good!  The next few sections will walk through how to build the count down timer app.

Getting Started

First thing, open Visual Studio and create a new project. In the Windows Phone section you will see a ‘Windows Phone HTML5 App’ project template.

project

When the project gets created you will have a MainPage.xaml which will contain your WebBrowser Control. It’s wired up to do things like navigate the pages but but if you are creating an app you want it to not look like a web app in my opinion and having navigation buttons doesn’t help.

For the countdown timer we don’t require that code, so we can remove most of that code.  Your MainPage.xaml.cs you should end up with something as follows

// Url of Home page
private string MainUri = "/Html/index.html";

// Constructor
public MainPage()
{
    InitializeComponent();
}

private void Browser_Loaded(object sender, RoutedEventArgs e)
{
    Browser.IsScriptEnabled = true;

    // Add your URL here
    Browser.Navigate(new Uri(MainUri, UriKind.Relative));
}

// Handle navigation failures.
private void Browser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
{
    MessageBox.Show("Navigation to this page failed, check your internet connection");
}

Your MainPage.xaml, you can remove the buttons in the app and you can end up with something as follows

<phone:PhoneApplicationPage.ApplicationBar>
    <shell:ApplicationBar Mode="Minimized" Opacity="0.7" IsVisible="True" IsMenuEnabled="True">
        <shell:ApplicationBar.MenuItems>
            <shell:ApplicationBarMenuItem Text="about" Click="ApplicationBarMenuItem_Click"/>
        </shell:ApplicationBar.MenuItems>
    </shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>

Some quick things to point out.

  1. I’ve left one menu item because a Windows Phone requirement is to have contact information for the app
  2. I’ve set the mode to ‘Minimized‘ and the opacity to 0.7 so it’s not overtaking the main content, the timer

Because we have a click handler for the menu item add the following stub code which we will implement later

private void ApplicationBarMenuItem_Click(object sender, EventArgs e)
{
}

Run the app and you’ll get something like this

baseapp

 

From the screen shot you can’t really tell the difference if it’s native or HTML but when you use it you can.

Updating the HTML Page

The app consists of a single HTML page that gets loaded within the browser control. The HTML file is located under the Html directory which also contains the CSS styles

folders

 

In your Html directory create a images folder then add the following image which is the background

bg

Open up index.html and update the code to the following which all it does is add the image to the body.

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" type="text/css" href="css/phone.css" />

    <title></title>
</head>
<body>
    <img id="bg" src="images/bg.png" alt="">
</body>
</html>

In the css folder, open up phone.css and add the following to the end of the file

#bg {
  position:absolute; 
  top: 0; 
  left: 0; 
  z-index: -1;
  min-width: 100%;
  min-height: 100%;
  width: 100%;
  height: 100%;
}

When you run the app you should get a full screen image.

Implementing the Timer

Instead of re-inventing the wheel, we decided to search for some existing JavaScript code and found this http://www.rmkwebdesign.com/Countdown_Timers/Style_1_B.html. This is how we got the timer working.

In the CSS directory, create a file called timer.css and add the following (note, this was changed from the original CSS)

.numbers {
    padding: 0px;
    width: 45px;
    text-align: center;          
    font-size: 42px;
    font-weight: normal;    /* options are normal, bold, bolder, lighter */
    font-style: normal;   /* options are normal or italic */
    color: #FFFFFF;       /* change color using the hexadecimal color codes for HTML */
}
.title {    /* the styles below will affect the title under the numbers, i.e., “Days”, “Hours”, etc. */
    border-style: none;
    padding: 0px 0px 0px 0px;
    width: 45px;
    text-align: center;
    font-family: Arial;
    font-size: 15px;
    font-weight: bold;    /* options are normal, bold, bolder, lighter */
    color: #FFFFFF;       /* change color using the hexadecimal color codes for HTML */
}
#table {
    width: 400px;
    height: 70px;
    border-style: ridge;
    border-width: 3px;
    border-color: rgba(0,0,0,0)  ;     /* change color using the hexadecimal color codes for HTML */
    background-color: rgba(0,0,0,0);   /* change color using the hexadecimal color codes for HTML */
    margin: 0px auto;
    margin-top: 200px;
    margin-left: -70px;
    position: relative;   /* leave as "relative" to keep timer centered on your page, or change to "absolute" then change the values of the "top" and "left" properties to position the timer */
    top: 0px;            /* change to position the timer */
    left: 0px;            /* change to position the timer; delete this property and it's value to keep timer centered on page */
}

Under the HTML folder, create a directory called js. Create a file called timer.js and add the following CSS.

/*
Count down until any date script-
By JavaScript Kit (www.javascriptkit.com)
Over 200+ free scripts here!
Modified by Robert M. Kuhnhenn, D.O. 
on 5/30/2006 to count down to a specific date AND time,
on 10/20/2007 to a new format, and 1/10/2010 to include
time zone offset.
*/

var current = "XBox Reveal is here!";    //-->enter what you want the script to display when the target date and time are reached, limit to 20 characters
var year = 2013;    //-->Enter the count down target date YEAR
var month = 5;      //-->Enter the count down target date MONTH
var day = 21;       //-->Enter the count down target date DAY
var hour = 18;      //-->Enter the count down target date HOUR (24 hour clock)
var minute = 38;    //-->Enter the count down target date MINUTE
var tz = -5;        //-->Offset for your timezone in hours from UTC (see http://wwp.greenwichmeantime.com/index.htm to find the timezone offset for your location)

//    DO NOT CHANGE THE CODE BELOW!
var montharray = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");

function countdown(yr, m, d, hr, min) {
    theyear = yr; themonth = m; theday = d; thehour = hr; theminute = min;
    var today = new Date();
    var todayy = today.getYear();
    if (todayy < 1000) { todayy += 1900; }
    var todaym = today.getMonth();
    var todayd = today.getDate();
    var todayh = today.getHours();
    var todaymin = today.getMinutes();
    var todaysec = today.getSeconds();
    var todaystring1 = montharray[todaym] + " " + todayd + ", " + todayy + " " + todayh + ":" + todaymin + ":" + todaysec;
    var todaystring = Date.parse(todaystring1) + (tz * 1000 * 60 * 60);
    var futurestring1 = (montharray[m - 1] + " " + d + ", " + yr + " " + hr + ":" + min);
    var futurestring = Date.parse(futurestring1) - (today.getTimezoneOffset() * (1000 * 60));
    var dd = futurestring - todaystring;
    var dday = Math.floor(dd / (60 * 60 * 1000 * 24) * 1);
    var dhour = Math.floor((dd % (60 * 60 * 1000 * 24)) / (60 * 60 * 1000) * 1);
    var dmin = Math.floor(((dd % (60 * 60 * 1000 * 24)) % (60 * 60 * 1000)) / (60 * 1000) * 1);
    var dsec = Math.floor((((dd % (60 * 60 * 1000 * 24)) % (60 * 60 * 1000)) % (60 * 1000)) / 1000 * 1);
    if (dday <= 0 && dhour <= 0 && dmin <= 0 && dsec <= 0) {
        document.getElementById('count2').innerHTML = current;
        document.getElementById('count2').style.display = "inline";
        document.getElementById('count2').style.width = "390px";
        document.getElementById('dday').style.display = "none";
        document.getElementById('dhour').style.display = "none";
        document.getElementById('dmin').style.display = "none";
        document.getElementById('dsec').style.display = "none";
        document.getElementById('days').style.display = "none";
        document.getElementById('hours').style.display = "none";
        document.getElementById('minutes').style.display = "none";
        document.getElementById('seconds').style.display = "none";
        document.getElementById('spacer1').style.display = "none";
        document.getElementById('spacer2').style.display = "none";
        document.getElementById('count2').style.fontSize = "20pt";
        return;
    }
    else {
        document.getElementById('count2').style.display = "none";
        document.getElementById('dday').innerHTML = dday;
        document.getElementById('dhour').innerHTML = dhour;
        document.getElementById('dmin').innerHTML = dmin;
        document.getElementById('dsec').innerHTML = dsec;
        setTimeout("countdown(theyear,themonth,theday,thehour,theminute)", 1000);
    }
}

Add a file to the js directory called index.js and add the following code

document.addEventListener("DOMContentLoaded", function () {
    countdown(year, month, day, hour, minute);
}, false);

Back in index.html, add the following in between the <head> tags

<link rel="stylesheet" type="text/css" href="css/timer.css" />
<script src="js/timer.js"></script>
<script src="js/index.js"></script>

And add the following after the <img> tag which defines our table

<table id="table" border="0">
    <tr>
        <td align="center" colspan="6"><div class="numbers" id="count2" style="padding: 5px 0 0 0; "></div></td>
    </tr>
    <tr id="spacer1">
        <td align="center" ><div class="numbers" ></div></td>
        <td align="center" ><div class="numbers" id="dday"></div></td>
        <td align="center" ><div class="numbers" id="dhour"></div></td>
        <td align="center" ><div class="numbers" id="dmin"></div></td>
        <td align="center" ><div class="numbers" id="dsec"></div></td>
        <td align="center" ><div class="numbers" ></div></td>
    </tr>
    <tr id="spacer2">
        <td align="center" ><div class="title" ></div></td>
        <td align="center" ><div class="title" id="days">Days</div></td>
        <td align="center" ><div class="title" id="hours">Hours</div></td>
        <td align="center" ><div class="title" id="minutes">Minutes</div></td>
        <td align="center" ><div class="title" id="seconds">Seconds</div></td>
        <td align="center" ><div class="title" ></div></td>
    </tr>
</table>

Run the app and hopefully you’ll see a countdown timer as follows

finalImage

In the next few posts, I’ll follow up some polishing up of the app as well as how to support multiple resolutions in your application.


Warning: count(): Parameter must be an array or an object that implements Countable in /nfs/c07/h02/mnt/110221/domains/markarteaga.com/html/wp-includes/class-wp-comment-query.php on line 405