javascriptjquerycsshtml3d

Create a 3d rotating mouse-tracking wall of tiles navigation using javascript, html5 and css3


I've been searching and I can't find anything on the web, but I'm interested in creating (or using something already available, hopefully since I'm pressed with time) similar to this site: http://www.citroen.hr/citroen/#/citroen/

It's also similar to the Safari Top Sites view, but has the added mouse-tracking and 3d rotation.

Does anyone know of something similar created with javascript/html/css or can point me in the right direction?


Solution

  • 2020 update

    Here's a more modern version of something of the kind.

    2013 solution

    A basic version with HTML elements, CSS 3D transforms (so it only works in browsers supporting 3D transforms & nesting of 3D transformed elements - this means no Opera and no IE) and a little bit of JavaScript for the mouse tracking:

    demo

    HTML:

    <ul class='tiles'>
      <li class='tile'></li>
      <!-- more tiles; I used 16 for the demo and put them on an icosagon -->
    </ul>
    <div class='slider'></div>
    

    Relevant CSS:

    .tiles {
      position: absolute;
      top: 50%; left: 50%;
      padding: 0;
      width: 0; height: 0;
      list-style: none;
      transform-style: preserve-3d;
      transform: rotateY(-162deg);
    }    
    .tile {
      position: absolute;
      left: 50%;
      margin: 0.5em -10em;
      width: 20em; height: 20em;
      backface-visibility: hidden;
      opacity: 0.5;
      /* inradius of an icosagon */
      cursor: pointer;
      transition: 0.5s;
    }
    .tile:hover { opacity: 1; }
    .tile:nth-child(odd) { bottom: 100%; }
    .tile:nth-child(2), .tile:nth-child(1) {
      transform: rotateY(18deg) translateZ(-66.29439em);
    }
    /* and so on... in general, something of the form: 
    .tile:nth-child(2*i), .tile:nth-child(2*i-1) {
      transform: rotateY(1*18deg) translateZ(-66.29439em);
    }
    where 18deg = outer angle of the icosagon 
    66.29439em = 1.05*20em*(1 + sqrt(5) + sqrt(5 + 2*sqrt(5)))/2 
               = 1.05 * inradius of icosagon
    see http://mathworld.wolfram.com/Icosagon.html */
    .tile:nth-child(1) {
      background: url(image1.jpg);
      background-size: cover;
    }
    /* and so on, set backgrounds for each */
    .slider {
      position: absolute;
      bottom: 5%; left: 10%;
      height: 0.25em; width: 80%;
      opacity: 0.5;
      background: grey 
        linear-gradient(90deg, crimson 100%, transparent 100%) no-repeat;
      background-size: 5% 100%;
    }
    

    JavaScript:

    (function(){
      var b = document.body;
      
      b.addEventListener('mousemove', function(e) {
        var w = b.clientWidth, x = e.clientX, 
            perc = x/w, 
            full_angle = -162, 
            to_angle = full_angle + (100 - perc)*full_angle, 
            txt = 'rotateY(' + to_angle + 'deg)', 
            prefixes = ['Webkit', 'Moz', /*'ms', 'O', */''], 
            len = prefixes.length, 
            property = 'Transform',
            a = document.querySelector('.tiles'), 
            s = document.querySelector('.slider');
        for(var i = 0; i < len; i++) {
          if(prefixes[i] == '')
            property = property.toLowerCase();
          a.style[prefixes[i] + property] = txt;
        }
        s.style.backgroundPosition = (perc*100 - .5) + '% 50%';
      }, false);
    }());