DOMless inputs with HTML5 canvas

Below is a form that doesn’t use any <input> tags, and no DOM elements other than <canvas>.

TLDR; GitHub Link

It’s not often that I’m programming and have to do something that hasn’t been done in some fashion or another in the language I’m working with. However, the other day I came across one of those issues: trying to get user input *without* having access to the DOM. Not having the DOM available means no simple <input>. Sure, I could just use a prompt(), but that isn’t as pretty to use. The solution was to build the equivalent of an <input> just using the <canvas> element.

Let me explain why I was able to use <canvas> and not <input>, and why I even did this in the first place…

I initially created this for Clay.io - for those reading this blog from outside sources like HackerNews, Clay.io is a platform for HTML5 games. We offer an API for game developers to implement features like high scores, achievements, data storage, payment processing, etc. in their HTML5 games. See our developer page for more info on that…

There are a few services (CocoonJS and AppMobi notably) that boost performance of <canvas> for HTML5 games on mobile devices by eliminating the DOM completely, so we needed to develop a version of our API that plays nicely without the DOM. Despite making our API “DOMless”, we still needed a way to allow users to login and signup so their achievements, high scores and persistant data could be associated with their account.

Another use-case for this might be to eliminate spammers without use of a captcha. At least at this point in time, they’re not going to catch onto the fact that you are using ‘fake’ inputs in a <canvas> rather than using <input>s, and won’t be able to insert of a bunch of junk.

The library works by creative use of drawRect’s and attaching keydown, click and mousemove events to the canvas. Your best bet for understanding is to have a look at the code

I figured this might be of use to other developers, so I made it into an external library that can be found on GitHub. Do with it what you want, if you’re feeling ambitious you could even fork it and implement radio buttons, checkboxes, etc…

The basic format for creating inputs is:

// text field
new CanvasText( canvas, {
    x: 'center',
    y: 120,
    width: 300,
    placeholder: 'Enter your username...'
} );
// password field
new CanvasPassword( canvas, {
    x: 'center',
    y: 155,
    width: 300,
    placeholder: 'Enter your password...'
} );
// Submit button
new CanvasSubmit( canvas, {
    x: 'center',
    y: 195,
    width: 300,
    placeholder: 'Submit',
    onSubmit: ( function() {
        return alert( 'Submit button pressed' );
    } )
} );

One of the issues I ran into was, “how do I pull up the keyboard?”. There’s no way to do it with just JavaScript, so this implementation has a couple of options. If you’re on a desktop with a keyboard plugged in, it doesn’t matter, and doesn’t try to pull up a keyboard. For mobile devices, CocoonJS comes packaged with a canvas-drawn keyboard, so that is used if CocoonJS is available. If not, the library checks if the DOM exists anyways, and creates a hidden input and focuses on it to bring up the keyboard. The final fallback if none of that exists is to bring up a prompt() when the input is clicked, and the field is filled once saved. 

Be sure to checkout the GitHub repo and another demo based on the code above here. If you’re interested in HTML5 games, why not go ahead and signup for Clay.io in the form at the top of this post? We’re trying to become the Steam for HTML5 games!

Posted in Uncategorized | Tagged | 7 Comments
  • Davidweberza

    Great stuff!

  • Richard Mitchell

    It’d be great if I could paste into the fields, too. Using my current password manager, I would have to open the record, show the password and type it in character by character.

  • david berneda

    Nice job ! Another idea you can implement (we did for our charting library) is a domless Slider control:http://www.steema.com/files/public/teechart/html5/v2012.06.1.1/demos/extra/sl

  • Yoann

    Pretty neat.Working in all browsers accepting canvas ?

  • Austin Hallock

    @Richard – for what we’re using it for we don’t need paste, but anyone is welcome to fork the repo and add features :) @Yoann – Yep

  • duane_moody

    My email address has an underscore in it. Let me know when that’s not a problem for your framework.

  • Mike

    Nice! Ran into problems in chrome on my HTC OneX though. The phones keyboard popped up but every keypress added an “â”.