Search code examples
angularjscssng-animatepanning

Using angular animation to change view using panning snaps


I am changing the view using ngRoute which loads a new template for ng-view. The new view is loaded via angular animation (in a panning like manner). This works, however when the new view is sliding in it is not on the right place. When the animation is finished it 'snaps' into place. I've uploaded the code to PLNKR: http://plnkr.co/edit/uMCHGNKu2Eta0yx0uszP?p=info

I experimented all evening with position: relative, absolute, inhered, etc. Also searching the internet (incl. stackoverflow) didn't help.

Any help or suggestion is welcome.

Thanks, HT.

ps. the code:

<!DOCTYPE html>
<html ng-app="panningApp">
<head>
    <meta charset="utf-8">
    <title>Panning App</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">

    <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
    <script type="text/javascript" src="https://code.angularjs.org/1.3.14/angular-route.min.js"></script>
    <script type="text/javascript" src="https://code.angularjs.org/1.3.14/angular-animate.min.js"></script>
    <style>
        .bigdiv{
            height: 500px;
            background-color: #abc;
            position: inherit;

        }
          .ng-enter, .ng-leave {
              -webkit-transition: all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
              transition: all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
              position:inherit;

          }
          .ng-enter {
              top: 0px;
              left: -100%;
              opacity: 0;
              position:inherit;
          }
          .ng-enter.ng-enter-active{
                top: 0px;
              left: 0px;
              opacity: 1;
              position:relative;
          }
          .ng-leave {
              top: 0px;
              left: 0px;
              opacity: 1;
              position:relative;
          }
          .ng-leave.ng-leave-active {
              left: 100%;
              opacity: 0;
              position:relative;
          }
          .container{
            border: 1px dashed #f00;
          }
    </style>
</head>
<body>
    <div class="container">
        <a href="#/pag1">pag1</a>
        <a href="#/pag2">pag2</a>
    </div>
    <div class="bigdiv">
        <ng-view></ng-view>
    </div>

    <script>
    panningApp = angular.module("panningApp", ["ngRoute", "ngAnimate"]);
    panningApp.config(["$routeProvider", function($routeProvider){
        $routeProvider.
            when("/pag1",{
                templateUrl: "page1.html"
            }).
            when("/pag2",{
                templateUrl: "page2.html"
            }).
            otherwise({
                redirectTo: '/page1'
            });
    }]);
    </script>
    <script type="text/ng-template" id="page1.html">
          <div class="container">
            Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum 
        </div>
    </script>
    <script type="text/ng-template" id="page2.html">
          <div class="container">
            Quasi ego id Quasi ego id Quasi ego id Quasi ego id Quasi ego id Quasi ego id Quasi ego id Quasi ego id 
        </div>
    </script>
</body>
</html>

Solution

  • The new view is not in the right place because the new view is a new block element that gets placed under the current view. While the animation plays you have two view containing div elements that are placed below each other.

    When the animation completes the above div element gets removed and the below one snaps to the top.

    I got it to work using absolute positioning:

    <!DOCTYPE html>
    <html ng-app="panningApp">
    <head>
    	<meta charset="utf-8">
    	<title>Panning App</title>
    	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
    	
    	<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
    	<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
    	<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
    	<script type="text/javascript" src="https://code.angularjs.org/1.3.14/angular-route.min.js"></script>
    	<script type="text/javascript" src="https://code.angularjs.org/1.3.14/angular-animate.min.js"></script>
    	<style>
    		.bigdiv{
    			height: 500px;
    			background-color: #abc;
    			position: relative;
    			
    		}
    		  .ng-enter, .ng-leave {
                  -webkit-transition: all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
                  transition: all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
                  position:inherit;
     
              }
              .ng-enter {
                  top: 0px;
                  left: -100%;
                  opacity: 0;
                  position:absolute;
                  width:100%;
              }
              .ng-enter.ng-enter-active{
              		top: 0px;
                  left: 0px;
                  opacity: 1;
                  position:absolute;
                  width:100%;
              }
              .ng-leave {
                  top: 0px;
                  left: 0px;
                  opacity: 1;
                  position:absolute;
                  width:100%;
              }
              .ng-leave.ng-leave-active {
                  left: 100%;
                  opacity: 0;
                  position:absolute;
                  width:100%;
              }
              .container{
              	  border: 1px dashed #f00;
              }
    	</style>
    </head>
    <body>
    	<div class="container">
    		<a href="#/pag1">pag1</a>
    		<a href="#/pag2">pag2</a>
    	</div>
    	<div class="bigdiv">
    		<ng-view></ng-view>
    	</div>
    	
    	<script>
    	panningApp = angular.module("panningApp", ["ngRoute", "ngAnimate"]);
    	panningApp.config(["$routeProvider", function($routeProvider){
    		$routeProvider.
    			when("/pag1",{
    				templateUrl: "page1.html"
    			}).
    			when("/pag2",{
    				templateUrl: "page2.html"
    			}).
    			otherwise({
    				redirectTo: '/page1'
    			});
    	}]);
    	</script>
    	<script type="text/ng-template" id="page1.html">
              <div class="container">
    			Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum 
    		</div>
    	</script>
    	<script type="text/ng-template" id="page2.html">
              <div class="container">
    			Quasi ego id Quasi ego id Quasi ego id Quasi ego id Quasi ego id Quasi ego id Quasi ego id Quasi ego id 
    		</div>
    	</script>
    </body>
    </html>

    http://plnkr.co/edit/O7evrkXh8nMUOaUQfx69?p=preview