用CSS3動畫,讓頁面動起來

之前就據說過有個庫,叫animate.css,可是本身並無在實際項目中使用過,此次正好要作個招聘頁面,得以利用一下這個庫,在常常會卡頓的UC瀏覽器中也能流暢執行。css

掃描下面的二維碼,能夠看到在線的demo頁面:html

若是對CSS3動畫的一些基礎概念不是很熟悉,能夠參考《CSS3中的動畫效果記錄》。前端

 

1、animate.css庫中的相關知識點

從github上面下載下來是一個css文件,文件裏面有3000多行代碼,大部分的代碼仍是能看懂的。css3

但裏面的代碼仍是有不少回味無窮的地方。git

1. 關鍵幀的選定,不只有整數,還有小數,而且也不是說有規律的,幾的倍數。github

2. 速度曲線的選定,使用的是cubic-bezier函數,自定義貝塞爾曲線,這裏有個在線製做貝塞爾曲線的工具web

3. 全程使用transform屬性來實現動畫效果,使用了大量的translate3d、rotate3d、scale3d,這樣還能開啓硬件加速。chrome

4. 使用perspective屬性設置鏡頭到元素平面的距離。gulp

 

1)內置的動畫有多種瀏覽器

1. bounce(跳動)、flash(閃光)、pulse(脈衝)、rubber band(橡皮筋)、shake(抖動)、swing(搖擺)、wobble(搖擺不定)

2. fade(淡入或淡出)

3. flip(翻轉)

4. rotate(旋轉)

5. slide(滑動)

6. zoom(放大或縮小)

 

2)translate3d、rotate3d、scale3d

上圖就是一個3D座標,人眼的正對面是z軸的正方向。能夠在線調試這三個屬性的效果。

1. translate3d語法以下:

聽說tz軸位移向量的長度不能設置爲百分比值,若是取值爲百分比值,將會認爲無效值。

2. rotate3d語法以下:

x,y,z是一個0到1之間的數值,主要用來描述元素圍繞X軸或Y軸或Z軸旋轉的矢量值

a:是一個角度值,主要用來指定元素在3D空間旋轉的角度,若是其值爲正值,元素順時針旋轉,反之元素逆時針旋轉。

下圖中two到three是繞着X軸旋轉,six到one是繞Y軸旋轉。而繞Z軸就和2D的旋轉效果相似。

3. scale3d語法以下:

 

2、頁面開發過程

1)設計稿

踩到的第一個坑,我頁面採用了flexible.js可伸縮佈局,這樣寬度就和設計稿同樣了。設計稿的寬度是750px,也就是iPhone6的CSS像素。

我伸縮下也變成了750px,這樣在設置邊距的時候就能夠直接用設計稿上面的了。關於屏幕適配能夠參考《移動開發屏幕適配分析

寬度是搞好了,可是高度卻不同,手機上面是1198px,設計稿是1206px,chrome上的模擬器是1256px。

額,怪不得我按照設計稿的邊距設置,在模擬器或手機上都達不到效果圖的樣子。

 

2)實現原理

在翻頁的時候,將當前頁面隱藏掉,給新頁面加個樣式,觸發動畫。

下圖中的「li」就是在翻頁後加一個樣式「play」,觸發整個動畫開始執行。

「li」中的子元素就是img圖片,發生動畫的就是這些img標籤:

CSS代碼以下:

.img3 {
  width: 4.666667rem;
  height: 2.133333rem;
  left: 2.8rem;
  top: 4rem;
  z-index: 4;
}
.play .img3 {
  -webkit-animation: zoomInUp 1s 1.2s backwards;
  animation: zoomInUp 1s 1.2s backwards;
}

下圖中,這個箭頭實際上是兩個動畫的結合體,不過在IOS能夠實現兩個動畫,而在Android中只能實現一種。

先放大而後再用脈衝效果。

