This demo and blog post almost didn’t see the light of day. The Web has produced impressive 3D apps recently (example) and my concept seemed unremarkable compared to them. But after thinking about it for some time I realized I had built a Hello World example and it’s not fair to compare it to other apps. And my Hello World packs some interesting features too.
I recommend opening the link on a phone or a tablet. I tested it in Chrome and Safari, so it should work on all newer Android and iOS devices. It will also work on desktop browsers, but you’ll have to start the animation manually.
If it got you interested, read on about my motivation and the technology used to build it.
WebGL support is improving daily and our mobile devices are more powerful than our desktop computers from a couple of years ago. All of this rekindled my passion for computer graphics. At the university I took all available computer graphics and virtual reality classes. There weren’t as many as I wanted, but I had the opportunity to play with OpenGL and C among other things.
I had found a WebGL course on Coursera and decided I’ll use it as a paced refresher. During the whole summer I was watching lectures and doing homework in my off-work hours. It was like being in school again–working and studying at the same time.
I passed the course mid-September last year. I built some interesting things for assignments, but couldn’t share them due to Coursera’s restrictions; future course students might use them as their own submissions. At the same time, I wanted to build something for mobile. At concat in March 2015, Franzisca Hinkelmann demonstrated new and interesting web APIs. One of them was device orientation and it just stuck in my mind.
It is not a surprise my first idea was to build something in WebGL that would react to rotation of a mobile device. I coded the concept in early fall, but had to leave it unfinished due to travel and work. Winter holidays came to the rescue. One long weekend later and the cube was ready.
WebGL is the star of the show. It’s a flavor of OpenGL, “first created as an open and reproducable alternative to Iris GL which had been the proprietary graphics API on Silicon Graphics workstations” (source). In short: old. It’s close to hardware and operates with global states, and that makes it hard to wrap your head around because it’s so different from modern application development.
One resource I highly recommend is WebGL Fundamentals. It’s a series of almost thirty in-depth articles with clear explanations, code examples, and visualizations.
Detecting device orientation is critical for this concept and fortunately not complex. An event listener is added to deviceorientation if supported and the event returns three angles which define the physical device in space.
The biggest problem is inconsistency; different browser makers return different ranges for angles, so the cube might rotate in different directions if viewed in two different browsers.
MDN docs should be more than enough to start with device orientation.
One tip to keep in mind: even desktop browsers support this, so it’s a not good indicator that someone is browsing on a mobile device.
The last thing I needed was to detect the screen orientation change. I needed that for two reasons:
- If I rotate a device to the side, my “up” and device’s “up” don’t match anymore, so I need to read different angles. To make things worse, I can rotate the device to left or right.
- I wanted to make the cube always fully visible on the screen so I needed to resize the drawing canvas.
In the end I settled on something quick and dirty–I’m listening to resize event and checking if the viewport ratio changed. It’s not flawless and will break in some cases, but does two things at the same time:
- Handles resizing of desktop browsers.
- Mobile browsers, for now, change their viewport ratios only when rotated. We’ll see how it’ll work out with split pane functionality some tablets will support in the future.
And that’s all there is to it. Now go and create something.