Archive for March, 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…

Stop Using “rm” on the Command Line (Before It’s Too Late)

True story…

While writing a Python script one day to do a little screen scraping and reporting, the topic of data loss came up between a friend and myself. I was bragging that I had never in my life accidentally lost a single file or piece of data that I wasn’t able to recover. Literally seconds later, while intending to rename my script using “mv”, I accidentally typed “rm” instead and deleted it.

That was just about the last time I used “rm”. I now use a script which, for no particular reason, I call “rr”. Rather than deleting files and/or directories, it moves them to the trash where they can be easily recovered if necessary. Here’s the script itself (configured to work on OS X):

#!/bin/bash

if test $1
then
    mv $1 ~/.Trash/
fi


Just make the script executable (chmod 755 rr), drop it in your path, and forget “rm” ever existed.

As always, there are several other ways of doing this (remapping “rm”, making an alias, using the Finder, etc.), so pick the way that works best for you. The important thing is to keep yourself from losing hours of work on the command line like I did.

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 check out the code used in this example, you can download it here.

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

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.

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;
    }
}

The Next Step in Mobile HTML Workflows

If you do a lot of mobile web development, you might want to check out Adobe Shadow. Shadow is a way to easily push web content from your desktop to any number of mobile devices while you’re developing or testing so you don’t have to type in cumbersome URLs and keep refreshing. Additionally, Shadow allows you to debug and inspect web content running in your iOS or Android browser.

Adobe Shadow is now available on Labs. If you want to see it in action, check out the “sneak peek” below:


Also, you can check out an early prototype I built around these concepts after doing enough mobile web development that the workflow was really starting to bug me. In my opinion, the Shadow team really nailed it.