.arrow {
    animation: zoomIn 1s 5s backwards, pulse 1s 0s infinite;
}

 

3)animation-fill-mode的使用

一開始不太明白,這動畫怎麼才能觸發,並且一開始各個元素是隱藏掉的,這咋作到的,後面參考了些頁面,發現了下面這個屬性。

animation-fill-mode規定對象動畫時間以外的狀態。

將其設置爲「backwards」:在 animation-delay 所指定的一段時間內,在動畫顯示以前,應用開始屬性值(在第一個關鍵幀中定義)。

在第一幀中設置爲透明,而後就能達到一個一個出現的效果了。

左圖所示,這個時候就能夠在第一幀中設置透明,注意不能用display:none,來隱藏,display不會出現動畫。

若是不設置爲「backwards」,那就會像右圖所示,先顯示而後隱藏,再開始動畫。

  

 

4)rem與CSS自動前綴

我如今是用SASS來寫CSS,上面代碼中的rem都是在編譯的時候動態計算出來的。

-webkit的那個前綴也是在編譯的時候動態添加的。

如今開發會使用前端自動化構建工具gulp。具體配置能夠參考《前端自動化構建工具gulp記錄

 

3、JavaScript部分

1)slider綁定

給「ul」綁定touchstarttouchmovetouchendtouch的相關概念能夠參考《觸屏touch事件記錄

touchmove中計算偏移量,超過指定的偏移纔在touchend觸發滑動效果。

頁面中動畫不少,有的地方須要在動畫結束後觸發一些效果,因此要綁定「webkitTransitionEnd」事件。

 1 $slider.on("webkitTransitionEnd", 'li', function() {
 2   isSlide = false; //slide動畫結束 防止暴力切換
 3 });
 4 $slider.on('touchstart', function(e) {
 5   var touch = e.touches[0];
 6   startX = touch.clientX;
 7   startY = touch.clientY;
 8   if (isSlide) {
 9     e.preventDefault();
10   }
11 }).on('touchmove', function(e) {
12   var touch = e.touches[0],
13     posY = touch.clientY,
14     posX = touch.clientX;
15   offsetY = posY - startY;
16   offsetX = posX - startX;
17   isMove = true;
18   e.preventDefault();
19 }).on("touchend", function(e) {
20   if (!offsetY || Math.abs(offsetY) < 30 || !isMove) {
21     return;
22   }
23   $this = $(e.target);
24   if ($this[0].tagName != 'LI') {
25     $this = $this.closest('li');
26   }
27   var current = $this.index();
28   $this.siblings('li').removeClass('play'); //防止出現重疊BUG
29   if (offsetY > 0) { //向下滑動
30     direction = "down";
31     $next = $this.prev();
32   } else { //向上滑動
33     direction = "up";
34     $next = $this.next();
35   }
36 
37   if (current == 0 && direction == 'down') {
38     return;
39   }
40   if (current == length - 1 && direction == 'up') {
41     return;
42   }
43 
44   if (direction == 'up') {
45     $this.addClass('move-up');
46   } else {
47     $this.addClass('move-down');
48   }
49   isSlide = true;
50   offsetY = 0;
51   offsetX = 0;
52   setTimeout(function() {
53     $this.removeClass('play move-up move-down');
54     $next.addClass('play').siblings('li').removeClass('play');
55   }, 300);
56 });

 

2)e.preventDefault

在「touchstart」和「touchmove」都調用了這個方法,這句話的意思是阻止默認行爲。

第一個調用是爲了防止在手指快速的上下滑動的時候觸發「touchend」中的切換。

第二個是Android 4.0+的一個BUG,就是有時候不會觸發「touchmove」事件,加了這個後就能觸發。

不過加了這個後,相應位置的滾動就無效了,囧。

關於事件處理的相關概念能夠參考《JavaScript中事件處理

 

 

參考資料:

CSS3 Transform的perspective屬性

CSS3 3D Transform