简体   繁体   中英

AngularJS how to animate body background (CSS or JS)?

I'd like to animate background image when the view changes. Background image is currently set by a function which is defined in MainController - it looks like that:

// app/js/controllers.js

$scope.getBg = function() {
  return $route.current.scope.pageBg || 'bg-intro';
};

it just returns a class name ('pageBg' is defined in each Controller separately) which should be applied to the body:

// app/index.html
<body ng-class="getBg()">
...
</body>

The CSS classes looks something like that:

.bg-intro {
  background: #4d4638 url(../img/home.jpg) no-repeat top center;
}

I tried both CSS and JS ways to solve this but without success.

CSS:

/* app/css/animations.css */

.bg-intro.ng-enter,
.bg-intro.ng-leave {
background: #ffffff;
}

.bg-intro.ng-enter {
animation: 0.5s fade-in;
}

.bg-intro.ng-leave {
animation: 0.5s fade-out;
}

@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}

@keyframes fade-out {
from { opacity: 1; }
to { opacity: 0; }
}

JS (with Greensock):

.animation('.bg-intro', function() {
    return {
        enter: function(element, done) {
            TweenMax.set(element, { backgroundColor:"#ffffff"});
            TweenMax.from(element, .5, {alpha:0, ease:Power2.easeInOut, onComplete:done});

            return function(cancel) {
                if(cancel) {
                    element.stop();
                }
            };
        },

        leave: function(element, done) {
            TweenMax.set(element, { backgroundColor:"#ffffff"});
            TweenMax.to(element, .5, {alpha:0, ease:Power2.easeInOut, onComplete:done});

            return function(cancel) {
                if(cancel) {
                    element.stop();
                }
            };
        }
    }})

I thought that this would be an easy task and unfortunately it appeares to be to hard for me.

ng-enter and ng-leave are applied when you're using directives like ng-show etc. In this case, you're just applying a style, so you can achieve what you are trying to do with simple CSS transition on the background element for body:

body{
  transition: background ease-in-out 0.5s;
}

I recommend this article for a more complete overview of Angular animations.

You must create a factory that animates your background, and on complete the factory needs to return a promise. Then using something like Angular UI-Router, you can request a promise before changing views. Here is an example of the same concepts that I use for my footer to animate open and close when transitioning views.

angular.module('App.factory', []).factory("footerUtility", function($window){
var element = document.getElementById('footer-wrapper');
return {
    open : function() {
        TweenMax.to(element,1, {
            delay:1.5,
            maxHeight: '300',
            height: 'auto',
            width: '100%',
            marginTop:'0px',
            overflow: 'hidden',
            ease: Cubic.easeInOut
        });


    },
    close : function(deferred) {
        TweenMax.to(element, .500, { delay:0,maxHeight: 0, height: 0,width: '100%', overflow: 'hidden', ease: Cubic.easeInOut,
            onComplete:function(){
                $window.scrollTo(0,0);
                deferred.resolve('complete');
            }});
    }
}
});

Then you would use angular UI-Router to set a enter and leave and a resolove. like so:

'use strict';
angular.module('App.home', [])
.config(
['$stateProvider', '$locationProvider', '$urlRouterProvider',
    function ($stateProvider, $locationProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise('/home');

        $stateProvider.state("home", {
            abstract: false,
            url: "/home",
            controller: 'homeCtrl',
            templateUrl: 'partials/home.html',
            onExit: ['footerUtility'],
            onEnter: ['footerUtility',
                function (footerUtility) {
                    footerUtility.open();
                }],
            resolve:['footerUtility', '$q', function(footerUtility, $q){
                var deferred = $q.defer();
                footerUtility.close(deferred);
                return deferred.promise;
            }]
        })
    }]
).controller('homeCtrl', ['$scope','$stateParams', '$http', '$location', '$timeout', function($scope, $stateParams, $http, $location, $timeout) {


}]);

Hopefully this is a good enough example to get you going with the basics. you could also pass a color or url into your factory so you could specify the background of the body changing on the way out, and the way in, etc...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM