Shortly after I posted the CSS 3D cube tutorial last week my friend Marlon jumped on the comments and suggested I create a mobile version. I played around with device orientation and JavaScript earlier in the year when me and Marlon were working together at Specialmoves so I presumed this is what he meant and it was a great idea!
I’ve now had a bit of time to put it together and created both an orientation version using the device accelerometer and also a touch event version (as whenever I showed someone the orientation one they tried to spin the cube with their finger!). Before you attempt to view the links you’ll need to be using either a tablet or mobile device and viewing in a browser that is WebKit powered as with the tutorial (iPhone, iPad and Android phones should be fine). Don’t start touching your computer monitor as nothing will happen (that was mostly for my Dad). 😉
Device accelerometer
First up the orientation version which can be view here. To get a device orientation via JavaScript is as simple as merely listening to an event.
window.addEventListener("orientationChanged", function(event) {
orientation = event.orientation;
}, true);
window.addEventListener("deviceorientation", function(event) {
// process event.alpha, event.beta and event.gamma
var x, y;
if(orientation == 0) x = event.beta;
else x = (orientation == 90) ? event.gamma : event.gamma * -1;
if(orientation == 0) y = event.gamma;
else y = (orientation == 90) ? event.beta : event.beta * -1;
$('.cube')[0].style.webkitTransform = "rotateX("+(x * -1)+"deg) rotateY("+(y * -1)+"deg)";
}, true);
The orientationChanged event is dispatched when the window changes from portrait to landscape and visa versa. deviceorientation then gives you the x / y / z orientation of the device.
Touch Events
Next we’ll look at the touch event version which can be viewed here. Again the code is pretty simple as shown below. I’m planning on writing a simple tutorial for touch events so hopefully should have that up soon.
var px = 0, py = 0;
var lastx, lasty;
document.addEventListener('touchstart', function(event) {
event.preventDefault();
var touch = event.touches[0];
lastx = touch.pageX;
lasty = touch.pageY;
}, false);
document.addEventListener('touchmove', function(event) {
event.preventDefault();
var touch = event.touches[0];
var mousex = touch.pageX;
var mousey = touch.pageY;
if(lastx !== mousex) vx = mousex - lastx;
if(lasty !== mousey) vy = mousey - lasty;
lastx = mousex;
lasty = mousey;
}, false);
function render() {
px += vx;
py += vy;
vx *= 0.9;
vy *= 0.9;
$('.cube')[0].style.webkitTransform = "rotateX("+px+"deg) rotateY("+py+"deg)";
}
setInterval(render, 50);
Finally I put them both together to create this version that utilizes both device orientation and touch events.
Thanks for the comment Jesse. I had the same conversation with a friend when I originally released this.
27 Feb 2013Great examination and work!
I do want to point out that when I view the cube, and I rotate the top of my device away from me, the bottom of the cube rotates away from me. I expected the behavior of the cube to match my phone. The same for using my finger: it felt like I was spinning the cube from the rear instead of the front face of it.
25 Feb 2013Looks like my MacBook has accelerometer as well. Works great.
7 Feb 2013New York is great thanks mate! Send me a link to your version. I’ve been playing around with three.js recently – really nice library!
31 Jul 2012Hi mate… I implemented something similar a while ago for my folio… also utilises webgl via three…
hope you’re enjoying the US
30 Jul 2012