# Test your maths skills at the MathDOJO!

Another productive weekend bares fruit for another mini game! This time I’ve put together a dojo-themed mini game whose sole purpose is to test your ability to do simple (well, mostly) arithmetic calculations in your head and your tolerance for my sense of humour (which is not so bad I hope ;-) ).

#### Screenshots

Here’s some screenshots taken from the game:

As you can see, the main game loop is simple: see some dialogue from your opponent, he asks a question, you answer, if you answer correctly within time then your opponent loses health point, when the opponent’s HP is depleted then you’ve defeated him and move onto the next opponent.

So far there’re 7 opponents in the game, each with his own set of dialogues and questions become progressively harder, your score is tracked and you can get a big bonus in score if you answer the questions quickly (and correctly of course!) and manage to string together a succession of correct answers! As the opponents become tougher, their questions will yield greater scores too, and not to mention they’ll be harder to beat as they have a higher HP value which means you have more chance to better your all-time top score!

#### Game Flow

Without going through all the steps of making the game (maybe I’ll do that at a later date), the basic flow of the game goes something like this:

The tricky thing is then how do you control this flow easily so that depending on the state you’re in the right action is triggered when the play presses the ENTER key.

In the end I settled for a mechanism where the DOM‘s onkeydown event is handled by this bit of code:

`   1: // hook up the onkeydown event to execute the 'next' action whatever it might be`

`   2: document.onkeydown = function(event) {`

`   3:     if (event.keyCode == 13) {`

`   4:         nextAction();`

`   5:     }`

`   6: };`

The nextAction variable is updated at each step of the game loop so that when the player presses the ENTER key the game does the right thing. The only deviation from this pattern is when I try to get the answer from a player, because there’s a time restriction on answering the questions I needed to set up a timer so that when it times out it’ll trigger the state transition as well.

#### Play

You can play the game at:

http://mathdojo.theburningmonk.com

http://LNK.by/fgzcu

Enjoy! Do let me know if you have any suggestions, difficulty level, etc. etc.

# Creating a count down meter with CSS3 and JQuery

Whilst working on the MathDOJO mini game one of the neat little things I tried to do was implement a time meter which steadily counts down and changes colour (from green to yellow to glowing red) as it approaches 0:

First, you need something to represent the meter, a simple <span> element will do:

`   1: <body>`

`   2:     <span id="count-down-meter"></span>`

`   3: </body>`

Then you need CSS to define its colour (and glow effect using CSS3 animation which for now, is only supported by webkit browser unfortunately) at different stages

`   1: /* define the animation (webkit-only) */`

`   2: @-webkit-keyframes redPulse`

`   3: {`

`   4:     from { -webkit-box-shadow: 0 0 9px #f00; }`

`   5:     50% { -webkit-box-shadow: 0 0 18px #f00; }`

`   6:     to { -webkit-box-shadow: 0 0 9px #f00; }`

`   7: }`

`   8:`

`   9: /* initial state of the meter */`

`  10: #count-down-meter`

`  11: {`

`  12:     display: block;`

`  13:     width: 100%;`

`  14:     height: 15px;`

`  15:     margin-top: 10px;`

`  16:     background-color: #0f0;`

`  17: }`

`  18:`

`  19: /* change color at midway */`

`  20: #count-down-meter.middle`

`  21: {`

`  22:     background-color: #ff0;`

`  23: }`

`  24:`

`  25: /* change colour and play animation when it's on its last leg */`

`  26: #count-down-meter.lastleg`

`  27: {`

`  28:     background-color: #f00;`

`  29:     -webkit-animation-name: redPulse;`

`  30:     -webkit-animation-duration: 2s;`

`  31:     -webkit-animation-iteration-count: infinite;`

`  32: }`

The animation itself is handled by Javascript, using JQuery’s animate method:

`   1: function start() {`

`   2:         // change to yellow when 40% way through`

`   3:     var midWidth = meter.width() * 0.6,`

`   4:         // change to glowing red when 70% way through`

