1. 程式人生 > >animation中的steps()逐幀動畫

animation中的steps()逐幀動畫

在我們平時做寬高確定,需要背景圖片切換的效果時,我如果用的是一張大的png圖片。而且恰好是所有小圖都是從左向右排列的,那麼 我們只需測量出某一個小圖距左側有多少畫素(x),然後我們banckground-position:-x 0;就可以顯示出來當前我們想要的這個小圖。

用steps(n,start/end)做逐幀動畫時也是在不斷地切換顯示的背景圖片。如果按照上邊的說法,我只要量出距左側有多少畫素,來做操作,會出現一些很莫名其妙的問題。開始說明之前,我們先看看steps是什麼樣的操作。

在應用 CSS3 漸變/動畫時,有個控制時間的屬性timing-function 。它的取值中除了常用到的 貝塞爾曲線 以外,還有個讓人比較困惑的 steps() 函式。steps(n,start/end) 第一個引數 number 為指定的間隔數,即把動畫分為 n 步階段性展示,第二個引數預設為 end,設定最後一步的狀態,start 為結束時的狀態,end 為開始時的狀態。

steps 有兩個引數

1、第一個肯定是分幾步執行完

2、第二個有兩個值

2.1start 第一幀是第一步動畫結束

2.2end 第一幀是第一步動畫開始

看完上邊以為start對應的是初態,end對應的是末態,好吧!按著這個做,然後計算距左側畫素是多少,結果出來,就是不對。

為什麼呢?

W3C的解釋

steps 函式指定了一個階躍函式,第一個引數指定了時間函式中的間隔數量(必須是正整數);第二個引數可選,接受 start 和 end 兩個值,指定在每個間隔的起點或是終點發生階躍變化,預設為 end。

 

當指定躍點為 start 時,動畫在每個計時週期的起點發生階躍(即圖中 空心圓 → 實心圓 )。 由於第一次階躍發生在第一個計時週期的起點處(0s),所以我們看到的第一步動畫(初態)就為 1/3 的狀態,因此在視覺上動畫的過程為 1/3 → 2/3 → 1 。

我們看我們小人的例子,當為start時,我們看到的是視覺動畫的1/6的末狀態。會跳幀不連續。我們會想了,我們直接把這個動畫 的第一幀寫在background-position: -0 0;不就可以了麼,但是這個想多了。因為動畫開始執行的時候我們基本是看不到這個的變化的,而且重複開始之後就不再起作用了。(上邊的人裡有這個屬性,我 們是看不到第一幀的)

當指定躍點為 end,動畫則在每個計時週期的終點發生階躍(即圖中 空心圓 → 實心圓 )。 由於第一次階躍發生在第一個計時週期結束時(1s),所以我們看到的初態為 0% 的狀態;而在整個動畫週期完成處(3s),雖然發生階躍跳到了 100% 的狀態,但同時動畫結束,所以 100% 的狀態不可視。因此在視覺上動畫的過程為 0 → 1/3 → 2/3

這個時候我們在去想計算的距左側的畫素問題時,為什麼百分之百是-450px應該是最後一張小圖,但是就是不對,因為100%的狀 態是不可視的。即使有我們也沒有看到。所以我們就把距左側寫到最後一張小圖的結束位置,相當於最後一張沒有圖。當最後一幀100%狀態是也沒圖,也不需要 看到,等再重複進行時,又從第一幀開始了,動畫就連續起來了。

說完start跟end,那我們預設end的時候,只寫一個引數n,就跟上邊end的其實是一樣的。

還有一種情況是,我們分將steps中的n設為1。即我階躍一次。我控制keyframes裡邊的狀態。

測試的有6張圖,所以一個動畫從0到100分6個階段。預設是end。所以距左側要測量到下一個小圖的開始位置。

steps()動畫效果作為一個幀頻來執行

step-start:動畫一開始就跳到 100% 直到週期結束

@keyframes stepStart{ 0%{left:0;} 100%{ left:200px; } }

@-webkit-keyframes stepStart{ 0%{left:0;} 100%{ left:200px; } }

step-end:保持 0% 的樣式直到週期結束

@keyframes stepEnd{ 0%{left:0;} 100%{ left:200px; } }

@-webkit-keyframes stepEnd{ 0%{left:0;} 100%{ left:200px; } }

總結一下用法,直接預設寫就行了。圖片有多長(x),不要計算距左側的位置,直接最後background-position: -x 0;然後直接百分之百到這個位置。分幾步就讓n等於多少。參考上邊的end時的用法或者預設狀態下的用法

