HTML5 and JavaScript Continued – New Dev Environment & Animation

Continuing on from my basic getting started post, I want to continue covering some more basics of my HTML5 and JavaScript development.

Changing Development Environment

One thing before getting to the actual JavaScript, I wanted to highlight a change in my development environment. I previously said that I began with Notepad++ and then moved to the Visual Studio behemoth for my development needs. In the office, I moved to Sublime Text 2 for my day-to-day text (mostly non-code) editing based on over-the-shoulder previews of what it could do and a quick trial to get used to the look and feel.

A few days after making the change I heard about Sublime’s scriptability on twitter where some devs were using it to lint their Lua code. Other than the clean interface, syntax highlighting and code completion features, I wondered what Sublime’s scripting could do for streamlining my HTML and JS development workflow. I managed to find this post on the Sublime Text 2 forums which highlighted how to create a plugin that would load the current page in a browser. The only thing missing from this was how to save the current page before loading in a browser to avoid “I’m sure I just fixed that – why’s it not working!?!” syndrome.

This script is now bound to the F5 key in my Sublime and that’s massively improved my productivity. Here’s my version of the script (it’s Python so tabs are important but the blog may have scrambled them):

import sublime, sublime_plugin
import webbrowser
class OpenBrowserCommand(sublime_plugin.TextCommand):
 def run(self,edit):
  url = self.view.file_name()
  self.view.run_command('save');
  webbrowser.open_new(url)

and my key binding:

{ "keys": ["f5"], "command": "open_browser" }

Choosing a Framework

One other thing to note before I start was how I chose the framework that I’ve decided to use. For me, a lot of the fun of this development comes from finding things out for myself and learning new things. I understand the value of frameworks especially in the case of rapid development and wanting to get something to market, possibly on different platforms. Since that’s not my situation and I just want to learn and explore, I’m going to skip using a framework (although I’m keeping an eye on those that exist) and try and do as much as I can for myself.

Bring on the FPS

So back to coding and speaking of games, there was one FPS I wanted to look at before I got much further – Frames Per Second! I do know that FPS isn’t the best way to track performance, so I’ll include a millisecond time as well. All I really wanted was an initial figure to know when I’m not running at a playable speed (and I’ll worry about timing CrossFire/SLI performance when it comes to it). Basically if the refresh rate of a cleared screen on an iPad 2 couldn’t hit 60fps, then I was thinking I’d either have to give up or try something else.

Initially I thought if I couldn’t clear the screen each frame and redraw my scene, there was no other way to do it. Then I realized trying to clear a whole retina density display might not be the best way to go anyways. Since I come from a world of 16 milliseconds and change per frame, it’s difficult to twist my head around not redrawing the whole screen every frame where the only alternative is implementing something that selectively overdraws existing content rather than clearing and redrawing, and that’s a whole different mindset.

I started by creating the most simplistic FPS class that I could (all by myself! although it was several months ago now) which was my first use of  JavaScript classes. With the class written, I created  a simple test page that could give me an idea of performance when clearing the screen and rendering a couple of lines as fast as possible using setInterval() with a one millisecond interval. At that time, I ran that test in Chrome (which is my current weapon of choice for running my test pages). That was the only time I’ve really used setInterval() and the page updated at 80fps (not that I can remember the Chrome version number) .

Proper Animation in HTML5/JavaScript

The current wisdom is that for proper animation you should use requestAnimationFrame() to allow the browser to decide on the callback rate, rather than hardcoding an interval between frames. The best reference for requestAnimationFrame() I’ve found is http://paulirish.com/2011/requestanimationframe-for-smart-animating/ (with the draft spec here). Creating a new FPS test to use this highlighted a change in performance, then running at something like 120fps. This was so different that I’ve got two versions of the FPS Test page, one for setInterval() and another for requestAnimationFrame(). It made me smile that the explicit “run as fast you can” setInterval() version updates less frequently than the “run when allowed” requestAnimationFrame() version. (And just to note, I got similar results on Firefox). One other thing to note is the time taken between calls needs to be checked since requestAnimationFrame() will pause on inactive tabs (as mentioned here) so you may see large time deltas.

