I tried to kill it, officer, really
I was really looking forward to a Bones pic for this post. So I’m going to put one up anyway, because I’m stubborn like that.
The latest update of the HTML5 iPhone test app introduces touch events to the app. Yes sir, that’s right, the user now has an interface. Of sorts, anyway. The purpose of this update, and the reason why I thought it was going to allow me to blast the app into oblivion, was to add a new goblin token every time the user touched the screen and start sliding that token back and forth with all the tokens that have already been added. With the amount of JavaScript processing going on to move and render each individual token, I wondered if I’d be able to get 20 or so tokens moving before my iPhone 3GS started to show some serious stutter. Yeah, that didn’t happen.
At one hudred tokens, I finally got the iPhone rendering to drop below 50 FPS. At three hundred tokens, all animated to slide back and forth with every heartbeat tick, the FPS on the iPhone drops to 24FPS, but honestly if it wasn’t for the number printed at the top of the screen, I don’t think I would have realized it.
Now is probably also a good time to point out that on my desktop, I haven’t seen the slightest dip in FPS no matter how many tokens I add to the screen. You desktop HTML5 developers are in really, really good shape.
The extra code that I mentioned in the last update to make this piece a snap to add worked swimmingly. Thanks to the wonders of OO programming, pretty much all I needed to add to get hundreds of tokens rather than a single token was the following:
tenbyten.CanvasApp.prototype.touchStart = function(event){ var touch = event.changedTouches[0]; var token = new tenbyten.Token("images/token.png"); token.setCoordinates(touch.clientX , touch.clientY); this.tokens.push(token); event.preventDefault(); };
As an aside or three, in the process of adding the touch event, I learned a few tricks to getting an iPhone web application to behave more like a native application.
Trick the first: as soon as the app is loaded in the browser, call window.scrollTo to move the location bar out of the way. This both makes the screen look more like a native app with less of the browser UI in the way and provides your app with more precious screen space. Like so:
if(!window.navigator.standalone){ window.scrollTo(0, 1); }
Trick the second: did you catch that test for whether navigator was in standalone mode in there? If a user bookmarks your app and saves it to their home screen, several nifty features open up. 1) You can specify an icon and loading image for your app. 2) You don’t have any of the Safari UI in your way, granting you even more valuable screen real estate. 3) You can even cache all of your resources on the device so that even if the device goes offline, a user can still run your “web” app.
Trick the third: use event.preventDefault() to keep Safari from panning up and down as the user “drags” the canvas element up and down with their finger. Again, this allows your web app to behave more like a native app and gives you the opportunity to support drag events from the user across your canvas. Note: the only way I was able to disable the standard panning behavior when the app was running both within the browser and in standalone mode was to add a preventDefault() trigger to the body element in the HTML page:
<body ontouchmove="function(e){e.preventDefault();}">
At this point the web app is running strong and feeling an awful lot like a native application. I wasn’t sure when I started this project that this would be the result, and to be honest I’m thrilled with the results so far. So come on you HTML5 developers, lets see some apps for the iPhone!
Next step: multiplayer.
This is great reporting – thanks for writing this up!
I’m seriously impressed that the app behaved that well with that much processing going on.
Way to try and break it …. the tips for making HTML5 work like a native are inspiring. have you checked the difficulty factor of porting from native platforms to H5? or are we talking entire refactors?
If the bulk of your application is written in OpenGL, you’re in luck, since I believe the WebGL and OpenGL specs are similar though I haven’t explored them firsthand.
If your native app is mostly iOS calls, you have more work ahead of you as the core language of HTML5 is JavaScript, while the language for iOS devices is Objective C. Migrating from ObjectiveC to JavaScript is probably a decent chunk of work, I’m afraid.