0

I 'm building an application with a number of slides, and I'm using Angular JS to toggle classes on the elements that trigger CSS animations. The problem that I'm having is that when a button is clicked that triggers a function on the angular controller that updates the $scope's property that determines the element's class, the property that causes the animation to begin appears to be updated before the element's old class is removed, and the new class assigned, so the element always moves in only one direction.

What I want to happen is when the proceed() function gets called from slide1, for slide2 to slide in from the right to the left, which it does correctly, but when the backToOne function gets called by clicking the Back button on slide 2, slide2 should slide out to the right.

What's actually happening is that when the backToOne() function gets called, slide2 slides out to the left. Any help is appreciated. I'm pretty new to angular, so I'm trying to figure out what I need to do to update that class, and then change the property's value that causes the animation to happen.

Thanks in advance.

Here's the (simplified) view:

<div ng-init="switcher='one'">
    <div ng-switch="switcher" class="my-switch-container">
      <div ng-switch-when="one" id="slide1" ng-class="slide1">
        <p>stuff</p>
        <button type="button" class="btn btn-primary" ng-click="proceed()">Proceed</button>
      </div>
      <div ng-switch-when="two" id=slide2" ng-class="slide2">
        <p>more stuff</p>
        <button type="button" class="btn" ng-click="backToOne()">Back</button>
        <button type="button" class="btn btn-primary" ng-click="keepGoing()">Go</button>
      </div>
      <div ng-switch-when="three" id=slide3" ng-class="slide3">
        <p>last stuff</p>
      </div>
    </div>
  </div>

Here's the (again, simplified) controller:

myApp.controller('siteCtrl', ['$scope', '$http', 'SomeData', function($scope, $http, SomeData) {
    $scope.model = SomeData;
    $scope.animateLeft = "my-switch-animation-left";
    $scope.animateRight = "my-switch-animation-right";
    $scope.slide1 = $scope.animateLeft;
    $scope.slide2 = $scope.animateLeft;
    $scope.slide3 = $scope.animateLeft;

    $scope.proceed = function() {
      $scope.switcher = "two";
      $scope.slide1 = $scope.animateRight;
    }

    $scope.backToOne = function() {
      $scope.slide2 = $scope.animateRight;
      $scope.switcher = "one";
    }

    $scope.keepGoing = function() {
      $scope.switcher = "three";
      $scope.slide2 = $scope.animateRight;
    }
}]);

Here's the CSS:

.my-switch-container{
    position: relative;
}

.my-switch-animation-left, .my-switch-animation-right {
    width: 700px;
    background-color: #FFF;
    border-radius: 20px;
    border: 1px solid #000;
    -webkit-border-radius: 20px;
    -moz-border-radius: 20px;
    -webkit-box-shadow: 0 5px 15px #000;
    -moz-box-shadow: 0 5px 15px #000;
    -ms-box-shadow: 0 5px 15px #000;
    box-shadow: 0 5px 15px #000;
    margin: 0 auto;
}
.my-switch-animation-left.ng-enter, 
.my-switch-animation-left.ng-leave, 
.my-switch-animation-right.ng-enter, 
.my-switch-animation-right.ng-leave {
    -webkit-transition: 1s linear all;
    -moz-transition: 1s linear all;
    -o-transition: 1s linear all;
    -transition: 1s linear all;
    position: relative;
    top: 0px;
}
/* moving right to left */
.my-switch-animation-left.ng-enter{
    left: 100%;
}
.my-switch-animation-left.ng-leave, 
.my-switch-animation-left.ng-enter.ng-enter-active{
    left: 0;
}
.my-switch-animation-left.ng-leave.ng-leave-active{
    left: -100%;
}
/* moving left to right */
.my-switch-animation-right.ng-enter{
    right: 100%;
}
.my-switch-animation-right.ng-leave, 
.my-switch-animation-right.ng-enter.ng-enter-active{
    right: 0;
}
.my-switch-animation-right.ng-leave.ng-leave-active{
    right: -100%;
}

Here's a (gross) plunkr of it: http://plnkr.co/edit/hSUEQDkVMSdwX2nPEFly?p=info

  • Are you injecting nganimate into your app? Can you provide a plunkr? – Snowburnt Feb 17 '14 at 23:37
  • Yes, I am injecting ng-animate into the app. It is animating, it's just not switching the class quickly enough to toggle the animation direction. I'll put together a plunkr shortly – user3163245 Feb 18 '14 at 00:31
  • @Snowburnt here is a really stripped-down plunkr of it that still gets across the basic functionality that I'm looking for: http://plnkr.co/edit/hSUEQDkVMSdwX2nPEFly?p=info – user3163245 Feb 18 '14 at 00:53
  • I'm looking, but I should mention there's a few plug ins out there already, here's one from angular-ui : http://angular-ui.github.io/bootstrap/#/carousel and another generic one: http://blog.revolunet.com/angular-carousel/ – Snowburnt Feb 18 '14 at 02:03
  • @Snowburnt Thanks for the suggestions. I'll give those a try! – user3163245 Feb 18 '14 at 02:16

1 Answers1

0

try this:

$scope.backToOne = function() {
  $scope.slide2 = $scope.animateRight;
  $scope.$apply();
  $scope.switcher = "one";
}

The digest didn't have a chance to run before applying the ng-class. $apply will force the scope to reevaluate. There's an error that pops up on the console, but it works.

Snowburnt
  • 6,523
  • 7
  • 30
  • 43
  • 1
    Thanks for that. It does work, but I think I'm going to try to implement the functionality in a way more similar to one of the examples you provided for doing it another way, as the way I'm doing it is probably not the optimal way for accomplishing the task in angular. – user3163245 Feb 18 '14 at 22:11
  • 1
    FYI, I got it working. To resolve the console error, I ended up doing this: `$scope.backToOne = function() { $scope.slide2 = $scope.animateRight; $timeout(function() { $scope.switcher = "one"; }); }` – user3163245 Feb 20 '14 at 01:28