AngularJS1.X學習筆記14-動畫(解讀文檔)


  最近在看算法分析,那個大O啊,小o啊,分治法啊(目前就看到這里),真是搞死了。這回呢休息一下,學學AngularJS動畫,上一篇文章根據自由男人的書簡單談到了動畫的話題,發現反響很大(好吧,我說慌了,那篇文章的動畫談得太簡單了),今天來看看官方文檔。嗯,邊看邊寫。

一、安裝

  這個應該都知道了,和其他的擴展模塊安裝相同。這里為了文章完整性簡單提一下。文檔給到了獲取動畫擴展angular-animate.js的多種方式。

  1、cdn,自己去查

  2、npm install --save angular-animate@X.Y.Z   

  3、bower install angular-animate#X.Y.Z

  拿到這個文件后需要引入到我們要應用動畫的頁面,添加依賴ngAnimate。

二、使用

  動畫的使用方式有兩種,一是CSS,二是通過javascript。前者是通過純粹的css來實現動畫,后者通過腳本觸發動畫。兩者都需要用到Angrular提供的一些特殊的類。

  1、支持動畫的指令

  

  最后兩個指令屬於一個擴展模塊ngMessages,為了集中火力搞動畫,先不管。

  2、基於CSS的動畫

  CSS動畫的特殊性在於你不需要寫一行javascript就可以創建出炫酷的動畫,這讓我想到了Bootstrap,她只要在html元素上添加一些特定的屬性就可以實現一些動畫。Angularjs基於CSS實現動畫的原理很簡單,即,如果你為某個指令加上了一些類比如fade,而你在樣式表中這樣寫.fade.ng-leave,這樣如果元素沒有ng-leave這個類,你加的fade的樣式就不會被運用,但是Angularjs會監視我們的指令,當檢測到指令進入某種狀態時就會添加相應的類,從而你的樣式就會被使用了,如此,動畫就觸發了。下面給個例子

  

<!DOCTYPE html>
<html lang="en" ng-app='myApp'>
<head>
    <meta charset="UTF-8">
    <title>animate</title>
    <style type="text/css">
        #div{
            width: 300px;
            height: 300px;
            background:red;
        }
        .ani.ng-hide{
            transition: 6s linear all;
            opacity: 0;
            background: blue;
        }
    </style>
</head>
<body>
    <div ng-controller='animateCtrl'>
        <div id="div" class="ani" ng-show='show'></div>
        <button ng-click='clickHandler()'>change</button>
    </div>


    <script type="text/javascript" src="../node_modules/angular/angular.min.js"></script>
    <script type="text/javascript" src="../node_modules/angular-animate/angular-animate.min.js"></script>
    <script type="text/javascript">
        var myApp = angular.module("myApp",['ngAnimate']);
        myApp.controller("animateCtrl",function($scope){
            $scope.show = true;
            $scope.clickHandler = function(){
                $scope.show = !$scope.show;
            }
        })
    </script>
</body>
</html>

  我們看一下當單擊按鈕隱藏時發生了什么。

  看到沒,angular給我們動態添加了很多類,正是因為如此,我們的動畫樣式才能被應用。

  有開始有結束

/* The starting CSS styles for the enter animation */
.fade.ng-enter {
  transition:0.5s linear all;
  opacity:0;
}

/* The finishing CSS styles for the enter animation */
.fade.ng-enter.ng-enter-active {
  opacity:1;
}

 

  angularjs對動畫元素的狀態進行了管理,可以標識狀態的開始如ng-enter 和狀態的結束 ng-enter-active.我們可以在狀態開始指定動畫的初始狀態,狀態的結束指定動畫的最終狀態。

  另外,angular提供了自己加類的機制。

  

<div ng-class="{on:onOff}" class="highlight">
  Highlight this box
</div>
<button ng-click="onOff=!onOff">Toggle</button>

