Wednesday, April 21st, 2010

Implementing 3d video navigation carousel a la iAds

Category: CSS

The video above isn’t from Steve Jobs’ keynote, but is by Ted Littledale. He created a 3d navigation carousel that mimics the iAds demo that Steve gave:

I used the webkit team’s morphing cube example as my starting point as that showed how to get a bunch of flat elements arranged as a 3d ring. I just created a function to add the 3d transform to each li dynamically rather than in the css file:

javascript

  1. jAd.createRing = function(){
  2.     var items = shape.getElementsByTagName('li');
  3.     var angle = 360 / items.length, newAngle;
  4.     for(var i = 0, l = items.length; i < l; i++){
  5.         newAngle = (angle * i);
  6.         var matrix = new WebKitCSSMatrix();
  7.         items[i].style.webkitTransform  = matrix.rotate(newAngle, 0, 0).translate(0, 0, 380);
  8.     }
  9. }
  10. [/javascript]
  11.  
  12. The next step was to bind the finger swiping events. Webkit allows you to bind ‘touchstart’, ‘touchmove’ and ‘touchend’ events to any html element and from the touch event you can access the screenPosition and the time of the touch. Using these it is easy to determine which direction the swipe is and how hard the user swiped
  13.  
  14. [javascript]
  15. jAd.bindTouches = function(){
  16. //ignore the touchmove event
  17.         document.addEventListener('touchmove', function(e) {e.preventDefault();});
  18.         document.addEventListener('touchstart', function(e) {
  19.             e.preventDefault();
  20. //e.touches is an array (for multitouch usage) but we just want the first finger down
  21.             var touch = e.touches[0];
  22. //save the time and the screenY coordinate
  23.             jAd.currentTouch.startY = touch.screenY;
  24.             jAd.currentTouch.startTime = e.timeStamp;
  25.         }, false);
  26.         document.addEventListener('touchend', function(e) {
  27.             e.preventDefault();
  28.             var touch = e.changedTouches[0];
  29.             jAd.currentTouch.endY = touch.screenY;
  30.  //work out the speed using the saved coordinate and time
  31.             var time = e.timeStamp - jAd.currentTouch.startTime;
  32.             var speed = (jAd.currentTouch.startY - jAd.currentTouch.endY)/time;
  33.  //send the speed to the spin function
  34.             jAd.spin(speed);
  35.  
  36.         }, false);
  37.     };
  38. [/javascript]
  39.  
  40. The speed that is sent to the spin function can be positive or negative and this determines which way the nav spins.
  41.  
  42. Next I had to create a function to change the rotation of the <ul> element which contains the &lt;li&gt; elements that make up the ring.
  43.  
  44. [javascript]
  45. jAd.spin = function(speed){
  46.  //get a string representation of the current 3dCSSMatrix of the <ul> (jAd.shape)
  47.         var theTransform = window.getComputedStyle(jAd.shape).webkitTransform;
  48.  //from this create a new WebKitCSSMatrix
  49.         var matrix = new WebKitCSSMatrix(theTransform);
  50.  //do some stuff to get a number that is somewhere between 0 and 179
  51.         var newX = Math.round(speed * 120);
  52.         newX = (newX > 179) ? 179 : ((newX < -179) ? -179 : newX);
  53. //rotate the <ul> in the x plane by this value
  54.         shape.style.webkitTransform = matrix.rotate(newX, 0, 0);
  55.     };

Note that this function doesn’t animate the ring, it simply changes the rotateX value of the webkit-transform css property. In order to get the animation to happen we have to give the <ul> some webkit-transition css.

  1. #shape {
  2. /* this tell it to animate whenever the -webkit-trasform property changes */
  3.     -webkit-transition-property: -webkit-transform;
  4.     -webkit-transition-duration: 1500ms;
  5.     -webkit-transition-timing-function : ease-out;
  6.     -webkit-transition-delay: 0;
  7. }

Great work Ted!

Posted by Dion Almaer at 6:27 am
3 Comments

++++-
4.5 rating from 13 votes

3 Comments »

Comments feed TrackBack URI

This is great. It would be even more great (for me) if someone will make a iPhone wordpress theme using this slider.

Comment by mpakier — April 21, 2010

It’s a true shame that 3D CSS will likely be exclusively relegated to the iPhone for quite some time. :/

Comment by Baryn — April 21, 2010

I didn’t come across the finger tips code, I’ll check it out, it probably would have saved me some time.

Comment by superted — April 21, 2010

Leave a comment

You must be logged in to post a comment.