AngularJS bidirectionnal ng-views animations
Shows how to dynamically change the ng-view animation.
by Adam Mendoza
HTML
<script src="http://code.angularjs.org/1.1.5/angular.js"></script>
<!-- * * * * * * P A G E W R A P P E R * * * * * -->
<ng-view ng-animate="transitionClass"></ng-view>
<!-- * * * * * * P A G E T E M P L A T E S * * * * * -->
<script type="text/ng-template" id="page1.html">
<div class="page page1">
<h1>Page 1</h1>
<button ng-click="go('/two')">go page 2 (Left to Right)</button>
</div>
</script>
<script type="text/ng-template" id="page2.html">
<div class="page page2">
<h1>Page 2</h1>
<button ng-click="go('/three')">go page 3 (Right to Left)</button>
</div>
</script>
<script type="text/ng-template" id="page3.html">
<div class="page page3">
<h1>Page 3</h1>
<button ng-click="go('/two')">go page 2 (Left to Right)</button>
<button ng-click="go('/one')">go page 1 (Right to Left)</button>
</div>
</script>
CSS
body {
overflow:hidden;
margin:0;
padding:0;
}
.page {
width:100%;
height:300px;
padding:20px;
position: absolute;
}
.page1 { background-color: #cff; }
.page2 { background-color: #fcc; }
.page3 { background-color: #cfc; }
/* * * * * * N O T E * * * * *
angular 1.1.4 used the classes myname-enter-setup, myname-enter-start
angular 1.1.5 uses the classes myname-enter, myname-enter-active
by default, where 'myname' ist the identifier provided with <ng-view ng-animate="'myname'">
* * * * * * * * * * * * * * * */
/* * * * * * * LR * * * * * * */
.LR-enter {
-webkit-transition: 1.5s ease-out all;
-webkit-transform: translate(-100%,0);
}
.LR-enter-active {
-webkit-transform: translate(0,0);
}
.LR-leave {
-webkit-transition: 1.5s ease-out all;
-webkit-transform: translate(0,0);
}
.LR-leave-active {
-webkit-transform: translate(100%,0);
}
/* * * * * * * RL * * * * * * */
.RL-enter {
-webkit-transition: 1.5s ease-out all;
-webkit-transform: translate(100%,0);
}
.RL-enter-active {
-webkit-transform: translate(0,0);
}
.page::before, ng-view::before {
content:attr(class);
}
.RL-leave {
-webkit-transition: 1.5s ease-out all;
-webkit-transform: translate(0,0);
}
.RL-leave-active {
-webkit-transform: translate(-100%,0);
}
JavaScript
var app = angular.module('demo', []);
/* * * * * V I E W R O U T I N G * * * * */
app.config(function ($routeProvider) {
$routeProvider
.when('/one', {
templateUrl:'page1.html'
})
.when('/two', {
templateUrl:'page2.html'
})
.when('/three', {
templateUrl:'page3.html'
})
.otherwise({
redirectTo:'/one'
});
});
/* * * * * T R I G G E R R O U T E C H A N G E * * * * */
app.controller('MainCtrl', function($scope, $rootScope, $location) {
$scope.go = function(path) {
$location.path(path);
}
});
/* * * * * L I S T E N F O R R O U T E C H A N G E * * * * */
/* * * * * A N D S E T T R A N S I T I O N C L A S S * * * * */
app.run(function($rootScope, $window) {
$rootScope.$on("$locationChangeSuccess", function (event, next, current) {
// $rootScope.transitionClass = "";
});
$rootScope.$on("$locationChangeStart", function (event, next, current) {
// url slug : shortening the url to stuff that follows after "#"
current = current.slice( current.lastIndexOf('#')+1, current.length );
next = next.slice( next.lastIndexOf('#')+1, next.length );
// apply transition class according to route
switch( next ){
// trigger "back" transition
case $rootScope.lastPage: $rootScope.transitionClass = $rootScope.backTransition; break;
// trigger "regular" transitions
case '/one': $rootScope.transitionClass = "RL"; break;
case '/two': $rootScope.transitionClass = "LR"; break;
case '/three': $rootScope.transitionClass = "RL"; break;
}
// set "back" transition class according to currently set transitionClass
switch( $rootScope.transitionClass ){
case 'RL': $rootScope.backTransition = "LR"; break;
case 'LR': $rootScope.backTransition = "RL"; break;
default: console.log("couldn't set backTransition");
}
// save current page slug, so we can check...