6

While attempting to create a slideshow that fades images in and out I ran into this problem. What I found is that when doing animations one at a time, they are smooth and seamless. However when doing multiple animations, they become choppy and erratic. Here is the code I'm using for fading one image in, while at the same time, fading a overlapping image out (all happens in a directive):

var fadeToNextImg = function() {
    var nextImg = imageHandler.getNextImage();
    $animate.addClass(curImage, 'ng-hide');
    $animate.removeClass(nextImg, 'ng-hide');
    curImage = nextImg; 
};

This works, however the animation produces erratic results. The images don't fade in and out smoothly, instead they just appear, or sometime one of the images will fade. However if I nest the animations so that only one happens at a time then both animations excecute perfectly, one right after the other, like so:

var fadeToNextImg = function() {
    var nextImg = imageHandler.getNextImage();
    $animate.addClass(curImage, 'ng-hide', function() {
        $animate.removeClass(nextImg, 'ng-hide');
        curImage = nextImg;
    });
};

That's great.. just not the desired effect I wanted. I want for one image to fade out while the other image seamlessly fades in on top of it! Am I doing something wrong? Or is this a bug/performance issue in Angular Animate library?

Another thing to be aware of, I also tried this using JQuery DOM manipulation outside of a directive, and the animation was flawless. I only moved it to a directive because that is the angular way of doing things. So why does it jack up my animations?

Matt.M
  • 1,039
  • 3
  • 14
  • 21
  • You would be better off using jQuery for animations. angular-animate has been knows to have performance issues. Also read here... https://github.com/angular/angular.js/issues/4011 – Judson Terrell Jul 07 '16 at 18:11

1 Answers1

0

Not having used $animate before, the primary issue you're seeing is that $animate.addClass(...) returns a 'promise' once it is complete which indicates it is ASYNCHRONOUS. This means each following animation must be activated only after the previous promise's callback is complete (which means the image has finally loaded).

Put another way, the way you have it, your $animate.addClass(..)'s are executed immediately/consecutively and do not wait for the previous one to complete ergo the choppiness. Also, the way you have it, I don't believe ng-hide will work. Seems perhaps your end css state in one image is 'faded' and the start css state in the next image is 'faded' too. In this case, you may need to pass the options object to addClass(...) to handle the various from and to css states. Some rough pseudocode on how to use then on the $animate's promise callback:

var fadeToNextImg = function() {

  var nextImg = imageHandler.getNextImage();
  var promise = $animate.addClass(curImage, 'endfade');

  promise.then(function(results){
    $animate.removeClass(...)
    curImage = nextImg; 
  });

}
MoMo
  • 1,836
  • 1
  • 21
  • 38