Posts in Category "JavaScript"

April 19, 2012

Building the Keyboard from TRON Legacy with Web Technologies

I recently re-watched TRON: Legacy, and after the scene where Sam types a few Unix commands on a virtual keyboard, I decided I had to try one out for myself. In addition to wanting to see what it was like to use a virtual keyboard, I also wanted to see if I could build it entirely with web technologies. I discovered I was able to do everything I wanted — except type particularly well.

Below is an explanation of the project (along with some conclusions on virtual keyboards in general). All the source code for the project is available on GitHub.


4:34 PM Comments (2) Permalink
March 29, 2012

HTML Animation with requestAnimationFrame and Flash Professional CS6

If you’re curious about the new requestAnimationFrame API, here’s a demo along with a code walk-through:

The requestAnimationFrame API is a replacement for setTimeout and setInterval in the context of HTML animations. It has two primary advantages over timer functions:

  1. It is synchronized with the browser’s repaint loop which allows for more highly optimized animations.
  2. Since it’s specifically designed and intended to be used for animation rather than being a general purpose timer, the browser knows that it’s safe to throttle it back when the tab isn’t active. Throttling back animations means freeing up CPU cycles, and reducing unnecessary battery drain on mobile devices.

If you want to see this animation in action (and/or check out the code), it’s available here (Hint: if it’s running slowly, try making your browser window smaller). Thanks to Chris Georgenes for the “rocker girl” animation. And finally, here are the resources I used to learn about requestAnimationFrame:

Continue reading…

2:54 PM Comments (0) Permalink
March 22, 2012

A Short Simple Video Explaining the Shadow DOM and Web Components

I’ve been playing around with the shadow DOM and web components, so I thought I’d put together a quick video explaining the advantages:


You can starting experimenting with these concepts today using Chrome Canary. Just make sure you enable the Shadow DOM and scoped style flags by typing “chrome://flags” into your location bar:

If you want to learn more about the shadow DOM and web components, here are the resources I used:

2:56 PM Comments (0) Permalink
March 20, 2012

Accessing the Accelerometer and Gyroscope in JavaScript

Now that you can access motion sensors in both Google Chrome and mobile browsers, I decided to demo a couple of sample application which hook into the accelerometer and gyroscope:


If you want to see these applications in action and/or check out the code, the links are below:

Note that the compass application only works on devices with gyroscopes (no laptops that I know if), and requires iOS 5 or newer.

1:33 PM Comments (3) Permalink
March 15, 2012

Mouse Pointer Lock in HTML: Video and Sample Code

After watching Paul Irish’s talk at SXSW, I got curious about the new pointer lock APIs in Chrome and decided to create a sample application. Pointer lock refers to the ability to lock the mouse pointer in one location and hide it while still getting certain mouse events like mousemove. This is critical for immersive experiences like games since the user wants to be able to use the mouse to navigate, but doesn’t want the pointer to move off the screen or get in the way.

It’s still early days for navigator.webkitPointer, but I was able to get something to work with Chrome Canary. First, a video demo, then some explanation:


If you want to try the demo firsthand (and maybe experiment with the pointer lock APIs yourself), you can find the code here. But first, you need to follow these steps:

  1. Download Chrome Canary.
  2. Enable pointer lock:
    1. Type "chrome://flags" into your location bar.
    2. Scroll down to "Enable Pointer Lock Mac, Windows, Linux, Chrome OS".
    3. Click "Enable".
    4. Click the "Relaunch Now" button at the bottom to relaunch Chrome Canary.
  3. Allow sites to disable the mouse cursor:
    1. Open settings.
    2. Click "Show advanced settings…".
    3. Click "Content settings…"
    4. Scroll down to the "Mouse Cursor" section.
    5. Select "Allow all sites to disable the mouse cursor". In theory, you should be able to select "Ask me when a site tries to disable the mouse cursor (recommended)," however this isn’t working for me right now (remember: still early days).

Currently, you can only lock the mouse pointer in Chrome while in fullscreen mode. Here’s the relevant code:

document.addEventListener('webkitfullscreenchange', onFullscreenChange, false);

function onFullscreen(event) {
    document.body.webkitRequestFullScreen();
}

function onFullscreenChange(event) {
    if (document.webkitIsFullScreen) {
        id('fullscreenButton').style.display = 'none';
        if (navigator.webkitPointer) navigator.webkitPointer.lock(document.body);
    } else {
        if (navigator.webkitPointer) navigator.webkitPointer.unlock();
        id('fullscreenButton').style.display = 'block';
    }
}

Remember that you have to handle mouse coordinates differently when the pointer is locked versus when the pointer is visible. When it’s locked, even though you can’t see the mouse cursor, it’s actually frozen in one location so it can’t be moved out of the window or onto another monitor which means properties on MouseEvent like clientX and clientY are useless. Instead, you can use properties like webkitMovementX and webkitMovementY that tell you how much (and in which direction) the mouse is being moved as opposed to the location of the mouse cursor. Below is the relevant code from the sample application:

var lastMouse;

