Wednesday, April 21st, 2010

Implementing 3d video navigation carousel a la iAds

Category: CSS

<p>

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
< view plain text >
  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. }

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

javascript
< view plain text >
  1. jAd.bindTouches = function(){
  2. //ignore the touchmove event
  3.         document.addEventListener('touchmove', function(e) {e.preventDefault();});
  4.         document.addEventListener('touchstart', function(e) {
  5.             e.preventDefault();
  6. //e.touches is an array (for multitouch usage) but we just want the first finger down
  7.             var touch = e.touches[0];
  8. //save the time and the screenY coordinate
  9.             jAd.currentTouch.startY = touch.screenY;
  10.             jAd.currentTouch.startTime = e.timeStamp;
  11.         }, false);
  12.         document.addEventListener('touchend', function(e) {
  13.             e.preventDefault();
  14.             var touch = e.changedTouches[0];
  15.             jAd.currentTouch.endY = touch.screenY;
  16.  //work out the speed using the saved coordinate and time
  17.             var time = e.timeStamp - jAd.currentTouch.startTime;
  18.             var speed = (jAd.currentTouch.startY - jAd.currentTouch.endY)/time;
  19.  //send the speed to the spin function
  20.             jAd.spin(speed);
  21.  
  22.         }, false);
  23.     };

The speed that is sent to the spin function can be positive or negative and this determines which way the nav spins.

Next I had to create a function to change the rotation of the

    element which contains the <li> elements that make up the ring.

    javascript
    < view plain text >
    1. jAd.spin = function(speed){
    2.  //get a string representation of the current 3dCSSMatrix of the <ul> (jAd.shape)
    3.         var theTransform = window.getComputedStyle(jAd.shape).webkitTransform;
    4.  //from this create a new WebKitCSSMatrix
    5.         var matrix = new WebKitCSSMatrix(theTransform);
    6.  //do some stuff to get a number that is somewhere between 0 and 179
    7.         var newX = Math.round(speed * 120);
    8.         newX = (newX > 179) ? 179 : ((newX < -179) ? -179 : newX);
    9. //rotate the <ul> in the x plane by this value
    10.         shape.style.webkitTransform = matrix.rotate(newX, 0, 0);
    11.     };

    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!

Related Content:

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.