CSS3 animation 練習

Vadim發表於2019-01-03

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 練習

 

相關文章