用CSS3动画,让页面动起来
以前就聽說過有個庫,叫animate.css,但是自己并沒有在實際項目中使用過,這次正好要做個招聘頁面,得以利用一下這個庫,在經常會卡頓的UC瀏覽器中也能流暢執行。
掃描下面的二維碼,可以看到在線的demo頁面:
如果對CSS3動畫的一些基礎概念不是很熟悉,可以參考《CSS3中的動畫效果記錄》。
一、animate.css庫中的相關知識點
從github上面下載下來是一個css文件,文件里面有3000多行代碼,大部分的代碼還是能看懂的。
但里面的代碼還是有很多耐人尋味的地方。
1. 關鍵幀的選定,不僅有整數,還有小數,并且也不是說有規律的,幾的倍數。
2. 速度曲線的選定,使用的是cubic-bezier函數,自定義貝塞爾曲線,這里有個在線制作貝塞爾曲線的工具。
3. 全程使用transform屬性來實現動畫效果,使用了大量的translate3d、rotate3d、scale3d,這樣還能開啟硬件加速。
4. 使用perspective屬性設置鏡頭到元素平面的距離。
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語法如下:
二、頁面開發過程
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記錄》
三、JavaScript部分
1)slider綁定
給“ul”綁定touchstart、touchmove、touchend。touch的相關概念可以參考《觸屏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
總結
以上是生活随笔為你收集整理的用CSS3动画,让页面动起来的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 生成高斯图像
- 下一篇: .Net三种实现以及跨平台