MarionetteJS - animate to a view by transformation of parent

by Jon Beebe

HTML

<script src="http://pixelfilmstudios.com/test/point.js"></script>
<script src="http://pixelfilmstudios.com/test/matrix.js"></script>
<div id="container">
  <div id="viewport">
    <div id="world">
      <div id="world-bg"></div>
      <div id="world-fixed"></div>
      <div id="world-content">
        <div id="one" class="slide">
          Slide 1
          <iframe src="http://player.vimeo.com/video/57078160?title=0&amp;byline=0&amp;portrait=0&amp;autoplay=1" width="50%" height="50%" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
        </div>
        <div id="two" class="slide">
          Slide 2
          <iframe src="http://player.vimeo.com/video/57084980?title=0&amp;byline=0&amp;portrait=0&amp;autoplay=1" width="50%" height="50%" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
        </div>
      </div>
    </div>
  </div>
</div>
<button id="rotateMe">Press Me</button>

CSS

#container {
  position: absolute;
  top:0;
  left:0;
  width: 100%;
  height: 100%;
}

#viewport {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow:hidden;
}

#world {
  position: absolute;
  top: 0;
  left: 0;
  width: 200%;
  height: 100%;
}

#world-content {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

#world-content, 
#world-bg {
  -webkit-transform-origin: 0 0;
  -webkit-transition: -webkit-transform 1s ease-in-out;
}

#world-content > div.slide {
  width: 50%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  -webkit-transform-origin: 0 0;
}


#world-bg {
  position: absolute;
  top: -500%;
  left: -500%;
  width: 1000%;
  height: 1000%;
}

#two {
  background: rgba(255,255,255,0.2);
  /* -webkit-transform: translateX(100%) translateY(100%) rotate(90deg); */
  -webkit-transform: translateX(100%);
}

/* 
 * styles 
 */

#container {
  background: #eee;
}

#world-fixed {
  position: absolute;
  top: 10%;
  left: 10%;
  width: 30%;
  height: 80%;
  background: rgba(0,0,0,0.5);
}

#world-bg {
  position: absolute;
  top: -500%;
  left: -500%;
  width: 1000%;
  height: 1000%;
  background: url(http://subtlepatterns.com/patterns/rockywall.png);
}

#world-content > div.slide {
  line-height: 50%;
  text-align: center;
  border: 1px solid white;
}

#one {
  background: rgba(0,0,0,0.2);
}

iframe {
  position: absolute;
  top: 25%;
  left: 25%;
}

#rotateMe {
  z-index: 1;
  position: relative;
}

JavaScript

Matrix.prototype = $.extend({}, Matrix.prototype, {
  toMatrixString: function () {
    return 'matrix(' + this.a.toFixed(20) + ', ' + this.b.toFixed(20) + ', ' + this.c.toFixed(20) + ', ' + this.d.toFixed(20) + ', ' + this.tx.toFixed(20) + ', ' + this.ty.toFixed(20) + ')';
  }
});

Matrix.initWithElem = function ($elem) {
  var tr = $elem.css('-webkit-transform');
  var m = new Matrix();

  try {
    var v = tr.split('(')[1].split(')')[0].split(',');
    m = new Matrix(Number(v[0]),
    Number(v[1]),
    Number(v[2]),
    Number(v[3]),
    Number(v[4]),
    Number(v[5]));
  } catch (e) {}

  return m;
};

var button = $('#rotateMe');
var world = $('#world');
var worldContent = $('#world-content');
var worldBg = $('#world-bg');
var one = $('#one');
var two = $('#two');

var showingTwo = false;

button.on('click', function (event) {

  var worldMatrix = Matrix.initWithElem(world);
  var worldContentMatrix = Matrix.initWithElem(worldContent);
  var worldBgMatrix = Matrix.initWithElem(worldBg);
  var twoMatrix = Matrix.initWithElem(two);

  // undo the transformation on two
  //two.css('-webkit-transform', twoMatrix.concat(twoMatrix.clone().invert()).toMatrixString());

  if (showingTwo == true) {
    // world.css('-webkit-transform', worldMatrix.concat(worldMatrix.clone().invert()).toMatrixString());
    
    
    worldContent.css('-webkit-transform', worldContentMatrix.concat(worldContentMatrix.clone().invert()).toMatrixString());
    worldBg.css('-webkit-transform', worldBgMatrix.concat(worldBgMatrix.clone().invert()).toMatrixString());
    
    showingTwo = false;
  } else {
    // cause the parent to inverse
    // world.css('-webkit-transform', twoMatrix.clone().invert().toMatrixString());
    worldContent.css('-webkit-transform', twoMatrix.clone().invert().toMatrixString());
    worldBg.css('-webkit-transform', twoMatrix.clone().invert().toMatrixString());
    showingTwo = true;
  }
});