`   5:         lastlegWidth = meter.width() * 0.3;`

`   6:`

`   7:     meter.animate({`

`   8:         width: 0 + "px",`

`   9:     }, {`

`  10:         duration: 5000,`

`  11:         easing: "linear",`

`  12:         step: function(now, fx) {`

`  13:             if (now <= midWidth) {`

`  14:                 meter.addClass("middle");`

`  15:`

`  16:                 if (now <= lastlegWidth) {`

`  17:                     meter.addClass("lastleg");`

`  18:                 }`

`  19:             }`

`  20:         }`

`  21:     });`

`  22: };`

To reset the state changes to the meter afterwards, it’s easiest to remove the “style” attribute as JQuery applies the changes through the “style” attribute, which can be a problem if you had manually inserted style in your HTML:

`   1: function reset() {`

`   2:     meter.stop()`

`   3:          .removeAttr("style")`

`   4:          .removeClass("middle")`

`   5:          .removeClass("lastleg");`

`   6: };`

Here’s a live demo:

So that’s it, nice and easy! Enjoy! Hope you find some good use for it.

# Creating a sticky note app with HTML5, CSS3 and Javascript

I saw this tutorial the other day, it’s cool but I fancied taking it a step further and make it useful as an app rather than just a fancy way to show some structured data on the screen. Here’s a list of the features which I wanted to add:

• being able to edit the title and content of the notes
• being able to save all your notes
• being able to add new notes
• being able to delete notes you no longer want
• randomize the colour of the notes more

#### HTML and CSS changes

I initially considered using the new contenteditable attribute in HTML5 to make the title and content editable, but settled on using textarea instead as it offers better support for multiple line text and you can easily add placeholder text as well as set a limit on the length of the title.

I added two images as buttons to add a new note and save the state of all the notes and put a a border around the notes to make them stand out a little more.

Here’s the updated HTML:

`   1: <body>`

`   2:     <div id="controls">`

`   3:         <img id="btnNew" src="images/newnote.png"/>`

`   4:         <img id="btnSave" src="images/save.png"/>`

`   5:     </div>`

`   6:`

`   7:     <ul id="notes">`

`   8:     </ul>`

`   9: </body>`

And the CSS to go along with it:

`   1: * {`

`   2:     maring: 0;`

`   3:     padding: 0;`

`   4: }`

`   5:`

`   6: .hide {`

`   7:     display: none;`

`   8: }`

`   9:`

`  10: body {`

`  11:     font-size: 100%;`

`  12:     margin: 15px;`

`  13:     background: #666;`

`  14:     color: #fff;`

`  15: }`

`  16:`

`  17: #controls img {`

`  18:     width: 28px;`

`  19:     height: 30px;`

`  20:     background: rgba(0, 0, 0, 0);`

`  21: }`

`  22:`

`  23: #controls img:hover, #controls img:focus {`

`  24:     -webkit-transform: scale(1.2);`

`  25:       -moz-transform: scale(1.2);`

`  26:       -o-transform: scale(1.2);`

`  27:       position:relative;`

`  28: }`

`  29:`

`  30: ul, li {`

`  31:     list-style: none;`

`  32: }`

`  33:`

`  34: ul {`

`  35:     overflow: hidden;`

`  36:     padding: 15px;`

`  37: }`

`  38:`

`  39: ul li {`

`  40:     margin: 15px;`

`  41:     float: left;`

`  42:     position: relative;`

`  43: }`

`  44:`

`  45: ul li div {`

`  46:     text-decoration: none;`

`  47:     color: #000;`

`  48:     background: #ffc;`

`  49:     display: block;`

`  50:     height: 150px;`

`  51:     width: 150px;`

`  52:     padding: 10px;`

`  53:     -moz-box-shadow: 5px 5px 7px rgba(33, 33, 33, 1);`

`  54:     -webkit-box-shadow: 5px 5px 7px  rgba(33, 33, 33, .7);`

`  55:     box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);`

