CSS3動畫詳解(圖文教程)


本文最初發表於博客園,並在GitHub上持續更新前端的系列文章。歡迎在GitHub上關注我,一起入門和進階前端。

以下是正文。

前言

本文主要內容:

  • 過渡:transition

  • 2D 轉換 transform

  • 3D 轉換 transform

  • 動畫:animation

過渡:transition

transition的中文含義是過渡。過渡是CSS3中具有顛覆性的一個特征,可以實現元素不同狀態間的平滑過渡(補間動畫),經常用來制作動畫效果。

  • 補間動畫:自動完成從起始狀態到終止狀態的的過渡。不用管中間的狀態。

  • 幀動畫:通過一幀一幀的畫面按照固定順序和速度播放。如電影膠片。

參考鏈接:補間動畫基礎

transition 包括以下屬性:

  • transition-property: all; 如果希望所有的屬性都發生過渡,就使用all。

  • transition-duration: 1s; 過渡的持續時間。

  • transition-timing-function: linear; 運動曲線。屬性值可以是:

    • linear 線性
    • ease 減速
    • ease-in 加速
    • ease-out 減速
    • ease-in-out 先加速后減速
  • transition-delay: 1s; 過渡延遲。多長時間后再執行這個過渡動畫。

上面的四個屬性也可以寫成綜合屬性

	transition: 讓哪些屬性進行過度 過渡的持續時間 運動曲線 延遲時間;

	transition: all 3s linear 0s;

其中,transition-property這個屬性是尤其需要注意的,不同的屬性值有不同的現象。我們來示范一下。

如果設置 transition-property: width,意思是只讓盒子的寬度在變化時進行過渡。效果如下:

如果設置 transition-property: all,意思是讓盒子的所有屬性(包括寬度、背景色等)在變化時都進行過渡。效果如下:

案例:小米商品詳情

代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CSS 過渡</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            background-color: #eeeeee;
        }

        .content {
            width: 800px;
            height: 320px;
            padding-left: 20px;
            margin: 80px auto;
        }

        .item {
            width: 230px;
            height: 300px;
            text-align: center;
            margin-right: 20px;
            background-color: #FFF;
            float: left;
            position: relative;
            top: 0;
            overflow: hidden; /* 讓溢出的內容隱藏起來。意思是讓下方的橙色方形先躲起來 */
            transition: all .5s; /* 從最初到鼠標懸停時的過渡 */
        }

        .item img {
            margin-top: 30px;
        }

        .item .desc {
            position: absolute;
            left: 0;
            bottom: -80px;
            width: 100%;
            height: 80px;
            background-color: #ff6700;
            transition: all .5s;
        }

        /* 鼠標懸停時,讓 item 整體往上移動5px,且加一點陰影 */
        .item:hover {
            top: -5px;
            box-shadow: 0 0 15px #AAA;
        }

        /* 鼠標懸停時,讓下方的橙色方形現身 */
        .item:hover .desc {
            bottom: 0;
        }
    </style>
</head>
<body>
<div class="content">
    <div class="item">
        <img src="./images/1.png" alt="">
    </div>

    <div class="item">
        <img src="./images/2.png" alt="">
        <span class="desc"></span>
    </div>
    <div class="item">
        <img src="./images/3.jpg" alt="">
        <span class="desc"></span>
    </div>
</div>
</body>
</html>

效果如下:

動畫效果錄制的比較差,但真實體驗還是可以的。

工程文件:

2D 轉換

轉換是 CSS3 中具有顛覆性的一個特征,可以實現元素的位移、旋轉、變形、縮放,甚至支持矩陣方式。

轉換再配合過渡和動畫,可以取代大量早期只能靠 Flash 才可以實現的效果。

在 CSS3 當中,通過 transform 轉換來實現 2D 轉換或者 3D 轉換。

  • 2D轉換包括:縮放、移動、旋轉。

我們依次來講解。

1、縮放:scale

格式:

	transform: scale(x, y);

	transform: scale(2, 0.5);

