var app = angular.module('plunker', [
  'ngRoute',
  'ngAnimate'
]);


//
// Resolver
// ---------------------------
var resolve = {
  delay: function($q, $timeout, $rootScope) {
    var deferred = $q.defer();

    var stopListening = $rootScope.$on('changeRoute', function (event) {
      event.stopPropagation();
      deferred.resolve('delay');
      stopListening();
    });

    return deferred.promise;
  }
};


//
// Routes
// ---------------------------

app.config(['$locationProvider', '$routeProvider', function ($locationProvider, $routeProvider) {
  $routeProvider.
    when('/', {
      controller: 'Page1Ctrl',
      templateUrl: 'page1.html',
      resolve: resolve
    })
    .when('/page2', {
      controller: 'Page2Ctrl',
      templateUrl: 'page2.html',
      resolve: resolve
    })
    .when('/page3', {
      controller: 'Page3Ctrl',
      templateUrl: 'page3.html',
      resolve: resolve
    })
    .otherwise({
      redirectTo: '/'
    });

  $locationProvider.html5Mode(true);
}])


//
// Controllers
// ---------------------------

.controller('MainCtrl', function ($scope, $rootScope,$timeout) {
  $rootScope.currentPage = 'page1';

  // Trigger on load:
  $timeout(function () {
    $rootScope.$emit('changeRoute');
  }, 0);
})
.controller('Page1Ctrl', function ($scope, $rootScope) {
  $rootScope.currentPage = 'page1';
})
.controller('Page2Ctrl', function ($scope, $rootScope) {
  $rootScope.currentPage = 'page2';
})
.controller('Page3Ctrl', function ($scope, $rootScope) {
  $rootScope.currentPage = 'page3';
})


//
// Directives
// ---------------------------

// Stage
.directive('stage', function ($rootScope, $timeout) {
  return {
    restrict: 'A',
    link: function (scope, element) {
      TweenMax.set('#main', {perspective:500});

      scope.$on('$locationChangeStart', function (event, next, current) {
        scope.$broadcast('hide');
      });
    }
  }
})


// Animations Page 1
.directive('page1', function ($rootScope) {

  var show = function (id, done) {
    var tl = new TimelineMax({onComplete: done});
    tl.add(TweenMax.from(id, .6, {rotationX: -90}));
    tl.add(TweenMax.from('#element1', .4, {x: 100, opacity: 0}));
    tl.add(TweenMax.from('#element2', .4, {x: 100, opacity: 0}));

    tl.play();
  };

  var hide = function (id, done) {
    var tl = new TimelineMax({onComplete: done});
    tl.add(TweenMax.to('#element2', .4, {x: 100, opacity: 0}));
    tl.add(TweenMax.to('#element1', .4, {x: 100, opacity: 0}));
    tl.add(TweenMax.to(id, .6, {rotationX: -90}));
    tl.play();
  };

  return {
    restrict: 'A',
    link: function (scope, element) {

      show(element);

      scope.$on('hide', function (event, next, current) {
        hide(element, function () {
          scope.$emit('changeRoute');
        });
      });
    }
  }
})


// Animations Page 2
.directive('page2', function ($rootScope) {

  var show = function (id, done) {
    var tl = new TimelineMax({onComplete: done});
    tl.add(TweenMax.from(id, .6, {rotationX: -90}));
    tl.add(TweenMax.from('#element3', .4, {y: 100, opacity: 0}));
    tl.add(TweenMax.from('#element4', .4, {y: 100, opacity: 0}));

    tl.play();
  };

  var hide = function (id, done) {
    var tl = new TimelineMax({onComplete: done});
    tl.add(TweenMax.to('#element4', .4, {y: 100, opacity: 0}));
    tl.add(TweenMax.to('#element3', .4, {y: 100, opacity: 0}));
    tl.add(TweenMax.to(id, .6, {rotationX: -90}));
    tl.play();
  };

  return {
    restrict: 'A',
    link: function (scope, element) {

      show(element);

      scope.$on('hide', function (event, next, current) {
        hide(element, function () {
          scope.$emit('changeRoute');
        });
      });
    }
  }
})


// Animations Page 3
.directive('page3', function ($rootScope) {

  var show = function (id, done) {
    var tl = new TimelineMax({onComplete: done});
    tl.add(TweenMax.from(id, .6, {rotationX: 90, rotationY: 90}));
    tl.add(TweenMax.from('#element5', .4, {x: 100, rotationY: -90, opacity: 0}));
    tl.add(TweenMax.from('#element6', .4, {x: 100, rotationX: -90, opacity: 0}));

    tl.play();
  };

  var hide = function (id, done) {
    var tl = new TimelineMax({onComplete: done});
    tl.add(TweenMax.to('#element6', .4, {x: 150, rotationX: 90, opacity: 0}));
    tl.add(TweenMax.to('#element5', .4, {x: 150, rotationY: 90, opacity: 0}));
    tl.add(TweenMax.to(id, .6, {rotationX: -90, rotationY: -90}));
    tl.play();
  };

  return {
    restrict: 'A',
    link: function (scope, element) {

      show(element);

      scope.$on('hide', function (event, next, current) {
        hide(element, function () {
          scope.$emit('changeRoute');
        });
      });
    }
  }
});
<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    
    <!--<script>document.write('<base href="' + document.location + '" />');</script>-->
    
    <link rel="stylesheet" href="style.css" />
  </head>

  <body ng-controller="MainCtrl">
    <h1>App</h1>
    <a href="./">Page 1</a> | <a href="./page2">Page 2</a> | <a href="./page3">Page 3</a>
    
    <main id="main"><div class="pages" ng-view stage></div></main>
    
    <script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.11.2/TweenMax.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular-animate.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular-route.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular-resource.min.js"></script>
    
    <script src="app.js"></script>
    
    <script>angular.element(document.getElementsByTagName('head')).append(angular.element('<base href="' + window.location.pathname + '" />'));</script>
  </body>

</html>
/* Put your css in here */

.pages {
  width: 400px;
  height: 400px;
  margin: 1em auto;
}

.page {
  padding: 10px;
  width: 100%;
  height: 100%;
  box-sizing:border-box;
}

#page1 {
  background: red;
}

#page2 {
  background: green;
}

#page3 {
  background: blue;
}
<div id="page1" class="page" page1>
  Content Page 1
  <div id="element1">Element 1</div>
  <div id="element2">Element 2</div>
</div>
<div id="page2" class="page" page2>
  Content Page 2
  <div id="element3">Element 3</div>
  <div id="element4">Element 4</div>
</div>
<div id="page3" class="page" page3>
  Content Page 3
  <div id="element5">Element 5</div>
  <div id="element6">Element 6</div>
</div>