对几个角动画进行排序/链接的好方法是什么?

时间:2015-01-27 04:48:33

标签: angularjs

作为一个例子,我有一个ng-view动画,我有几个内容元素。我希望在视图动画完成后运行内容动画。目前我在内容元素上使用ng-hide,然后在ng-view-enter完成时设置范围变量。它不完全是一个优雅的完整解决方案。显然我可以将所有动画添加到ng-view-enter中,但是我希望保留单独的指令以使代码可重用。以下是使用TweenMax的示例:

//<ng-view class="animate-view"></ng-view>
    app.animation('.animate-view', [ function () {
        var obj = {};
        obj.enter = function(element, done){
            var $scope = angular.element(element).scope();
            console.log("15","obj","enter", $scope);
            var tm = new TimelineMax();
            tm.from(element.find('section'), 0.3, {scaleX:0});
            tm.add(done);
            tm.add(function(){
                $scope.$apply(function(){
                    $scope.viewReady=true;
                });
            }, "+=0.1");
        }

        return obj;
    }]);

    //<div class="animate-heading" ng-hide="!viewReady" >Heading 1</div>
        app.animation('.animate-heading', [ function () {
            var obj = {};        
            obj.beforeRemoveClass = function (element, className, done) {
                var $scope = angular.element(element).scope();
                if(className == "ng-hide"){
                    var tm = new TimelineMax();
                    tm.from(element, 0.4, {opacity:0});
                    tm.add(done);
                    tm.add(function(){
                        $scope.$apply(function(){
                            $scope.headingReady=true;
                        });
                    }, "+=0.1");
                }
            }

            return obj;
        }]);

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

2 个答案:

答案 0 :(得分:0)

Thomas Burleson对此post的阅读真的迫使我重新考虑Angular中的动画。我认为使用某种服务肯定是要走的路。但是,我知道的唯一真正做到这一点的例子是gsTimelines和ngFx

ngFx使用ngAnimate从注入的服务创建新动画。这里有一个小小的演示,展示了它是如何工作的。此演示中有2个动画模块,.shake执行addClass个动画,.block执行enter个动画。调用这些动画时,它们会创建一个新的TweenBuilder,根据存储在TweenBuilder服务中的可配置动画创建时间轴。

&#13;
&#13;
angular
  .module("app", ["ngAnimate"])
  .controller("MainController", MainController)
  .animation(".block", blockAnimation)
  .animation(".shake", shakeAnimation)
  .factory("TweenBuilder", TweenBuilder);

function MainController($timeout) {

  var vm   = this;
  vm.show  = false;
  vm.shake = false;
  
  vm.shakeBlock = function() {
    if (vm.shake) vm.shake = false; 
    $timeout(function() { vm.shake = true; });
  };
  
  vm.addBlock = function() {
    if (vm.show) vm.show = false; 
    $timeout(function() { vm.show = true; });
  };
}

function shakeAnimation(TweenBuilder) {
  
  var tweens = [
    { name: "shake", options: { x: 2, y: 2, repeat: 50 }}
  ];

  return new TweenBuilder({ addClass: tweens });
}

function blockAnimation(TweenBuilder) {

  var tweens = [
    { name: "slide", type: "from", duration: 0.5, label: "0", options: { x: window.innerWidth / 4 }}, 
    { name: "fade",  type: "to",   duration: 1.0, label: "0", options: { autoAlpha: 1 }}, 
    { name: "scale", type: "from", duration: 0.5, label: "0", options: { scale: 0.2 }}, 
    { name: "slide", type: "staggerFrom", duration: 0.5, label: "0.1", element: ".block div", stagger: 0.05, options: { x: 100 }}, 
  ];

  return new TweenBuilder({ enter: tweens });
}

function TweenBuilder() {
  
  var animation = {
    slide: function(element, tween) {
      return TweenMax[tween.type](element, tween.duration, { x: tween.options.x, y: tween.options.y }, tween.stagger);
    },
    scale: function(element, tween) {
      return TweenMax[tween.type](element, tween.duration, { scale: tween.options.scale });
    },
    fade: function(element, tween) {
      return TweenMax[tween.type](element, tween.duration, { autoAlpha: tween.options.autoAlpha });
    },
    shake: function(element, tween) {
      var x = tween.options.x, y = tween.options.y;
      return TweenMax.fromTo(element, 0.01, {x: -x, y: y}, {x: x, y: -y, clearProps: "x,y", repeat: tween.options.repeat });
    },
  };
  
  return function(config) {
    
    var className, done;
    
    this.enter    = angular.bind(this, buildTweens, "enter");
    this.addClass = angular.bind(this, buildTweens, "addClass");
    
    function buildTweens(type, element) {
      
      done = type === "addClass" 
        ? (className = arguments[2], arguments[3]) 
        : arguments[2];
      
      if (!config[type]) {
        done(); return;
      }
      
      config[type].reduce(function(timeline, tween) {
        return timeline
          .add(animation[tween.name](tween.element || element, tween), tween.label);
        
      }, new TimelineMax({ onComplete: done }));
    }
  };
}
&#13;
body {
  padding: 25px;
  overflow: hidden;
}

.block {
  position:relative;
  padding: 15px;
  opacity: 0;
  visibility: hidden;
}

.block > div {
  padding: 5px;
}
&#13;
<!DOCTYPE html>
<html ng-app="app">

<head>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.css" />
  <link rel="stylesheet" href="style.css" />
</head>

<body ng-cloak>
  
  <div ng-controller="MainController as vm">
  
    <div>
      <button class="btn btn-default" ng-click="vm.addBlock()">Add Block</button>
      <button class="btn btn-default" ng-click="vm.shakeBlock()">Shake Block</button>
    </div>
    
    <div class="block" ng-if="vm.show" ng-class="{ shake: vm.shake }">
      <h1>Lorem ipsum dolor sit amet.</h1>
      <hr>
      <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>
      <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>
      <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>
      <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>
      <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>
    </div>

  </div>

  <!-- vendor -->
  <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.js"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.15.0/TweenMax.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-animate.min.js"></script>

  <!-- app -->
  <script src="app.js"></script>

</body>
</html>
&#13;
&#13;
&#13;

答案 1 :(得分:-1)