參數解釋: x:表示水平方向的縮放倍數。y:表示垂直方向的縮放倍數。如果只寫一個值就是等比例縮放。

取值:大於1表示放大,小於1表示縮小。不能為百分比。

格式舉例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box {
            width: 1000px;
            margin: 100px auto;
        }

        .box div {
            width: 300px;
            height: 150px;
            background-color: pink;
            float: left;
            margin-right: 15px;
            color: white;
            text-align: center;
            font: 400 30px/150px “宋體”;

        }

        .box .box2 {
            background-color: green;
            transition: all 1s;
        }

        .box .box2:hover {
            /*width: 500px;*/
            /*height: 400px;*/
            background-color: yellowgreen;

            /* transform:  css3中用於做變換的屬性
                scale(x,y):縮放 */
            transform: scale(2, 0.5);
        }

    </style>
</head>
<body>
<div class="box">
    <div class="box1">1</div>
    <div class="box2">2</div>
    <div class="box3">3</div>
</div>

</body>
</html>

效果:

上圖可以看到,給 box1 設置 2D 轉換,並不會把兄弟元素擠走。

2、位移:translate

格式:

	transform: translate(水平位移, 垂直位移);

	transform: translate(-50%, -50%);

參數解釋:

  • 參數為百分比,相對於自身移動。

  • 正值:向右和向下。 負值:向左和向上。如果只寫一個值,則表示水平移動。

格式舉例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box {
            width: 1000px;
            margin: 100px auto;
        }

        .box > div {
            width: 300px;
            height: 150px;
            border: 1px solid #000;
            background-color: red;
            float: left;
            margin-right: 30px;
        }

        div:nth-child(2) {
            background-color: pink;
            transition: all 1s;
        }

        /* translate:(水平位移,垂直位移)*/
        div:nth-child(2):hover {
            transform: translate(-50%, -50%);
        }
    </style>

</head>
<body>
<div class="box">
    <div class="box1">1</div>
    <div class="box2">2</div>
    <div class="box3">3</div>
</div>

</body>
</html>

效果:

上圖中,因為我在操作的時候,鼠標懸停后,立即進行了略微的移動,所以產生了兩次動畫。正確的效果應該是下面這樣的:

應用:讓絕對定位中的盒子在父親里居中

我們知道,如果想讓一個標准流中的盒子在父親里居中(水平方向看),可以將其設置margin: 0 auto屬性。

可如果盒子是絕對定位的,此時已經脫標了,如果還想讓其居中(位於父親的正中間),可以這樣做:

	div {
		width: 600px;
		height: 60px;
		position: absolute;  絕對定位的盒子
		left: 50%;           首先,讓左邊線居中
		top: 0;
		margin-left: -300px;  然后,向左移動寬度(600px)的一半
	}

如上方代碼所示,我們先讓這個寬度為600px的盒子,左邊線居中,然后向左移動寬度(600px)的一半,就達到效果了。

現在,我們還可以利用偏移 translate 來做,這也是比較推薦的寫法:

	div {
	    width: 600px;
	    height: 60px;
	    background-color: red;
	    position: absolute;       絕對定位的盒子
	    left: 50%;               首先,讓左邊線居中
	    top: 0;
	    transform: translate(-50%);    然后,利用translate,往左走自己寬度的一半【推薦寫法】
	}

3、旋轉:rotate

格式:

	transform: rotate(角度);

	transform: rotate(45deg);

參數解釋:正值 順時針;負值:逆時針。

舉例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box {
            width: 200px;
            height: 200px;
            background-color: red;
            margin: 50px auto;
            color: #fff;
            font-size: 50px;
            transition: all 2s; /* 過渡:讓盒子在進行 transform 轉換的時候,有個過渡期 */
        }

        /* rotate(角度)旋轉 */
        .box:hover {
            transform: rotate(-405deg); /* 鼠標懸停時,讓盒子進行旋轉 */
        }

    </style>
</head>
<body>
<div class="box">1</div>

</div>
</body>
</html>

效果:

注意,上方代碼中,我們給盒子設置了 transform 中的 rotate 旋轉,但同時還要給盒子設置 transition 過渡。如果沒有這行過渡的代碼,旋轉會直接一步到位,效果如下:(不是我們期望的效果)

案例1:小火箭

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        html,body{
            height:100%;
        }

        body{
            background-color: #DE8910;
        }
        .rocket{
            position: absolute;
            left:100px;
            top:600px;
            height: 120px;
            transform:translate(-200px ,200px) rotate(45deg);
            transition:all 1s ease-in;
        }

        body:hover .rocket{
            transform:translate(500px,-500px) rotate(45deg);
        }
    </style>
</head>
<body>
    <img  class="rocket" src="images/rocket.png" alt=""/>
</body>
</html>

上方代碼中,我們將 transform 的兩個小屬性合並起來寫了。

小火箭圖片的url:http://img.smyhvae.com/20180208-rocket.png

案例2:撲克牌

rotate 旋轉時,默認是以盒子的正中心為坐標原點的。如果想改變旋轉的坐標原點,可以用transform-origin屬性。格式如下:

	transform-origin: 水平坐標 垂直坐標;

	transform-origin: 50px 50px;

	transform-origin: center bottom;   //旋轉時,以盒子底部的中心為坐標原點

我們來看一下 rotate 結合 transform-origin 的用法舉例。

代碼如下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        body {
            /*background-color: #eee;*/
        }

        .box {

            width: 300px;
            height: 440px;
            margin: 100px auto;
            position: relative;
        }

        img {
            width: 100%;
            transition: all 1.5s;
            position: absolute;     /* 既然撲克牌是疊在一起的,那就都用絕對定位 */
            left: 0;
            top: 0;

            transform-origin: center bottom; /*旋轉時,以盒子底部的中心為坐標原點*/
            box-shadow: 0 0 3px 0 #666;
        }

        .box:hover img:nth-child(6) {
            transform: rotate(-10deg);
        }

        .box:hover img:nth-child(5) {
            transform: rotate(-20deg);
        }

        .box:hover img:nth-child(4) {
            transform: rotate(-30deg);
        }

        .box:hover img:nth-child(3) {
            transform: rotate(-40deg);
        }

        .box:hover img:nth-child(2) {
            transform: rotate(-50deg);
        }

        .box:hover img:nth-child(1) {
            transform: rotate(-60deg);
        }

        .box:hover img:nth-child(8) {
            transform: rotate(10deg);
        }

        .box:hover img:nth-child(9) {
            transform: rotate(20deg);
        }

        .box:hover img:nth-child(10) {
            transform: rotate(30deg);
        }

        .box:hover img:nth-child(11) {
            transform: rotate(40deg);
        }

        .box:hover img:nth-child(12) {
            transform: rotate(50deg);
        }

        .box:hover img:nth-child(13) {
            transform: rotate(60deg);
        }

    </style>
</head>
<body>
<div class="box">
    <img src="images/pk1.png"/>
    <img src="images/pk2.png"/>
    <img src="images/pk1.png"/>
    <img src="images/pk2.png"/>
    <img src="images/pk1.png"/>
    <img src="images/pk2.png"/>
    <img src="images/pk1.png"/>
    <img src="images/pk2.png"/>
    <img src="images/pk1.png"/>
    <img src="images/pk2.png"/>
    <img src="images/pk1.png"/>
    <img src="images/pk2.png"/>
    <img src="images/pk1.png"/>
</div>
</body>
</html>

效果如下:

4、傾斜

暫略。

3D 轉換

1、旋轉:rotateX、rotateY、rotateZ

3D坐標系(左手坐標系)

如上圖所示,伸出左手,讓拇指和食指成“L”形,大拇指向右,食指向上,中指指向前方。拇指、食指和中指分別代表X、Y、Z軸的正方向,這樣我們就建立了一個左手坐標系。

瀏覽器的這個平面,是X軸、Y軸;垂直於瀏覽器的平面,是Z軸。

旋轉的方向:(左手法則)