`  56:     -moz-transition: -moz-transform .15s linear;`

`  57:     -o-transition: -o-transform .15s linear;`

`  58:     -webkit-transition: -webkit-transform .15s linear;`

`  59:     border-style: solid;`

`  60: }`

`  61:`

`  62: ul li div img {`

`  63:     padding: 1px 3px;`

`  64:     margin: 10px;`

`  65:     position: absolute;`

`  66:     top: 0;`

`  67:     right: 0;`

`  68: }`

`  69:`

`  70: ul li textarea {`

`  71:     font-family: 'Chewy', arial, sans-serif;`

`  72:     background: rgba(0, 0, 0, 0); /* transparent background */`

`  73:     resize: none;`

`  74:     padding: 3px;`

`  75:     border-style: none;`

`  76: }`

`  77:`

`  78: .note-title {`

`  79:     font-size: 140%;`

`  80:     font-weight: bold;`

`  81:     height: 30px;`

`  82:     width: 70%;`

`  83: }`

`  84:`

`  85: .note-content {`

`  86:     font-size:120%;`

`  87:     height: 100px;`

`  88:     width: 95%;`

`  89: }`

`  90:`

`  91: ul li:nth-child(even) div {`

`  92:   -o-transform:rotate(4deg);`

`  93:   -webkit-transform:rotate(4deg);`

`  94:   -moz-transform:rotate(4deg);`

`  95:   position:relative;`

`  96:   top:5px;`

`  97: }`

`  98:`

`  99: ul li:nth-child(3n) div {`

` 100:   -o-transform:rotate(-3deg);`

` 101:   -webkit-transform:rotate(-3deg);`

` 102:   -moz-transform:rotate(-3deg);`

` 103:   position:relative;`

` 104:   top:-5px;`

` 105: }`

` 106:`

` 107: ul li:nth-child(5n) div {`

` 108:   -o-transform:rotate(5deg);`

` 109:   -webkit-transform:rotate(5deg);`

` 110:   -moz-transform:rotate(5deg);`

` 111:   position:relative;`

` 112:   top:-10px;`

` 113: }`

` 114:`

` 115: ul li div:hover, ul li div:focus {`

` 116:   -moz-box-shadow:10px 10px 7px rgba(0,0,0,.7);`

` 117:   -webkit-box-shadow: 10px 10px 7px rgba(0,0,0,.7);`

` 118:   box-shadow:10px 10px 7px rgba(0,0,0,.7);`

` 119:   -webkit-transform: scale(1.25);`

` 120:   -moz-transform: scale(1.25);`

` 121:   -o-transform: scale(1.25);`

` 122:   position:relative;`

` 123:   z-index:5;`

` 124: }`

` 125:`

` 126: /* define 3 different colours for the notes */`

` 127: ul li div.colour1 {`

` 128:     background: #ffc;`

` 129: }`

` 130: ul li div.colour2 {`

` 131:     background: #cfc;`

` 132: }`

` 133: ul li div.colour3 {`

` 134:     background: #ccf;`

` 135: }`

There’s a couple of things to note here:

• the textarea element has a transparent background
• the textarea element is not resizable
• the textarea element has a placeholder text

Here’s what the page looks like now:

In the CSS above, you can see that I had defined three CSS class:

`   1: /* define 3 different colours for the notes */`

`   2: ul li div.colour1 {`

`   3:     background: #ffc;`

`   4: }`

`   5: ul li div.colour2 {`

`   6:     background: #cfc;`

`   7: }`

`   8: ul li div.colour3 {`

`   9:     background: #ccf;`

`  10: }`

when we create a new note, all we need to do to randomize its colour is to add one of these classes to the element randomly.

Here’s the event handler for the ‘new’ image button:

`   1: \$(document).ready(function() {`

`   2:     notes = \$("#notes"); // get references to the 'notes' list`

`   3:     ...`

`   4:     // clicking the 'New Note' button adds a new note to the list`

`   5:     \$("#btnNew").click(function() {`

`   6:         addNewNote();`

`   7:     });`

`   8:     ...`

`   9: });`

`  10:`

`  11: //  adds a new note to the 'notes' list`

`  12: function addNewNote(class, title, content) {`

`  13:     // if class is not specified, use a random colour class`

`  14:     if (!class) {`

`  15:         class = "colour" + Math.ceil(Math.random() * 3);`

`  16:     }`

`  17:`

`  18:     // add a new note to the end of the list`

`  19:     notes.append("<li><div class='" + class + "'>" +`

`  20:                  "<textarea class='note-title' placeholder='Untitled' maxlength='10'/>" +`

`  21:                  "<textarea class='note-content' placeholder='Your content here'/>" +`

`  22:                  "<img class='hide' src='images/close.png'/>" +`

`  23:                  "</div></li>");`

`  24:`

`  25:     // get the new note that's just been added and attach the click event handler to its close button`

`  26:     var newNote = notes.find("li:last");`

`  27:     newNote.find("img").click(function() {`

`  28:         newNote.remove();`

`  29:     });`

`  30:`

`  31:     // hook up event handlers to show/hide close button as appropriate`

`  32:     addNoteEvent(newNote);`

`  33:`

`  34:     // if a title is provided then set the title of the new note`

`  35:     if (title) {`

`  36:         // get the title textarea element and set its value`

`  37:         newNote.find("textarea.note-title").val(title);`

`  38:     }`

`  39:`

`  40:     // if a content is provided then set the content of the new note`

`  41:     if (content) {`

`  42:         // get the content textarea element and set its value`

`  43:         newNote.find("textarea.note-content").val(content);`

`  44:     }`

`  45: }`

`  46:`

`  47: function addNoteEvent(noteElement) {`

`  48:     noteElement.focus(function () {`

`  49:         \$(this).find(".img").removeClass("hide");`

`  50:     }).hover(function() {`

`  51:         \$(this).find("img").removeClass("hide");`

`  52:     }, function () {`

`  53:         \$(this).find("img").addClass("hide");`

`  54:     });`

`  55: }`

as you can see, this event handler calls the addNewNote function which is responsible for adding a new note to the notes unordered list and sets its class, title or content depending on the arguments. In this particular usage it’ll pick one of the three colour classes randomly and add the class to the new note.

Once a note has been added, I then get a reference to it and create an event handler for its close button so that when its clicked it’ll remove this note from the DOM.

The addNoteEvent function is then charged with adding the focus and hover in/out event handlers to the note to show and hide the close button so that it’s only shown when the note is focused/hovered on.

Saving the notes

I have previously cover the use of HTML5’s local and session storage in this post already, what I’m doing here is very similar but a little more involved.

When the ‘save’ button is clicked, I need to inspect each of the notes and remember the class, title text (remember, you can’t get the text that’s been entered into the textarea by getting the HTML of the element) and content text in a bespoke object, the resulting array of objects is then JSON serialized using Douglas Crockford‘s Json.js library. It this is JSON string that’s saved into the local storage.

On the other end, when the page has been loaded and the DOM event fired (i.e. when JQuery.ready fires) I will need to check if the JSON string is in the local storage, if it is, then deserialize the string back to an object array and add the notes back in in the same order:

`   1: var notes;`

`   2: var count = 0;`

`   3:`

`   4: \$(document).ready(function() {`

`   5:     notes = \$("#notes"); // get references to the 'notes' list`

`   6:`

`   7:     // load notes from local storage if one's available`

`   8:     var storedNotes = localStorage.getItem("notes");`

`   9:     if (storedNotes)`

`  10:     {`

`  11:         // passes the stored json back into an array of note objects`

`  12:         var notesArray = JSON.parse(storedNotes);`

`  13:         count = notesArray.length;`

`  14:`

`  15:         for (var i = 0; i < count; i++) {`

`  16:             var storedNote = notesArray[i];`