function onMouseMove(event) {
    var xDelta, yDelta;
    if (navigator.webkitPointer && navigator.webkitPointer.isLocked) {
        xDelta = event.webkitMovementX;
        yDelta = event.webkitMovementY;
    } else {
        if (lastMouse == null) lastMouse = {x:event.clientX, y:event.clientY};
        xDelta = event.clientX - lastMouse.x;
        yDelta = event.clientY - lastMouse.y;
    }
}

12:18 PM Comments (2) Permalink
February 20, 2012

Prototyping in HTML


Over the weekend, I built an e-book reader prototype to demonstrate some ideas that might make the digital book reading experience better. Although I was prototyping a native application, I found the easiest way to build it was with HTML, JavaScript, and CSS. Once CSS regions make it into all mobile browsers, I might put some more time into this concept and build a real browser-based e-book reader (that works exactly how I want it to).

2:19 PM Comments (3) Permalink
February 13, 2012

CSS Regions: What’s Possible Now, and What’s Coming


I just made a quick screencast to show the current state of CSS Regions, and to demonstrate some new capabilities that will be here soon. In general, there are two aspects to CSS Regions:

  1. The ability to have text automatically flow between regions.
  2. The ability to hook into that flow using JavaScript in order to create more dynamic layouts.

If you use Chrome (Adobe’s work on CSS Regions is in WebKit which Chrome uses), you can go ahead and see text flow already working (including Chrome for Android). Other browsers have already committed to supporting CSS Regions, and we should know more about when their implementations will land soon. Let me know below if you have any comments or questions.

10:01 PM Comments (7) Permalink
February 3, 2012

Setting Text Selection Colors in JavaScript

If you’re building any kind of a text editor in JavaScript, you might want to be able to dynamically set or change the text selection color. I discovered it wasn’t as easy to do as I expected it to be, so I thought I’d share the code. I created this extreme (and admittedly, somewhat obnoxious) example showing the selection color changing as the mouse moves, but the core of the code is something like this:

var ss = document.styleSheets[0];
ss.insertRule('#content::selection {color: #'+
              newForegroundColor+'; background: #'+
              newBackgroundColor+';}', 0);

Note that I only tested this code in Chrome and Safari (I’m only targeting WebKit browsers for now), however it can work with Firefox with the correct "moz" prefixed style name. I haven’t yet tested or investigated IE.

If you know another way of changing text selection properties in JavaScript, let me know.

4:18 PM Comments (2) Permalink
January 31, 2012

How to Create a Custom File Input (For Use With the HTML5 File APIs)

I’m working on an HTML/JS application that lets users work with local files directly in the browser, and I’m using some new HTML5 APIs to access local files. It works great (in Chrome and Firefox, anyway — see note below), however my UI calls for a custom file input rather than the default (and usually pretty ugly) button-and-path input. Fortunately, customization is easy in this case. The trick is to create your own UI treatment (in my case, just a link), then use the click() function on a hidden file input to bring up the file dialog.

In Firefox, you can use the display:none style as noted in this Mozilla Developer Network documentation, however this won’t work in Chrome or Safari (although FileReader is currently not supported in Safari, you might as well think ahead for when it is). A better way of doing it, therefore, is to use visibility:hidden.

The only problem is that when something is hidden using its visibility property, it’s still actually in the DOM, and space is therefore allocated for it even though you can’t see it. If you want to get your file input completely out of the way, therefore, you can use something like this:

<input type="file" id="fileInput" onchange="handleFiles(this.files)" style="visibility:hidden;position:absolute;top:-50;left:-50"/>

Your file input will still be in the DOM (even though it’s hidden and off-screen), however it won’t take up any visual space.

Here’s the full HTML code:

<a href="javascript:onLoad();">Load a File!</a>
<input type="file" id="fileInput" onchange="handleFiles(this.files)" style="visibility:hidden;position:absolute;top:-50;left:-50"/>

And here’s the JavaScript code:

function onLoad() {
    id('fileInput').click();
}

function handleFiles(files) {
    var file = files[0];
    var reader = new FileReader();
    reader.onload = onFileReadComplete;
    reader.readAsText(file);
}

function onFileReadComplete(event) {
  // Do something fun with your file contents.
}

Note that this code is only going to work in current versions of Chrome and Firefox, but is expected to work in future versions of IE (10) and Safari (6).

7:42 PM Comments (1) Permalink
January 27, 2012

How to Download Data as a File From JavaScript

I’m currently working on an HTML/JavaScript application that allows you to author content entirely on the client. I want to let users download that content and save it locally, but without bouncing it off a server. After some trial and error, I have it working fairly well using a data URI. Rather than explain it, it’s probably easiest just to show the code:

HTML:

<a href="javascript:onDownload();">Download</a>

JavaScript code:

function onDownload() {
    document.location = 'data:Application/octet-stream,' +
                         encodeURIComponent(dataToDownload);
}

The only limitation is that I can’t figure out a way to give the downloaded file a name (and have concluded that it’s not currently possible, though I’m happy to be proven wrong). I’ve only tested the code in Safari and Chrome, and in both cases, the file name defaults to "download" (with no extension). All the data is in the file, but it’s not a very intuitive experience for the end user.

I’ll be releasing the application shortly which should demonstrate why downloading data directly from the client can be useful. In the meantime, I’m curious if this is something any of you might use, and if so, if you think the file name issue should be fixed.

Let me know in the comments.

5:36 PM Comments (9) Permalink