左手握住旋轉軸,豎起拇指指向旋轉軸的正方向,正向就是其余手指卷曲的方向

從上面這句話,我們也能看出:所有的3d旋轉,對着正方向去看,都是順時針旋轉。

格式:

	transform: rotateX(360deg);    //繞 X 軸旋轉360度

	transform: rotateY(360deg);    //繞 Y 軸旋轉360度

	transform: rotateZ(360deg);    //繞 Z 軸旋轉360度

格式舉例:

(1)rotateX 舉例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .rotateX {
            width: 300px;
            height: 226px;
            margin: 200px auto;

            /* 透視 :加給變換的父盒子*/
            /* 設置的是用戶的眼睛距離 平面的距離*/
            /* 透視效果只是視覺上的呈現,並不是正真的3d*/
            perspective: 110px;
        }

        img {
            /* 過渡*/
            transition: transform 2s;
        }

        /* 所有的3d旋轉,對着正方向去看,都是順時針旋轉*/
        .rotateX:hover img {
            transform: rotateX(360deg);
        }

    </style>
</head>
<body>
<div class="rotateX">
    <img src="images/x.jpg" alt=""/>
</div>
</body>
</html>

效果:

上方代碼中,我們最好加個透視的屬性,方能看到3D的效果;沒有這個屬性的話,圖片旋轉的時候,像是壓癟了一樣。

而且,透視的是要加給圖片的父元素 div,方能生效。我們在后面會講解透視屬性。

(2)rotateY 舉例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .rotateY {
            width: 237px;
            height: 300px;
            margin: 100px auto;

            /* 透視 */
            perspective: 150px;
        }

        img {
            transition: all 2s;  /* 過渡 */
        }

        .rotateY:hover img {
            transform: rotateY(360deg);
        }
    </style>
</head>
<body>
<div class="rotateY">
    <img src="images/y.jpg" alt=""/>
</div>
</body>
</html>

效果:

(3)rotateZ 舉例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .rotateZ {
            width: 330px;
            height: 227px;
            margin: 100px auto;

            /* 透視*/
            perspective: 200px;
        }

        img {
            transition: all 1s;
        }

        .rotateZ:hover img {
            transform: rotateZ(360deg);
        }
    </style>
</head>
<body>
<div class="rotateZ">
    <img src="images/z.jpg" alt=""/>
</div>
</body>
</html>

效果:

案例:百度錢包

現在有下面這張圖片素材:

要求做成下面這種效果:

上面這張圖片素材其實用的是精靈圖。實現的代碼如下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        body {
            background-color: cornflowerblue;
        }

        .box {
            width: 300px;
            height: 300px;
            /*border: 1px solid #000;*/
            margin: 50px auto;
            position: relative;
        }

        .box > div {
            width: 100%;
            height: 100%;
            position: absolute;
            /*border: 1px solid #000;*/
            border-radius: 50%;
            transition: all 2s;
            backface-visibility: hidden;
        }

        .box1 {
            background: url(images/bg.png) left 0 no-repeat; /*默認顯示圖片的左半邊*/
        }

        .box2 {
            background: url(images/bg.png) right 0 no-repeat;
            transform: rotateY(180deg); /*讓圖片的右半邊默認時,旋轉180度,就可以暫時隱藏起來*/

        }

        .box:hover .box1 {
            transform: rotateY(180deg); /*讓圖片的左半邊轉消失*/
        }

        .box:hover .box2 {
            transform: rotateY(0deg); /*讓圖片的左半邊轉出現*/
        }
    </style>
</head>
<body>
<div class="box">
    <div class="box1"></div>
    <div class="box2"></div>
</div>
</body>
</html>

2、移動:translateX、translateY、translateZ

格式:

	transform: translateX(100px);    //沿着 X 軸移動

	transform: translateY(360px);    //沿着 Y 軸移動

	transform: translateZ(360px);    //沿着 Z 軸移動

格式舉例:

(1)translateX 舉例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box {
            width: 200px;
            height: 200px;
            background: green;
            transition: all 1s;
        }

        .box:hover {
            transform: translateX(100px);
        }
    </style>