<style>
.highlight {
  transition:0.5s linear all;
}
.highlight.on-add {
  background:white;
}
.highlight.on {
  background:yellow;
}
.highlight.on-remove {
  background:black;
}
</style>

 

  這個例子的意思是,如果onOff為真,那么給元素加上on這個類,在添加的過程中會添加on-add類,當onOff為false是,會為元素添加一個on-remove,當然,這個on-remove只存在與由true變為false的過程。

  有時候我們希望進入某個狀態后並不立即執行動畫,而是延遲執行,你一定想到了transition-delay或者animation-delay,ng也給我們提供了實現的方法。

  

.my-animation.ng-enter-stagger {
  /* this will have a 100ms delay between each successive leave animation */
  transition-delay: 0.1s;

  /* As of 1.4.4, this must always be set: it signals ngAnimate
    to not accidentally inherit a delay property from another CSS class */
  transition-duration: 0s;

  /* if you are using animations instead of transitions you should configure as follows:
    animation-delay: 0.1s;
    animation-duration: 0s; */
}

 

  就像這個樣子,給我們的動畫類加上一個叫.ng-xx-stagger的東東。

  介紹一個狀態,在動畫開始之前的狀態,ng-xx-prepare,xx 可以是enter, move, and leave。用法如下:

.message.ng-enter-prepare {
  opacity: 0;
}

 

  這個可以給我們的元素在沒有開始動畫(或者叫即將開始吧)的情況下設置樣式。

   3、基於javascript的動畫

  ngAmination模塊允許使用javascript使用其動畫功能,方式與CSS類似,不同的是它需要調一個模塊的animation()  方法,使用js的好處是我們可以用一些優秀的js動畫庫來設計動畫。

<!DOCTYPE html>
<html lang="en" ng-app='myApp'>
<head>
    <meta charset="UTF-8">
    <title>animate3</title>
    <style type="text/css">
        #hh{
            width: 100px;
            height: 50px;
            background: red;
        }
        
    </style>
</head>
<body>
    <div ng-controller='animateCtrl'>
        <div id="hh" ng-if="bool" class="slide">
          大家好!
        </div>
        <button ng-click="handler()">點我</button>
    </div>

    <script type="text/javascript" src="../node_modules/jquery/dist/jquery.min.js"></script>
    <script type="text/javascript" src="../node_modules/angular/angular.min.js"></script>
    <script type="text/javascript" src="../node_modules/angular-animate/angular-animate.min.js"></script>
    
    <script type="text/javascript">
        var myApp = angular.module("myApp",['ngAnimate']);
        myApp.controller("animateCtrl",function($scope){
            $scope.handler = function(){
                $scope.bool = !$scope.bool;
            }
        });

        myApp.animation('.slide', [function() {
          return {
            // make note that other events (like addClass/removeClass)
            // have different function input parameters
            enter: function(element, doneFn) {
              jQuery(element).fadeIn(1000, doneFn);

              // remember to call doneFn so that AngularJS
              // knows that the animation has concluded
            },

            leave: function(element, doneFn) {
              jQuery(element).fadeOut(10000, doneFn);
            }
          }
        }]);
    </script>
</body>
</html>

   不同指令支持的動畫有區別,可以參見本文最前面的圖,本例中用到了enter,和leave。

  4、基於css的方式和基於javascript的方式可以混用嗎

  文檔講:如果css方式和js方式使用了相同的css類,那么css方式將不能工作。但是,我們可以通過js去讓我們用css方式定義的動畫執行,這就需要一個新的服務叫做$animateCss

  

myModule.animation('.slide', ['$animateCss', function($animateCss) {
  return {
    enter: function(element) {
       // this will trigger `.slide.ng-enter` and `.slide.ng-enter-active`.
      return $animateCss(element, {
        event: 'enter',
        structural: true
      });
    }
  }
}]);

 

   下文中對$animateCss進行詳細介紹,這里簡單提示。

  5、錨動畫

  

<!-- index.html -->
<div ng-view class="view-animation">
</div>

<!-- home.html -->
<a href="#/banner-page">
  <img src="./banner.jpg" class="banner" ng-animate-ref="banner">
</a>

<!-- banner-page.html -->
<img src="./banner.jpg" class="banner" ng-animate-ref="banner">

 

 

