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>