</head>
<body>
<div class="box">

</div>
</body>
</html>

效果:

(2)translateY 舉例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box {
            width: 200px;
            height: 200px;
            background: green;
            transition: all 1s;
        }

        .box:hover {
            transform: translateY(100px);
        }
    </style>
</head>
<body>
<div class="box">

</div>
</body>
</html>

效果:

(3)translateZ 舉例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        body {
            /* 給box的父元素加透視效果*/
            perspective: 1000px;
        }

        .box {
            width: 250px;
            height: 250px;
            background: green;
            transition: all 1s;
            margin: 200px auto
        }

        .box:hover {
            /* translateZ必須配合透視來使用*/
            transform: translateZ(400px);
        }
    </style>
</head>
<body>
<div class="box">

</div>
</body>
</html>

效果:

上方代碼中,如果不加透視屬性,是看不到translateZ的效果的。

3、透視:perspective

電腦顯示屏是一個 2D 平面,圖像之所以具有立體感(3D效果),其實只是一種視覺呈現,通過透視可以實現此目的。

透視可以將一個2D平面,在轉換的過程當中,呈現3D效果。但僅僅只是視覺呈現出3d 效果,並不是正真的3d。

格式有兩種寫法:

  • 作為一個屬性,設置給父元素,作用於所有3D轉換的子元素

  • 作為 transform 屬性的一個值,做用於元素自身。

4、3D呈現(transform-style)

3D元素構建是指某個圖形是由多個元素構成的,可以給這些元素的父元素設置transform-style: preserve-3d來使其變成一個真正的3D圖形。屬性值可以如下:

	transform-style: preserve-3d;     //讓 子盒子 位於三維空間里

	transform-style: flat;            //讓子盒子位於此元素所在的平面內(子盒子被扁平化)

案例:立方體

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box {
            width: 250px;
            height: 250px;
            border: 1px dashed red;
            margin: 100px auto;
            position: relative;
            border-radius: 50%;

            /* 讓子盒子保持3d效果*/

            transform-style: preserve-3d;

            /*transform:rotateX(30deg) rotateY(-30deg);*/

            animation: gun 8s linear infinite;
        }

        .box > div {
            width: 100%;
            height: 100%;
            position: absolute;
            text-align: center;
            line-height: 250px;
            font-size: 60px;
            color: #daa520;
        }

        .left {
            background-color: rgba(255, 0, 0, 0.3);
            /* 變換中心*/
            transform-origin: left;
            /* 變換*/
            transform: rotateY(90deg) translateX(-125px);
        }

        .right {
            background: rgba(0, 0, 255, 0.3);
            transform-origin: right;
            /* 變換*/
            transform: rotateY(90deg) translateX(125px);
        }

        .forward {
            background: rgba(255, 255, 0, 0.3);
            transform: translateZ(125px);
        }

        .back {
            background: rgba(0, 255, 255, 0.3);
            transform: translateZ(-125px);
        }

        .up {
            background: rgba(255, 0, 255, 0.3);
            transform: rotateX(90deg) translateZ(125px);
        }

        .down {
            background: rgba(99, 66, 33, 0.3);
            transform: rotateX(-90deg) translateZ(125px);
        }

        @keyframes gun {
            0% {
                transform: rotateX(0deg) rotateY(0deg);
            }

            100% {
                transform: rotateX(360deg) rotateY(360deg);
            }
        }
    </style>
</head>
<body>
<div class="box">
    <div class="up">上</div>
    <div class="down">下</div>
    <div class="left">左</div>
    <div class="right">右</div>
    <div class="forward">前</div>
    <div class="back">后</div>
</div>
</body>
</html>

動畫

動畫是CSS3中具有顛覆性的特征,可通過設置多個節點 來精確控制一個或一組動畫,常用來實現復雜的動畫效果。

1、定義動畫的步驟

(1)通過@keyframes定義動畫;

(2)將這段動畫通過百分比,分割成多個節點;然后各節點中分別定義各屬性;

