css3 的動畫讓 html 頁面變得生機勃勃,但是如何用好動畫是一門藝術,接下來我來以一個demo為例,來練習css3 animation。
我們先詳細瞭解一下animation 這個屬性。
animation-name
這是一個必填的選項,否則無法指定要執行哪一個動畫。
animation-duration
屬性定義動畫完成一個週期所需要的時間,以秒或毫秒計,如果不寫的話,動畫將無法執行。
animation-timing-function
動畫速度曲線(預設ease),這個屬性稍微複雜一些,它規定了這個動畫在哪個時間執行的快,那個時間執行的慢。屬性定義了一些常用的速度曲線,下面是一些例子:
linear // 動畫從頭到尾的速度是相同的
ease // 動畫以低速開始,然後加快,在結束前變慢
ease-in // 動畫以低速開始
ease-out // 動畫以低速結束
ease-in-out // 動畫以低速開始和結束
cubic-bezier(n,n,n,n) // cubic-bezier 是二階貝塞爾曲線,4個值都在[0,1]之間取,前兩個值組成一個點,後兩個值組成一個點。
animation-delay
規定在動畫開始之前的延遲時間(預設0),同樣以秒或毫秒計。
animation-iteration-count
動畫播放次數(預設1),可以是任意正整數或者無限次數 infinite。
animation-direction
動畫是否方向播放(預設normal)
normal // 每個動畫週期正向播放
reverse // 每個動畫週期反向播放
alternate // 奇數週期正向播放,偶數週期方向播放
alternate-reverse // 偶數週期方向播放,奇數週期正向播放
animation
animation 是animation動畫的簡寫,可以將以上6個屬性寫在一起。既:
animation: name duration timing-function delay iteration-count direction;
我們將animation基礎知識複習了一遍,接下來我們用一個小例子感受一下animation 的魅力。我們先看一下這個 animation-demo。這個demo主要有四處用到了 animation動畫。
第一處是當橫屏時 ( window.innerHeight < window.innerWidth ) 出現豎屏提示
這裡運用動畫的有三處,第一個是手機的旋轉,第二個和第三個是對號錯號的縮放。下面上程式碼
html部分
<div class="phone"> <img src="img/phone.png"/> <i class="yes"></i> <i class="no"></i> </div>
css部分
.phone {position: absolute;left: 50%;top: 100px;transform: translateX(-50%)} .phone img {position: relative;animation: rotate_phone 5s ease-in-out infinite} .phone .yes {position: absolute;left: 50%;top: 50%;display: inline-block;width: 40px;height: 30px; background-image: url("../img/yes.png");animation: scale_yes 5s ease infinite} .phone .no {position: absolute;left: 50%;top: 50%;display: inline-block;width: 40px;height: 30px; background-image: url("../img/no.png");animation: scale_no 5s ease infinite} @keyframes rotate_phone { 0% {transform: rotate(0deg)} 15% {transform: rotate(0deg)} 35% {transform: rotate(-90deg)} 65% {transform: rotate(-90deg)} 85% {transform: rotate(0deg)} 100% {transform: rotate(0deg)} } @keyframes scale_yes { 0% {transform: translate(-50%,-50%) scale(1);} 22% {transform: translate(-50%,-50%) scale(1);} 24% {transform: translate(-50%,-50%) scale(0);} 52% {transform: translate(-50%,-50%) scale(0);} 80% {transform: translate(-50%,-50%) scale(0);} 82% {transform: translate(-50%,-50%) scale(1.3);} 84% {transform: translate(-50%,-50%) scale(0.8);} 86% {transform: translate(-50%,-50%) scale(1.1);} 88% {transform: translate(-50%,-50%) scale(0.9);} 90% {transform: translate(-50%,-50%) scale(1);} 100% {transform: translate(-50%,-50%) scale(1);} } @keyframes scale_no { 0% {transform: translate(-50%,-50%) scale(0);} 30% {transform: translate(-50%,-50%) scale(0);} 32% {transform: translate(-50%,-50%) scale(1.3);} 34% {transform: translate(-50%,-50%) scale(0.8);} 36% {transform: translate(-50%,-50%) scale(1.1);} 38% {transform: translate(-50%,-50%) scale(0.9);} 40% {transform: translate(-50%,-50%) scale(1);} 72% {transform: translate(-50%,-50%) scale(1);} 74% {transform: translate(-50%,-50%) scale(0);} 100% {transform: translate(-50%,-50%) scale(0);} }
這段程式碼的精髓所在就是如何協調配合好這三個動畫。那麼怎麼協調呢?先拿手機旋轉來說,我設定的動畫運動的時間比上總時間為2:5,即在100%中,有60%的時間是不動的,這樣一來我們可以分配30%的時間在豎著的手機動畫上,30%的時間在橫著的手機動畫上。我的思路首先會想到下面這樣的程式碼:
0% {transform: rotate(0deg)} 50% {transform: rotate(-90deg)} 100% {transform: rotate(0deg)}
然後分析50%的時候是橫屏(rotate: -90deg),橫屏時間佔30%,分別向左右各延伸15%,即35%~65%,在迴圈動畫中0%其實就是100%,都可以看作是豎屏(rotate: 0deg)的時間中心,因此豎屏時間範圍從0%~15%和85%~100%。所以得到 rotate_phone 動畫。接下來我們以錯號(scale_no)的縮放動畫為例作分析,
0% {transform: translate(-50%,-50%) scale(0);} 30% {transform: translate(-50%,-50%) scale(0);} 32% {transform: translate(-50%,-50%) scale(1.3);} 34% {transform: translate(-50%,-50%) scale(0.8);} 36% {transform: translate(-50%,-50%) scale(1.1);} 38% {transform: translate(-50%,-50%) scale(0.9);} 40% {transform: translate(-50%,-50%) scale(1);} 72% {transform: translate(-50%,-50%) scale(1);} 74% {transform: translate(-50%,-50%) scale(0);} 100% {transform: translate(-50%,-50%) scale(0);}
動畫首先到達橫屏的時候為 rotate_phone 動畫的35%部分,我是以35%為錯號縮放動畫的中心時間,以2%為一個時間段(根據自己的需求),縮放程度先大後小scale(1.3)=>scale(0.8)=>scale(1.1)=>scale(0.9)=>scale(1)這裡只是粗略的表示。正號的部分就是將錯號的部分+50%或者-50%就可以了。超過100%的部分或者少於0%的部分在重新換算成0%~100%,比如72% => 22%。因此得到 scale_yes 動畫
0% {transform: translate(-50%,-50%) scale(1);} 22% {transform: translate(-50%,-50%) scale(1);} 24% {transform: translate(-50%,-50%) scale(0);} 80% {transform: translate(-50%,-50%) scale(0);} 82% {transform: translate(-50%,-50%) scale(1.3);} 84% {transform: translate(-50%,-50%) scale(0.8);} 86% {transform: translate(-50%,-50%) scale(1.1);} 88% {transform: translate(-50%,-50%) scale(0.9);} 90% {transform: translate(-50%,-50%) scale(1);} 100% {transform: translate(-50%,-50%) scale(1);}
第二處是主頁背景顏色的變換動畫
這個動畫比較簡單,就是背景顏色的變換,顏色我是藉助 Ant Design 的顏色設計。下面貼程式碼
article {height: 100%;width: 100%;position: relative;animation: change_color 10s ease-in-out infinite;overflow: hidden} @keyframes change_color { 0% {} 8% {background-color: #ffa39e;} 12% {} 28% {background-color: #b7eb8f;} 32% {} 48% {background-color: #ffadd2;} 52% {} 68% {background-color: #adc6ff;} 72% {} 88% {background-color: #ffe58f;} 92% {} 100% {background-color: #ffa39e;} }
第三處是轉盤的轉動
首先先把這個圓盤放在中間,這個不在動畫範圍而且比較簡單就不多說。中間的指標是130px * 155px的,但是這裡注意我們不能將指標圖片中心與轉盤中心重合,因為這個圖片不是正方形,我們要把指標圓形的中心與轉盤中心重合,我使用了絕對定位,這裡使用calc計算屬性(存在相容性問題)解決上面重合問題。
css部分
article .disc .disc-box .zz {position: absolute;left: calc(50% - 65px);top: calc(50% - 90px);transform: rotate(0deg);transition: all 8s cubic-bezier(0.25, 0.46, 0.45, 0.94);transform-origin: 65px 90px}
js部分
$('.zz').css('transform','rotate(3000deg)')
這裡使用點選事件來出發事件改變樣式。
第四部分是四邊運動的文字
這部分比較簡單,看程式碼就懂,其中兩個稍微麻煩的點就是將四個文字盒子通過旋轉平移到四個邊,再有就是要先得到一個重複單元文字的長度。下面貼程式碼。
html部分
<div class="move"> <div class="top pp"> <p> GUOZHIQIANG GUOZHIQIANG GUOZHIQIANG GUOZHIQIANG GUOZHIQIANG </p> </div> <div class="right pp"> <p> GUOZHIQIANG GUOZHIQIANG GUOZHIQIANG GUOZHIQIANG GUOZHIQIANG </p> </div> <div class="bottom pp"> <p> GUOZHIQIANG GUOZHIQIANG GUOZHIQIANG GUOZHIQIANG GUOZHIQIANG </p> </div> <div class="left pp"> <p> GUOZHIQIANG GUOZHIQIANG GUOZHIQIANG GUOZHIQIANG GUOZHIQIANG </p> </div> </div>
css部分
.move .pp {height: 80px;position: absolute;overflow: hidden;left: 0;top: 0;} .move .top {width: calc(100vw - 80px);transform: translate(0px, 0px);} .move .bottom {width: calc(100vw - 80px);transform: translate(80px, calc(100vh - 80px)) rotate(180deg);} .move .right {width: calc(100vh - 80px);transform: translate(100vw, 0px) rotate(90deg);transform-origin: 0px 0px;} .move .left {width: calc(100vh - 80px);transform: translate(0px, 100vh) rotate(-90deg);transform-origin: 0px 0px;} .move .pp p {height: 80px;line-height: 80px;font-size: 50px;color: #000;animation: move 1.5s linear infinite;} @keyframes move { from {transform: translate(-422px, 0px);} to {transform: translate(0px, 0px);} }
注意move動畫這裡的 -422px 就是一個重複單元文字的長度,既 "GUOZHIQIANG "的長度。
但這裡css動畫就看完了,程式碼很簡單,這裡是碼雲地址 https://gitee.com/guo_zq/color.git,喜歡請點贊哦。
轉載請註明:CSS3 animation 練習