由奥迪车灯想到的前端动画
先來看看我們需要實現的效果:預覽
方法一:css
首先,想到的自然是css,因為css動畫功能很強大,且這種方式代碼簡單,效果順滑,強烈推薦。代碼如下:
<div class="css-light"></div> div.css-light {width: 0%;height: 6px;background: #ff8908;animation: mymove 1s ease-out infinite; } @keyframes mymove {from {width: 0%;}to {width: 100%;} }其中,核心屬性是animation。那animation怎么用呢?如下:
第一個屬性指定要綁定到選擇器的關鍵幀的名稱,本例是mymove;
第二個屬性指定動畫指定需要多少秒或毫秒完成,本例是1s;
第三個屬性設置動畫將如何完成一個周期,默認是ease,本例是ease-out,表示動畫以低速結束;
第四個屬性定義動畫的播放次數,本例是無限循環;
由此可見,css的animation是真的強大,還支持多種動畫效果,比如ease-out這種效果,如果你要用js模擬ease-out等多種效果,那可就不是一行代碼的事兒了。
更多參數信息請參考:
CSS3 animation(動畫) 屬性
animation
方法二:js方法
除開css,js也給與了模擬動畫的能力,這種方式通常使用 setInterval()方法來控制動畫,代碼如下:
<div id="process"></div> let div = document.getElementById('process')function process() {div.style.width = '0%'setInterval(() => {div.style.width = (parseInt(div.style.width, 10) + 1) + '%'if (div.style.width === '100%') {div.style.width = '0%'}}, 20) } process()但這種方法有幾個弊端。
第一個就是不十分精確,為它傳入的第二個參數(如本例中的20),實際上只是指定了把動畫代碼添加到瀏覽器 UI 線程隊列中以等待執行的時間。如果隊列前面已經加入了其他任務,那動畫代碼就要等前面的任務完成后再執行。也就是說,以毫秒表示的延遲時間并不代表到時候一定會執行動畫代碼,而僅代表到時候會把代碼添加到任務隊列中。如果 UI 線程繁忙,比如忙于處理用戶操作,那么即使把代碼加入隊列也不會立即執行。
第二個弊端就是編寫動畫循環需要知道延遲時間多長合適。一方面,循環間隔必須足夠短,這樣才能讓不同的動畫效果顯得平滑流暢;另一方面,循環間隔還要足夠長,這樣才能確保瀏覽器有能力渲染產生的變化。拿本例來說,如果將20改成200,那么你會發現動畫效果會顯得一卡一卡的。而由20改成1,那么動畫會執行的非常快,并且性能的開銷也會增加。
第三個弊端是setInterval它的開銷也比較大,即便頁面后臺運行,這個開銷也一直存在。
那么,這些個弊端能不能優化呢?是時候讓requestAnimationFrame出場了!
與setInterval相比,requestAnimationFrame最大的優勢是由系統來決定回調函數的執行時機。
具體來說,如果屏幕刷新率是60Hz,那么回調函數就每16.7ms被執行一次,如果刷新率是75Hz,那么這個時間間隔就變成了1000/75=13.3ms,換句話說就是,requestAnimationFrame的步伐跟著系統的刷新步伐走。它能保證回調函數在屏幕每一次的刷新間隔中只被執行一次,這樣就不會引起丟幀現象,也不會導致動畫出現卡頓的問題。省心!用了它,你就再也不用糾結到底循環間隔設置為多少合適了,它幫你干了這事。
它的用法很簡單,用requestAnimationFrame方式改寫如下:
function updateProgress () {let div = document.getElementById('process')div.style.width = (parseInt(div.style.width, 10) + 1) + '%'if (div.style.width === '100%') {div.style.width = '0%'}window.requestAnimationFrame(updateProgress); } window.requestAnimationFrame(updateProgress);關于更多requestAnimationFrame的信息,請參考:
深入理解 requestAnimationFrame
window.requestAnimationFrame
真實情況
本文模擬了一個簡單的車燈動畫效果,從中引出了一些前端動畫方面的知識,并用二種不同的方式進行了實現(css和js)。
最后說下,在汽車上真實的效果應該是由多個led燈來實現的,我這里提供一種方法(借助vue),供大家參考,有興趣的同學可以用其他的方法自行模擬和拓展。
預覽(需要翻墻),核心代碼如下:
總結
以上是生活随笔為你收集整理的由奥迪车灯想到的前端动画的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 搜狐新闻如何关闭听新闻(搜狐电视剧频道)
- 下一篇: 魔兽世界黑上火抗buff怎么加 《魔兽世