(3)在指定元素里,通過 animation 屬性調用動畫。

之前,我們在 js 中定義一個函數的時候,是先定義,再調用:

    js 定義函數:
        function fun(){ 函數體 }

     調用:
     	fun();

同樣,我們在 CSS3 中定義動畫的時候,也是先定義,再調用

    定義動畫:
        @keyframes 動畫名{
            from{ 初始狀態 }
            to{ 結束狀態 }
        }

     調用:
      animation: 動畫名稱 持續時間;

其中,animation屬性的格式如下:

            animation: 定義的動畫名稱 持續時間  執行次數  是否反向  運動曲線 延遲執行。(infinite 表示無限次)

            animation: move1 1s  alternate linear 3;

            animation: move2 4s;

定義動畫的格式舉例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .box {
            width: 100px;
            height: 100px;
            margin: 100px;
            background-color: red;

            /* 調用動畫*/
            /* animation: 動畫名稱 持續時間  執行次數  是否反向  運動曲線 延遲執行。infinite 表示無限次*/
            /*animation: move 1s  alternate linear 3;*/
            animation: move2 4s;
        }

        /* 方式一:定義一組動畫*/
        @keyframes move1 {
            from {
                transform: translateX(0px) rotate(0deg);
            }
            to {
                transform: translateX(500px) rotate(555deg);
            }
        }

        /* 方式二:定義多組動畫*/
        @keyframes move2 {
            0% {
                transform: translateX(0px) translateY(0px);
                background-color: red;
                border-radius: 0;
            }

            25% {
                transform: translateX(500px) translateY(0px);

            }

            /*動畫執行到 50% 的時候,背景色變成綠色,形狀變成圓形*/
            50% {
                /* 雖然兩個方向都有translate,但其實只是Y軸上移動了200px。
                因為X軸的500px是相對最開始的原點來說的。可以理解成此時的 translateX 是保存了之前的位移 */
                transform: translateX(500px) translateY(200px);
                background-color: green;
                border-radius: 50%;
            }

            75% {
                transform: translateX(0px) translateY(200px);
            }

            /*動畫執行到 100% 的時候,背景色還原為紅色,形狀還原為正方形*/
            100% {
                /*坐標歸零,表示回到原點。*/
                transform: translateX(0px) translateY(0px);
                background-color: red;
                border-radius: 0;
            }
        }
    </style>
</head>
<body>
<div class="box">

</div>
</body>
</html>

注意好好看代碼中的注釋。

效果如下:

2、動畫屬性

我們剛剛在調用動畫時,animation屬性的格式如下:

animation屬性的格式如下:

            animation: 定義的動畫名稱  持續時間  執行次數  是否反向  運動曲線 延遲執行。(infinite 表示無限次)

            animation: move1 1s  alternate linear 3;

            animation: move2 4s;

可以看出,這里的 animation 是綜合屬性,接下來,我們把這個綜合屬性拆分看看。

(1)動畫名稱:

	animation-name: move;

(2)執行一次動畫的持續時間:

	animation-duration: 4s;

備注:上面兩個屬性,是必選項,且順序固定。

(3)動畫的執行次數:

	animation-iteration-count: 1;       //iteration的含義表示迭代

屬性值infinite表示無數次。

(3)動畫的方向:

	animation-direction: alternate;

屬性值:normal 正常,alternate 反向。

(4)動畫延遲執行:

	animation-delay: 1s;

(5)設置動畫結束時,盒子的狀態:

	animation-fill-mode: forwards;

屬性值: forwards:保持動畫結束后的狀態(默認), backwards:動畫結束后回到最初的狀態。

(6)運動曲線:

	animation-timing-function: ease-in;

屬性值可以是:linear ease-in-out steps()等。

注意,如果把屬性值寫成 steps(),則表示動畫不是連續執行,而是間斷地分成幾步執行。我們接下來專門講一下屬性值 steps()

steps()的效果

我們還是拿上面的例子來舉例,如果在調用動畫時,我們寫成:

	animation: move2 4s steps(2);