`  17:             addNewNote(storedNote.Class, storedNote.Title, storedNote.Content);`

`  18:         }`

`  19:     }`

`  20:`

`  21:     ...`

`  22:`

`  23:     // clicking the 'Save' button saves the state of the notes board to the local storage                `

`  24:     \$("#btnSave").click(function() {`

`  25:         var notesArray = new Array();`

`  26:`

`  27:         // for each of the notes add a bespoke note object to the array`

`  28:         notes.find("li > div").each(function (i, e) {`

`  29:             // save the class attribute of the div, as well as the text for the title and content text areas`

`  30:             var colourClass = \$(e).attr("class");`

`  31:             var title = \$(e).find("textarea.note-title");`

`  32:             var content = \$(e).find("textarea.note-content");`

`  33:`

`  34:             notesArray.push({ Index: i, Title: title.val(), Content: content.val(), Class: colourClass });`

`  35:         });`

`  36:`

`  37:         // json encode it`

`  38:         var jsonStr = JSON.stringify(notesArray);`

`  39:`

`  40:         // and save the json string into local storage`

`  41:         localStorage.setItem("notes", jsonStr);`

`  42:`

`  43:         // info the user it's done`

`  44:         alert("Notes saved");`

`  45:     });`

`  46:`

`  47:     // add a note to the list if there aren't any`

`  48:     if (count == 0)`

`  49:     {`

`  50:         \$("#btnNew").click();`

`  51:     }`

`  52: });`

#### Demo

You can try out the full demo at:

http://stickynote.theburningmonk.com

http://LNK.by/fhbba

Enjoy!

#### UPDATE 27/02/2011:

Thanks to Joey Beechey for pointing out to me in the comment that the demo doesn’t work in Safari and after a bit of digging I found that the problem is with the addNewNote function which has a parameter named ‘class‘ which is a reserved word. I found another reference of this problem here too, which mentions the same problem but with the variable name ‘abstract‘ instead!

I’ve also put the whole thing into a zip file which you can download from here, so feel free to play around with it yourself!

#### References:

Douglas Crockford’s JSON-js project on github

John Resig’s blog post which includes some handy examples on how to use the JSON-js library

Original tutorial which inspired this blog post

# Having fun with CSS3 – Box Shadow property

CSS3 introduces a useful little property called box-shadow, which as the name suggests adds a shadow to an element.

You can create a basic box shadow like this:

```div {
-webkit-box-shadow: 10px 20px #000;  /* for Chrome */
-moz-box-shadow: 10px 20px #000;  /* for Firefox */
}
```

This casts a shadow with an X-offset of 10 pixels and a Y-offset of 20 pixels:

You can equally use negative values for the offsets, which will simply cast the shadow onto the other side of the element:

```div {
-webkit-box-shadow: –10px -20px #000;  /* for Chrome */
-moz-box-shadow: -10px -20px #000;  /* for Firefox */
}
```

You might have noticed the use of vendor prefixes (-webkit for Chrome and –moz for Firefox), the reason for this is described in my post about the border radius here.

To make the shadow look more realistic, you can blur the shadow by supplying an additional parameter:

```div {
-webkit-box-shadow: 10px 20px 10px #000;  /* for Chrome */
-moz-box-shadow: 10px 20px 10px #000;  /* for Firefox */
}
```

The higher the number of pixels the more pronounced the effect of the blur is.

What’s more? You can add opacity to the shadow to make the shadow semi-transparent, to do this in CSS3 is simple as it introduces a new rgba function which you can use to specify the colour of the shadow. Most of you should be familiar with how RGBa works (a stands for alpha which is a value between 0 and 1 with 0 being fully transparent and 1 being fully opaque) already and to use it on a shadow here’s what you can do:

```div {
-webkit-box-shadow: 10px 20px 10px rgba(0, 0, 0, 0.4);  /* for Chrome */
-moz-box-shadow: 10px 20px 10px rgba(0, 0, 0, 0.4);  /* for Chrome */
}
```