複製程式碼
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>animation-steps詳解</title>
    <style>
    * {
        padding: 0;
        margin: 0;
    }
    body {
        background: #ccc;
    }
    .testbox {
        padding: 20px 0 100px 0;
    }
    p {
        width: 1000px;
        line-height: 30px;
        color: #3c3c3c;
        margin: 0 auto;
        text-indent: 2em;
        padding-bottom: 10px;
    }
    p.red {
        color: #f00;
    }
    .step {
        width: 88.83333333333333px;
        height: 54px;
        margin: 10px auto;
        background: url(images/test.png) no-repeat;
        animation: step 3s steps(6) both infinite;
        -webkit-animation: step 3s steps(6) both infinite;
    }
    @keyframes step {
        100% {
            background-position: -533px 0;
        }
    }    
    @-webkit-keyframes step {
        100% {
            background-position: -533px 0;
        }
    }
    .step1 {
        width: 88.83333333333333px;
        height: 54px;
        margin: 10px auto;
        background: url(images/test.png) no-repeat;
        animation: step1 3s steps(1) both infinite;
        -webkit-animation: step1 3s steps(1) both infinite;
    }
    @keyframes step1 {
        0% {
            background-position: 0;
        }
        16.7% {
            background-position: -90px 0;
        }
        33.4% {
            background-position: -180px 0;
        }
        50.1% {
            background-position: -270px 0;
        }
        67.8% {
            background-position: -360px 0;
        }
        84.5% {
            background-position: -450px 0;
        }
        100% {
            background-position: -533px 0;
        }
    }    
    @-webkit-keyframes step1 {
        0% {
            background-position: 0;
        }
        16.7% {
            background-position: -90px 0;
        }
        33.4% {
            background-position: -180px 0;
        }
        50.1% {
            background-position: -270px 0;
        }
        67.8% {
            background-position: -360px 0;
        }
        84.5% {
            background-position: -450px 0;
        }
        100% {
            background-position: -533px 0;
        }
    }
    .step_start {
        width: 88.83333333333333px;
        height: 54px;
        margin: 10px auto;
        background: url(images/test.png) no-repeat;
        background-position: -0 0;
        animation: step_start 3s steps(6, start) both infinite;
        -webkit-animation: step_start 3s steps(6, start) both infinite;
    }
    @keyframes step_start {
        100% {
            background-position: -533px 0;
        }
    }    
    @-webkit-keyframes step_start {
        100% {
            background-position: -533px 0;
        }
    }
    .step_end {
        width: 88.83333333333333px;
        height: 54px;
        margin: 10px auto;
        background: url(images/test.png) no-repeat;
        animation: step_end 3s steps(6, end) both infinite;
        -webkit-animation: step_end 3s steps(6, end) both infinite;
    }
    @keyframes step_end {
        100% {
            background-position: -533px 0;
        }
    }   
    @-webkit-keyframes step_end {
        100% {
            background-position: -533px 0;
        }
    }
    .step-start {
        width: 1000px;
        height: 178px;
        margin: 0 auto;
        position: relative;
    }
    .step-start img {
        display: block;
        width: 192px;
        height: 178px;
        position: absolute;
        top: 0;
        left: 0;
        animation: stepStart 10s step-start 0s infinite alternate both;
        -webkit-animation: stepStart 10s step-start 0s infinite alternate both;
    }
    @keyframes stepStart {
        0% {
            left: 0;
        }
        100% {
            left: 200px;
        }
    }
    @-webkit-keyframes stepStart {
        0% {
            left: 0;
        }
        100% {
            left: 200px;
        }
    }
    .step-end {
        width: 1000px;
        height: 178px;
        margin: 0 auto;
        position: relative;
    }
    .step-end img {
        display: block;
        width: 192px;
        height: 178px;
        position: absolute;
        top: 0;
        left: 0;
        animation: stepEnd 10s step-end 0s infinite alternate both;
        -webkit-animation: stepEnd 10s step-end 0s infinite alternate both;
    }
    @keyframes stepEnd {
        0% {
            left: 0;
        }
        100% {
            left: 200px;
        }
    }
    @-webkit-keyframes stepEnd {
        0% {
            left: 0;
        }
        100% {
            left: 200px;
        }
    }
    </style>
</head>