效果如下:

有了屬性值 steps(),我們就可以作出很多不連續地動畫效果。比如時鍾;再比如,通過多張靜態的魚,作出一張游動的魚。

step()舉例:時鍾的簡易模型

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        div {
            width: 3px;
            height: 200px;
            background-color: #000;
            margin: 100px auto;
            transform-origin: center bottom;    /* 旋轉的中心點是底部 */
            animation: myClock 60s steps(60) infinite;
        }

        @keyframes myClock {
            0% {
                transform: rotate(0deg);
            }

            100% {
                transform: rotate(360deg);
            }
        }
    </style>
</head>
<body>
<div></div>
</body>
</html>

上方代碼,我們通過一個黑色的長條div,旋轉360度,耗時60s,分成60步完成。即可實現。

效果如下:

動畫舉例:擺動的魚

現在,我們要做下面這種效果:

PS:圖片的url是http://img.smyhvae.com/20180209_1245.gif,圖片較大,如無法觀看,可在瀏覽器中單獨打開。

為了作出上面這種效果,要分成兩步。

(1)第一步:讓魚在原地擺動

魚在原地擺動並不是一張 gif動圖,她其實是由很多張靜態圖間隔地播放,一秒鍾播放完畢,就可以了:

上面這張大圖的尺寸是:寬 509 px、高 2160 px。

我們可以理解成,每一幀的尺寸是:寬 509 px、高 270 px。270 * 8 = 2160。讓上面這張大圖,在一秒內從 0px 的位置往上移動2160px,分成8步來移動。就可以實現了。

代碼是:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .shark {
            width: 509px;
            height: 270px; /*盒子的寬高是一幀的寬高*/
            border: 1px solid #000;
            margin: 100px auto;
            background: url(images/shark.png) left top; /* 讓圖片一開始位於 0 px的位置 */
            animation: sharkRun 1s steps(8) infinite; /* 一秒之內,從頂部移動到底部,分八幀, */
        }

        @keyframes sharkRun {
            0% {
            }

            /* 270 * 8 = 2160 */
            100% {
                background-position: left -2160px; /* 動畫結束時,讓圖片位於最底部 */
            }
        }
    </style>
</head>
<body>
<div class="sharkBox">
    <div class="shark"></div>
</div>

</div>
</body>
</html>

效果如下:

我們不妨把上面的動畫的持續時間從1s改成 8s,就可以看到動畫的慢鏡頭:

這下,你應該恍然大悟了。

(2)第二步:讓魚所在的盒子向前移動。

實現的原理也很簡單,我們在上一步中已經讓shark這個盒子實現了原地搖擺,現在,讓 shark 所在的父盒子 sharkBox向前移動,即可。完整版代碼是:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .shark {
            width: 509px;
            height: 270px; /* 盒子的寬高是一幀的寬高 */
            border: 1px solid #000;
            margin: 100px auto;
            background: url(images/shark.png) left top; /* 讓圖片一開始位於 0 px的位置 */
            animation: sharkRun 1s steps(8) infinite; /* 一秒之內,從頂部移動到底部,分八幀 */
        }

        /* 魚所在的父盒子 */
        .sharkBox {
            width: 509px;
            height: 270px;
            animation: sharkBoxRun 20s linear infinite;
        }

        @keyframes sharkRun {
            0% {
            }

            /* 270 * 8 = 2160 */
            100% {
                background-position: left -2160px; /* 動畫結束時,讓圖片位於最底部 */
            }
        }

        @keyframes sharkBoxRun {
            0% {
                transform: translateX(-600px);
            }

            100% {
                transform: translateX(3000px);
            }
        }

    </style>
</head>
<body>
<div class="sharkBox">
    <div class="shark"></div>
</div>

</div>
</body>
</html>

大功告成。

工程文件如下:

我的公眾號

想學習代碼之外的軟技能?不妨關注我的微信公眾號:生命團隊(id:vitateam)。

掃一掃,你將發現另一個全新的世界,而這將是一場美麗的意外:


免責聲明!

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



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