.banner.ng-anchor {
  /* this animation will last for 1 second since there are
         two phases to the animation (an `in` and an `out` phase) */
  transition:0.5s linear all;
}
.view-animation.ng-enter, .view-animation.ng-leave {
  transition:0.5s linear all;
  position:fixed;
  left:0;
  top:0;
  width:100%;
}
.view-animation.ng-enter {
  transform:translateX(100%);
}
.view-animation.ng-leave,
.view-animation.ng-enter.ng-enter-active {
  transform:translateX(0%);
}
.view-animation.ng-leave.ng-leave-active {
  transform:translateX(-100%);
}

 

  這里貼出文檔的例子,ng-animate-ref的意思是將表明組件的關系,這樣在寫動畫是就可以只用一個類是兩個組件效果相同,.ng-anchor-in .ng-anchor-out .ng-anchor分別是在某組件顯示,某組件卸載,顯示卸載時添加的類,這樣可以在不同的狀態運用動畫。你可以看看文檔的一個DEMO:https://plnkr.co/edit/?p=preview

  關於angular是如何實現變形的,如何實現移動的感興趣可以看看https://docs.angularjs.org/api/ngAnimate

三、$animate服務

  $animate服務提供了一些實現動畫的工具方法,官方建議是只應該將其用在與dom相關的動畫指令中。這翻譯的自己都不明白了,英語太差了,如果你想了解更多自己去官網看看,別看我瞎扯了。

  1、on(event, container, callback)

  這個方法的目的是設置事件偵聽器,一旦某元素上觸發動畫事件(前文有提到的enter,leave等),其中的回調函數將被調用。

  這個方法接受三個參數:event表示要偵聽的動畫事件類型,container是一個dom元素,表示要偵聽的dom元素(注意他是有事件代理功能的,及子元素的事件會冒泡到該元素被捕獲),callback是個回調函數,當事件被觸發是執行,可以有兩個參數,第一個表示觸發事件的元素,第二個表示動畫階段個:值start表動畫開始,值close表動畫結束。

  2、off(event, [container], [callback])

  這個方法是移出元素的偵聽器,參數與上一個方法的類似。

  3、pin(element, parentElement)

  不太能夠理解這個方法。文檔說這個方法能夠讓angular應用之外的元素能夠執行動畫,一般來將我們的angular應用的dom元素都是包含在ng-app內的,也就是說沒有元素跑到angular應用之外,所以這個方法很讓我費解。

  4、enabled([element], [enabled])

  此方法用於啟用或禁用動畫。有四種使用方法。

  

// returns true or false
$animate.enabled();

// changes the enabled state for all animations
$animate.enabled(false);
$animate.enabled(true);

// returns true or false if animations are enabled for an element
$animate.enabled(element);

// changes the enabled state for an element and its children
$animate.enabled(element, true);
$animate.enabled(element, false);

 

  5、cancel(animationPromise)

  用於取消動畫執行。

  6、enter(element, parent, [after], [options])

  將element作為parent的第一個子元素或者after元素后面的元素。options是一個對象可有下面這幾個屬性:

  • addClass - 添加到element的類
  • from - {Object} - 表示動畫開始時的css樣式
  • removeClass - {string} -移除element類
  • to - {Object} - 表示動畫結束時的css樣式

  這個方法返回一個promise對象,動畫完成時變為resolved狀態。

  7、move(element, parent, [after], [options])

  將element移動到一個新的位置。返回一個promise,與enter()類似。

  8、leave(element, [options])

  觸發動畫然后刪除element

  9、addClass(element, className, [options])

  將className類加到element上並觸發addClass事件。

  10、removeClass(element, className, [options])

  移出className類並觸發removeClass事件。

  11、setClass(element, add, remove, [options])

  12、animate(element, from, to, [className], [options])

  本文給到了一個angular動畫的一個參考,涉及到ngAnimate的一些個用法,包括如何用CSS指定動畫,如何用js觸發動畫等,然后講到了$animate服務,不過感覺官網講的也不夠詳細(也可能是我的英語太差了)。與angular動畫相關的還有$aniamteCss服務,本文沒有講,防止越講越亂,感覺上面講的已經夠亂了。

  參考:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM