I have a block with ng-repeat , which is defined as follows:
<div ng-show="isPageSelected(item.page)" class="block" ng-repeat="item in data"> ... </div>
Currently, I can switch between these blocks by clicking on certain elements. It works through ng-show="isPageSelected(item.page)" , as you might have guessed. Everything works fine, but they switch instantly, and I want to add animation, a simple fade / fade will do.
So, a block that is no longer selected should disappear, and when it is gone, the new block must disappear. When I use ngAnimate , they disappear and disappear at the same time. I need the first block to completely disappear and be hidden with display: none; , and when it is done, the next block should appear and disappear. This is a pretty simple task when using jQuery, but how do I do it elegantly using Angular.js
I have a strong suspicion that Angular.js is not a good choice for a site with complex animations.
EDIT: To simplify my question, all I have to do is
- By clicking the mouse button, start the animation;
- When the animation is complete, change the model;
- Run another animation.
Since I need to change the model after the animation, it may not be possible to do this with pure CSS. The only way to know the animation of individual elements in angular is to create a directive, pass the scope variable to the directive, create an observer for this variable in the directive, and then change the variable from the controller:
<div animation="page"></div>
app.directive('animation', function(){ return { scope: { page: '=animation' }, link: function(scope, element){ scope.$watch('page', function(newVal){ ... }); } }; });
I suppose this will work, but it seems really bloated to create a directive just for that. Also, how do I change $scope.page to this approach only after the animation finishes? Add another scope variable just to start the animation and somehow change $scope.page when the animation is finished? This can be done using the ngFx module, but the amount of code that is required is just ridiculous. At the moment, I think adding jQuery animation to the controller would be a more beautiful way to solve it.
EDIT: what it looks like with jQuery animation:
$scope.changePage = function(page) { $('.block').animate({opacity: 0}, 500, function(){ $scope.page.id = page; $scope.$apply(); $(this).animate({opacity: 1}, 500); }); };
It works fine, and it's not as much as the directive mode, but I have to use a CSS selector and it just feels โnon-angularโ. Do you guys use something similar when working with animations?
EDIT: A somewhat similar approach using ngFx :
<div ng-hide="switchPageAnimation" class="block fx-fade-normal fx-speed-300 fx-trigger">
In the controller:
$scope.switchPageAnimation = false; $scope.changePage = function(page) { if($scope.page.id === page || $scope.switchPageAnimation) return; $scope.switchPageAnimation = true; $scope.$on('fade-normal:enter', function(){ $scope.page.id = page; $scope.switchPageAnimation = false; }); };
I don't use CSS selectors, but it still looks awful. I have to define the scope variable for the animation, and then check if the animation is running. I feel like I'm missing something really obvious.