Apple’s 2.0 iPhone update brought some interesting enhancements to Mobile Safari, including 3-D perspective and access to multitouch events. Armed with the documentation (of varying quality) from Apple’s Web Apps Dev Centre, and invaluable information from blog articles such as Idean’s “Spin the Bottle”, SitePen’s “Touching and Gesturing on the iPhone” and Paul Bakaus’s “3D CSS Transforms on the iPhone”, I put together a simple web app that displays a cubic panorama in Mobile Safari. Look left, right, up and down by dragging your finger across the display. No zoom, currently, though. It was pretty straightforward, but I did learn a few things while creating it.
Go ahead, take a look :D Visit http://tinyurl.com/iphonevr on your iPhone or iPod Touch.
The images used for the panorama are taken from one of the QuickTime VR movies in Apple’s Cubic VR gallery. I extracted the images from the movie using the procedure explained here (in French, but it’s easy to follow).
I may write a full tutorial on this eventually, but for now I will just share a few notes (and the source code):
- It’s a lot easier to get the 3-d transforms right if the elements you want to transform start out centred in their containing block (so that they start at (0, 0, 0), essentially). I did this with regular CSS, but I suppose this could also be done as part of the transform.
- The above also applies (especially) to any DIV that contains nothing but other DIVs. At first my cube was spinning around its top edge, instead of its centre, because its children (the cube faces) were absolute-positioned, and thus the “cube” DIV itself had no height! Giving it an explicit width and height solved this.
- Touch events on 3-D transformed elements seemed to be little bit unreliable. I worked around this by putting a normal transparent DIV on top of the whole thing and listened to events on that instead.
Download the source code (MIT Licence).
Wow! Crazy, man. Great job! And also, props for posting the source code!
Awesome!
Great job. It looks amazing. :)
I modified a little to run on Chrome browser in PC environment.
But it doesn’t seem work well as I want.
Just a single picutre rotating… sigh…
The following is my modification
function init()
{
rotY = 0;
rotX = 0;
hideUrlBar();
// touch events!
if (hasTouchEvent()) {
var e = document.getElementById(“controller”);
e.addEventListener(“touchstart”, startTouch);
e.addEventListener(“touchmove”, moveTouch);
e.addEventListener(“touchend”, endTouch);
e.addEventListener(“touchcancel”, cancelTouch);
}
else{
window.onmousemove = mouseMove;
window.onmousedown = mouseDown;
window.onmouseup = mouseUp;
}
var loadingE = document.getElementById(“loading”);
loadingE.parentNode.removeChild(loadingE);
}
function mouseDown(e)
{
activeTouchId = 1;
lastX = e.clientX;
lastY = e.clientY;
}
function mouseMove(e)
{
if(activeTouchId > 0)
{
rotateByTouch(lastX, lastY, e.clientX, e.clientY);
lastX = e.clientX;
lastY = e.clientY;
}
}
function mouseUp(e)
{
activeTouchId = 0;
}