Compare the two images below, using solid colour on the left and using RGBa function with alpha value of 0.4 on the right:

As you can see, the shadow on the right look a lot more believable!

```div {
-webkit-box-shadow: 10px 20px 10px rgba(0, 0, 0, 0.4),
-10px 20px 10px rgba(100, 0, 0, 0.4);
-moz-box-shadow: 10px 20px 10px rgba(0, 0, 0, 0.4),
-10px 20px 10px rgba(100, 0, 0, 0.4);
}
```

```div {
-webkit-box-shadow: inset 10px 20px 10px rgba(0, 0, 0, 0.4);  /* for Chrome */
-moz-box-shadow: inset 10px 20px 10px rgba(0, 0, 0, 0.4);  /* for Firefox */
}
```

You could create multiple inner shadows, though the effect tend to be a little strange if you ask me..:

```div {
-webkit-box-shadow: inset 10px 20px 10px rgba(0, 0, 0, 0.4),
inset -10px -20px 10px rgba(0, 0, 150, 0.6);
-moz-box-shadow: inset 10px 20px 10px rgba(0, 0, 0, 0.4),
inset -10px -20px 10px rgba(0, 0, 150, 0.6);
}
```

```div {
-webkit-box-shadow: inset 10px 20px 10px rgba(0, 0, 0, 0.4),
10px 20px 10px rgba(0, 0, 150, 0.6);
-moz-box-shadow: inset 10px 20px 10px rgba(0, 0, 0, 0.4),
10px 20px 10px rgba(0, 0, 150, 0.6);
}
```

again, doesn’t feel quite right…

```div {
-webkit-box-shadow: 10px 20px 0px 10px #000;  /* for Chrome */
-moz-box-shadow: 10px 20px 0px 10px #000;  /* for Firefox */
}
```

Compare these two images, one with spread of 10 pixels (left) and one without:

#### Demo

Finally, here’s a quick demo page I’ve put together to let you play around with the box-shadow property and see its effects as you change the relevant parameters, note it only works with webkit browsers (Safari and Chrome) for now as I’m using the new range type input in HTML5 which is not yet supported in Firefox and iE.

# Having fun with CSS3 – Border Radius

As you may know already, CSS3 has introduced a new set of properties which allows you to easily add curved corners to a box.

#### Simple round corners

You can create a div with round corners with this simple css:

```div {
}
```

However, given the stage of development CSS3 is at as of now this is only supported by Google Chrome… Instead, you are encouraged to add vendor prefixes :

```div {
-webkit-border-radius: 50px; /* for Chrome */
-moz-border-radius: 50px; /* for Firefox */
}
```

How much of a curve the corners get is worked out by placing an imaginary circle of a radius of the given number of pixels at each of the corners (see image below):

Naturally this introduces an interesting edge condition – what if the radius of the imaginary circles is set to be equal to or greater than half of the width of a square-shaped element? Do we just get a circle back?

Yes.

#### Specify different radius for each corner

You can specify a different radius for each of the top-left, top-right, bottom-right and bottom-left corners either like this:

```div {
/* for Chrome */

/* for Firefox */
}
```

Note: the property names are different!

Or using the short-hand syntax by listing 4 consecutive values for each of the four corners in the above mentioned order:

```div {
-webkit-border-radius: 40px 10px 80px 20px;  /* for Chrome */
-moz-border-radius: 40px 10px 80px 20px;  /* for Firefox */
}
```

both will produce the same result:

#### Oval-shaped corners

You don’t have to be content with circular-shaped corners either, to specify an oval-shaped corner, just use this syntax:

```div {
-webkit-border-radius: 80px / 40px;  /* for Chrome */
-moz-border-radius: 80px / 40px;  /* for Firefox */
}
```

The only thing we’re doing differently now is that we’re putting an oval as opposed to a perfect circle into the corners. The oval is defined by a width and height:

And once more, you can specify these for each corner by setting separate properties:

```div {
/* for Chrome */

/* for Firefox */