I’ve been playing around with using 2D transformations to enable 3D effects, even (or especially) in browsers without support for the latter. There have been a few examples of this kind—putting text and images and even video on isometric cubes, for the most part—but I think we, as a community, have not gone far enough in the pursuit of the hideous. I’m here to help.
This demo does border on abuse of the format—probably better done with SVG or not at all—but as an outputted, interactive image it (vaguely) suggests something important. Before a particular problem, before identifying the needs of our users, before creating elegant interfaces, and before good visual design, I believe we need to ensure the delivery of that first promise of techno-utopianism: putting whatever the hell we want to on the screen.
To be perfectly clear, all the things I listed first are far more important than that ability, but we shouldn’t be limited before we begin. Limits inspire creativity, but they also circumscribe what is possible; I want to be in charge of that. If I want a giant blinking triangle covering half my text, then by golly, there should be a giant blinking triangle there. Just because something shouldn’t be done doesn’t mean it shouldn’t be doable.
Browser interaction techniques have historically been so poor that we are still astounded when the simplest of interfaces match some intuitive sense of physicality. Luckily, things are changing. There is an increasing belief in a kind of manifest destiny for the web, the idea that we can make any kind of interface that we set our mind to, but we’re just now getting around to it (we might also have been waiting for the right local storage api).
Deluded or not, I’m of this mind as well, and I was interested in experimenting with the mechanics of interacting with three-dimensional objects, specifically through the web browser. All interfaces are abstractions and therefore lossy (surjective, if you’re into that), but the 2D interface to a 3D scene ends up serving two masters, since the whole point is to mimic a physical interaction through a mouse and keyboard. A qualitatively-optimized mapping still needs to be made between data and interface, something as expressive as possible within the parameters available, but here it has to not only convince us that those degrees of freedom are sufficient for the task at hand, it has to simultaneously match our sense of the way things actually move in the real world. Otherwise: frustration.
Which is all a long way of saying that most 3D interfaces are terrible. If it’s just decoration, fine, but if you’re trying to perfectly map a physical task to the mouse, you’re doing computers wrong, and if mouse movements relate inconsistently to what’s happening on screen, your users hate you.
This demo just plays around with some ideas—there is no real task to accomplish—but it’s easy to see where it is not entirely successful. However, meaningful criticism would require a program that was meant to do something, which this one wasn’t. I will say, though, that the technical side of things is easier than you might think. So embrace our collective destiny, don’t be afraid of creating the next blink tag or flash banner ad, and stop waiting for the perfect version of local storage.
Also, those native-app developers told me you guys look like dorks, so you’d better get on that.
While waiting for the WebGL promised land to arrive, I wanted a reliable way of making 3D transformations work at interactive rates across all the major browsers, even accounting for those aging software renderers. The process turns out to be pretty simple and without any real hacks; every frame created dynamically here can be recreated statically with some plain, vendor-prefixed CSS. Now, “real hacks” is relative—especially depending on how you feel about “-ms-filter”—and I don’t explicitly support IE versions prior to 8, but it’s a start.
The key is the orthographic projection, one way of projecting a three-dimensional scene onto a two-dimensional surface (in this case, the screen). Since orthographic projections map 3D parallel lines to 2D parallel lines, objects do not shrink as they recede from a viewer. This can cause a somewhat unsettling effect—a pretty cool testament to the sophistication of our visual system—but is also one more tool to be exploited by artists. In a nutshell, the animation system keeps track of the 3D transformations per element, then does a simple projection before applying it to that element’s style property. I’ll post more on the math and implementation details shortly.
I want to make the core feature set work across browsers as reliably as possible. If you have an issue, please let me know about it and the platform it happened on.
- Internet Explorer’s matrix filter has proven surprisingly stable and performant, but this demo appears to be pushing it to its limit. Transformations nested three or four deep, especially on elements with untransformed siblings, cause background colors to bleed through in some circumstances. This is not an issue in IE9 Preview 2.
- Unfortunately, the nested transform necessary for the recursive side is ignored altogether. This is not corrected in IE9. The transform is there, but unperformed, even though transforms nested within that transform are executed correctly. I’m hopeful that a knock in the right place will get it working.
- Like most of us, IE9 Preview 3 isn’t a big fan of filters and won’t run this. If filters are removed from IE9 permanently (when in standards mode) and CSS3 transforms are not added, I don’t believe there is a replacement.
- The Embedacube™ feature saves the state of the cube just before you press the button; press it again to save the state after the first press (but before the second press).
- An Embedacube™ cube currently only works in the browser version (Firefox, IE, etc) in which it was created.
- Some style information is currently lost in the Embedacube™ process.
- Safari on the Mac and Chromium on Windows (with startup flag) both support hardware accelerated 3D transforms. Unfortunately, this demo interacted with
-webkit-transform-style and the subsequent stacking order differently than I anticipated, so I’ve forced them back to 2D for now. Performance suffers a bit, but their software renderer is pretty good, especially for such a simple scene. I am investigating how deeply I have to change things in order to get accelerated 3D transforms working properly, and hope to have the change pushed soon.
- CSS transitions are another feature currently unused that should map well to this demo and provide a good performance boost.
- In a few tests, mobile performance on this page has been good. However, my testing equipment is limited, so touch events, for instance, are not currently acted upon.