<body>
    <div class="testbox">
        <p>在我們平時做寬高確定,需要背景圖片切換的效果時,我如果用的是一張大的png圖片。而且恰好是所有小圖都是從左向右排列的,那麼我們只需測量出某一個小圖距左側有多少畫素(x),然後我們banckground-position:-x 0;就可以顯示出來當前我們想要的這個小圖。</p>
        <p>用steps(n,start/end)做逐幀動畫時也是在不斷地切換顯示的背景圖片。如果按照上邊的說法,我只要量出距左側有多少畫素,來做操作,會出現一些很莫名其妙的問題。開始說明之前,我們先看看steps是什麼樣的操作。</p>
        <p>在應用 CSS3 漸變/動畫時,有個控制時間的屬性timing-function 。它的取值中除了常用到的 貝塞爾曲線 以外,還有個讓人比較困惑的 steps() 函式。steps(n,start/end) 第一個引數 number 為指定的間隔數,即把動畫分為 n 步階段性展示,第二個引數預設為 end,設定最後一步的狀態,start 為結束時的狀態,end 為開始時的狀態。</p>
        <p>steps 有兩個引數</p>
        <P>1、第一個肯定是分幾步執行完</P>
        <P>2、第二個有兩個值</P>
        <P>2.1start 第一幀是第一步動畫結束</P>
        <P>2.2end 第一幀是第一步動畫開始</P>
        <p>看完上邊以為start對應的是初態,end對應的是末態,好吧!按著這個做,然後計算距左側畫素是多少,結果出來,就是不對。</p>
        <p class="red">為什麼呢?</p>
        <p class="red">W3C的解釋</p>
        <p class="red">steps 函式指定了一個階躍函式,第一個引數指定了時間函式中的間隔數量(必須是正整數);第二個引數可選,接受 start 和 end 兩個值,指定在每個間隔的起點或是終點發生階躍變化,預設為 end。</p>
        <p><img src="images/step.png" alt=""></p>
        <p><img src="images/step-start.png" alt=""></p>
        <div class="step_start"></div>
        <p>當指定躍點為 start 時,動畫在每個計時週期的起點發生階躍(即圖中 空心圓 → 實心圓 )。 由於第一次階躍發生在第一個計時週期的起點處(0s),所以我們看到的第一步動畫(初態)就為 1/3 的狀態,因此在視覺上動畫的過程為 1/3 → 2/3 → 1 。</p>
        <p>我們看我們小人的例子,當為start時,我們看到的是視覺動畫的1/6的末狀態。會跳幀不連續。我們會想了,我們直接把這個動畫的第一幀寫在background-position: -0 0;不就可以了麼,但是這個想多了。因為動畫開始執行的時候我們基本是看不到這個的變化的,而且重複開始之後就不再起作用了。(上邊的人裡有這個屬性,我們是看不到第一幀的)</p>
        <p><img src="images/step-end.png" alt=""></p>
        <div class="step_end"></div>
        <p>當指定躍點為 end,動畫則在每個計時週期的終點發生階躍(即圖中 空心圓 → 實心圓 )。 由於第一次階躍發生在第一個計時週期結束時(1s),所以我們看到的初態為 0% 的狀態;而在整個動畫週期完成處(3s),雖然發生階躍跳到了 100% 的狀態,但同時動畫結束,所以 100% 的狀態不可視。因此在視覺上動畫的過程為 0 → 1/3 → 2/3 </p>
        <p>這個時候我們在去想計算的距左側的畫素問題時,為什麼百分之百是-450px應該是最後一張小圖,但是就是不對,因為100%的狀態是不可視的。即使有我們也沒有看到。所以我們就把距左側寫到最後一張小圖的結束位置,相當於最後一張沒有圖。當最後一幀100%狀態是也沒圖,也不需要看到,等再重複進行時,又從第一幀開始了,動畫就連續起來了。</p>
        <p>說完start跟end,那我們預設end的時候,只寫一個引數n,就跟上邊end的其實是一樣的。</p>
        <div class="step"></div>
        <p>還有一種情況是,我們分將steps中的n設為1。即我階躍一次。我控制keyframes裡邊的狀態。</p>
        <div class="step1"></div>
        <p>測試的有6張圖,所以一個動畫從0到100分6個階段。預設是end。所以距左側要測量到下一個小圖的開始位置。</p>
        <p>steps()動畫效果作為一個幀頻來執行</p>
        <p>step-start:動畫一開始就跳到 100% 直到週期結束</p>
        <p> @keyframes stepStart{ 0%{left:0;} 100%{ left:200px; } }</p>
        <p> @-webkit-keyframes stepStart{ 0%{left:0;} 100%{ left:200px; } }</p>
        <div class="step-start"><img src="images/section1_1.png" alt=""></div>
        <p>step-end:保持 0% 的樣式直到週期結束</p>
        <p> @keyframes stepEnd{ 0%{left:0;} 100%{ left:200px; } }</p>
        <p> @-webkit-keyframes stepEnd{ 0%{left:0;} 100%{ left:200px; } }</p>
        <div class="step-end"><img src="images/section1_1.png" alt=""></div>

        <p class="red">總結一下用法,直接預設寫就行了。圖片有多長(x),不要計算距左側的位置,直接最後background-position: -x 0;然後直接百分之百到這個位置。分幾步就讓n等於多少。參考上邊的end時的用法或者預設狀態下的用法</p>
        <div class="step"></div>
        <div class="step_end"></div>
    </div>
</body>

</html>
複製程式碼