CSS3動畫詳解(圖文教程)

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

如下是正文。css

前言

本文主要內容:html

  • 過渡:transition前端

  • 2D 轉換 transformjava

  • 3D 轉換 transformcss3

  • 動畫:animationgit

過渡:transition

transition的中文含義是過渡。過渡是CSS3中具備顛覆性的一個特徵,能夠實現元素不一樣狀態間的平滑過渡(補間動畫),常常用來製做動畫效果。github

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

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

參考連接:補間動畫基礎

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轉換包括:縮放、移動、旋轉。

咱們依次來說解。

一、縮放: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 轉換,並不會把兄弟元素擠走。

二、位移: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,往左走本身寬度的一半【推薦寫法】
    }

三、旋轉: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>

效果以下:

四、傾斜

暫略。

3D 轉換

一、旋轉: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>

二、移動: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的效果的。

三、透視:perspective

電腦顯示屏是一個 2D 平面,圖像之因此具備立體感(3D效果),其實只是一種視覺呈現,經過透視能夠實現此目的。

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

格式有兩種寫法:

  • 做爲一個屬性,設置給父元素,做用於全部3D轉換的子元素

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

四、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)經過@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>

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

效果以下:

二、動畫屬性

咱們剛剛在調用動畫時,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)。

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

相關文章
相關標籤/搜索