It was shortly after trying to use the animation delta to make the animation in my test app smooth that I re-read the requestAnimationFrame() pages and I realized that (according to the chromium dev design doc here) the animation shouldn’t go any faster than 60 FPS. At this point I discovered my first big ol’ bug which was that both my common startup code and per-test local startup code kicked off the draw() function which reregisters itself with requestAnimationFrame(). With 2 initial calls, the system was running 2 instances of draw, both of which were updating the FPS counter – schoolboy error. Once fixed, the requestAnimationFrame() code now runs at 60 FPS, effectively frame-locked. I can now see the value of something like setInterval() as something less vsync’d, for example if you want to get a better idea of performance use setInterval() but ship with requestAnimationFrame().

Next time

To be continued with more development and possibly even a little game next time…

Advertisements

Getting started with HTML5 canvas

YHTML?

The idea of looking at HTML programming came from watching my little 3-year-old playing on the iPad and wanting to make something he could play with and learn from. Although the target platform is iPad (and maybe iPhone) I’d prefer to iterate on PC which means I need a common technology to reuse between the two. As we all know, native iOS development requires a Mac, iPhone developer program membership and the time to learn and use Xcode – I know I haven’t really got the money for the first two and the patience for the third. If I was responsible for planning the iOS Safari roadmap, I’d have told everyone to implement WebGL for me so that I can stick with the 3D I know, but since they’re not mine to command, I’m going to have to go for a 2D solution.

Looking at the HTML5 tutorials, I like the look of the canvas element over the option of programming HTML that changes dynamically. I’ve not programmed HTML since University which would have been HTML4 or some such over 11 years ago. However targeting canvas means that once the HTML is written, the rest of it is just code. Well… by code I mean JavaScript code which is a language that I’ve not worked with before! That said, I’ve only heard good things about it and some of the things you can do with it amaze me!

Getting started

The first step was to create the HTML to encapsulate the canvas. Looking at the specification for canvas, you need to specify a pixel size for the canvas but with an onload script, you can update the size to what you want. My main aim is to develop something that maximizes the available space on the screen I’m working with, either on the PC or the iPad, so a fixed size isn’t a great place to start and I spent a lot of time looking for a solution (the one I found is in the resources list below).

Here’s the first working attempt, with the main features I wanted to demonstrate:

  • Minimal HTML5 page with a canvas and JavaScript code to draw to it.
  • Supports resize and orientation changing on PC and iOS (please run it on your iPad/Phone and rotate!).
  • Provides a 1:1 area for the application.

Long term plans

Looking forward to future areas for research, there’s several things I want to look at:

  • Find a good editor. I’m using Notepad++ but I typically write basic .txt files in it and not HTML or JavaScript, so I’d like something easier, or maybe just more familiar, but opening Visual Studio makes me feel like I’m using a tactical nuclear strike to crack this nut. That said, VS is my current go-to tool for editing since it’s what I use day-to-day. Something with VS’s text editing but better intellisense would be perfect.
  • Make some reusable modules, containing common code and reusable toys for future development.
  • Performance. I did read an article about poor performance with canvas on iPad, due to the number of pixels to fill but I can’t find the link any more. I can find a lot of pages discussing performance problems Safari versus everything else and timing graphs. First thing to do: write something to check frame rate.
  • Touch input. This is something to try and get working early since it makes a really good interface for experimentation. It’s going to be a pain that iteration will need to be on an iOS target for me, but the improved iteration time with Dropbox should help. And on a related note, I want to look at joystick input too.
  • Audio. This is a whole area of HTML5 and possible compatibility problems that I need to research to add depth to the applications I want to write.
  • CSS (Cascading Style Sheets). Most of the style related stuff that is required for the full screen behaviour is currently implemented in script so I’m not sure if I need CSS.
  • Creating a HTML5 application that you can download to your iPhone. Hopefully that will also allow me to use the full screen, rather than bordered within a browser.

Resources

Most of what I’ve achieved has been thanks to the wealth of tutorials on all the aspects of the canvas tag, HTML5 and most of all JavaScript. Here’s a list of all of the resources  I used: