摘要:備注沒整理格式,抱歉動畫實現的幾種方式性能排序實現方式自身調用調用的定時器值推薦最小使用的原因即每秒幀為什么倒計時動畫一定要用而避免使用兩者區別及引發的線程討論線程討論為什么單線程是的一大特性。
備注:沒整理格式,抱歉
動畫實現的幾種方式:性能排序
js < requestAnimationFrame
1.setTimeout 自身調用 eg1
2.setInterval 調用 eg2
setTimeout的定時器值推薦最小使用16.7ms的原因(16.7 = 1000 / 60, 即每秒60幀)
為什么倒計時動畫一定要用setTimeout而避免使用setInterval-------兩者區別及setTimeout引發的js線程討論
1.js線程討論
1.1 為什么:單線程是JavaScript的一大特性。
JavaScript是瀏覽器用來與用戶進行交互、進行DOM操作的,這也使得了它必須是單線程這一特性。比如你去修改一個元素的DOM,同時又去刪除這個元素,那么瀏覽器應該聽誰的?
1.2 js單線程工作機制是:當線程中沒有執行任何同步代碼的前提下才會執行異步代碼
var t = true; window.setTimeout(function (){ t = false;},1000); while (t){} alert("end")
JavaScript引擎是單線程運行的,瀏覽器只有一個線程在運行JavaScript程序
1.3 瀏覽器工作基本原理
一、瀏覽器的內核是多線程的,內核制控下保持同步,
至少實現三個常駐線程:javascript引擎線程,GUI渲染線程,瀏覽器事件觸發線程(http請求線程等)
javascript引擎是基于事件驅動單線程執行的,JS引擎一直等待著任務隊列中任務的到來,然后加以處理,瀏覽器無論什么時候都只有一個JS線程在運行JS程序。
GUI渲染線程負責渲染瀏覽器界面,當界面需要重繪(Repaint)或由于某種操作引發回流(reflow)時,該線程就會執行。
但需要注意 GUI渲染線程與JS引擎是互斥的,當JS引擎執行時GUI線程會被掛起,GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執行。
事件觸發線程,當一個事件被觸發時該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理。異步事件:如setTimeOut、瀏覽器內核的其他線程如鼠標點擊、AJAX異步請求等,(當線程中沒有執行任何同步代碼的前提下才會執行異步代碼)
也就是說即使setTimeout為0,他也是等js引擎的代碼執行完之后才會插入到js引擎線程的最后執行。
1.4 JavaScript中任務,一種是同步任務,一種是異步任務。
同步任務:各個任務按照文檔定義的順序一一推入"執行棧"中,當前一個任務執行完畢,才會開始執行下一個任務。
異步任務:各個任務推入"任務隊列"中,只有在當前的所有同步任務執行完畢,才會將隊列中的任務"出隊"執行。(注:這里的異步任務并不一定是按照文檔定義的順序推入隊列中)
//只有用戶觸發點擊事件才會被推入隊列中(如果點擊時間小于定時器指定的時間,則先于定時器推入,否則反之)
1.5 "任務隊列是什么?異步任務通常包括哪些?"
任務隊列(event loop):你可理解為用于存放事件的隊列,當執行一個異步任務時,就相當于執行任務的回調函數。
通常io(ajax獲取服務器數據)、用戶/瀏覽器自執行事件(onclick、onload、onkeyup等等)以及定時器(setTimeout、setInterval)都可以算作異步操作。
先來看一段代碼來理解一下
console.log("1"); setTimeout(function(){ console.log("2"); },1000); console.log("3"); setTimeout(function(){ console.log("4"); },0); 輸出結果: 1->3->4->2.
那么在來看你這段代碼。
var t = true; window.setTimeout(function (){ t = false },1000); while (t){} alert("end"); 1.6 setTimeOut的討論
參數
描述
code
必需。要調用的函數后要執行的 JavaScript 代碼串。
millisec
必需。在執行代碼前需等待的毫秒數。
提示:setTimeout() 只執行 code 一次。如果要多次調用,請使用 setInterval() 或者讓 code 自身再次
原理:setTimeout調用的時候,JavaScript引擎會啟動定時器timer,當定時器時間到,就把該事件放到主事件隊列等待處理。
注意:瀏覽器JavaScript線程空閑的時候才會真正執行 ep3
millisec參數有什么用?
那么問題來了。setTimeout(handler,0)和setTimeout(handler,100)在多帶帶使用時,好像并沒有區別。(中間執行的代碼處理時間超過100ms時)
millisec一般在多個setTimeout一起使用的時,需要區分哪個先加入到隊列的時候才有用,否則都可以設置成setTimeout(handler,0)
1.7 SetTimeout 與 setInterval的區別
setTimeout(function(){ /* 代碼塊... */ setTimeout(arguments.callee, 10); }, 10); setInterval(function(){ /*代碼塊... */ }, 10);
setTimeout遞歸執行的代碼必須是上一次執行完了并間格一定時間才再次執行
比仿說: setTimeout延遲時間為1秒執行, 要執行的代碼需要2秒來執行,那這段代碼上一次與下一次的執行時間為3秒. 而不是我們想象的每1秒執行一次.
setInterval是排隊執行的
比仿說: setInterval每次執行時間為1秒,而執行的代碼需要2秒執行, 那它還是每次去執行這段代碼, 上次還沒執行完的代碼會排隊, 上一次執行完下一次的就立即執行, 這樣實際執行的間隔時間為2秒
這樣的話在我看來, 如果setInterval執行的代碼時間長度比每次執行的間隔段的話,就沒有意義,并且隊伍越來越長,內存就被吃光了.如果某一次執行被卡住了,那程序就會被堵死
巨坑無比的setInterval
定時器的代碼可能在代碼還沒有執行完成再次被添加到隊列,結果導致循環內的判斷條件不準確,代碼多執行幾次,之間沒有停頓。
JavaScript已經解決這個問題,當使用setInterval()時,僅當沒有該定時器的其他代碼實例時才將定時器代碼插入隊列。這樣確保了定時器代碼加入到隊列的最小時間間隔為指定間隔
某些間隔會被跳過
2.多個定時器的代碼執行之間的間隔可能比預期要小
大前端團隊 > 前端動畫實現 > image2017-11-28 14:24:25.png
5處,創建一個定時器
205處,添加一個定時器,但是onclick代碼沒執行完成,等待
300處,onclick代碼執行完畢,執行第一個定時器
405處,添加第二個定時器,但前一個定時器沒有執行完成,等待
605處,本來是要添加第三個定時器,但是此時發現,隊列中有了一個定時器,被跳過
等到第一個定時器代碼執行完畢,馬上執行第二個定時器,所以間隔會比預期的小。
二 CSS3動畫
1.tansition
transition-property 要運動的樣式 (all || [attr] || none) transition-duration 運動時間 transition-delay 延遲時間 transition-timing-function 運動形式 ease:(逐漸變慢)默認值 linear:(勻速) ease-in:(加速) ease-out:(減速) ease-in-out:(先加速后減速) cubic-bezier 貝塞爾曲線( x1, y1, x2, y2 ) http://matthewlein.com/ceaser/
transition的完整寫法如下
img { transition: 1s 1s height ease; }
多帶帶定義成各個屬性。
img{ transition-property: height; transition-duration: 1s; transition-delay: 1s; transition-timing-function: ease; }
/可以多個動畫同時運動/用逗號隔開
transition:1s width,2s height,3s background;
/可以在動畫完成時間之后添加動畫延遲執行的時間/
transition:1s width,2s 1s height,3s 3s background;
過渡完成事件
// Webkit內核: obj.addEventListener("webkitTransitionEnd",function(){},false); // firefox: obj.addEventListener("transitionend",function(){},false); /*tansition動畫發生在樣式改變的時候*/ function addEnd(obj,fn) ---封裝適應與各個瀏覽器的動畫結束 { //動畫執行完執行該函數 obj.addEventListener("WebkitTransitionEnd",fn,false); obj.addEventListener("transitionend",fn,false); //標準 } addEnd(oBox,function(){ alert("end"); }); // 面臨兩個bug:1.tansition中有多個動畫時,每個執行完,都會有一個結束彈出 // 2.發生重復調用的情況--需要移除 //移除動畫執行完的操作 function removeEnd(obj,fn) } obj.removeEventListener("transitionend",fn,false); obj.removeEventListener("WebkitTransitionEnd",fn,false); {
使用注意
(1)不是所有的CSS屬性都支持transition http://oli.jp/2010/css-animatable-properties/ http://leaverou.github.io/animatable/ (2)transition需要明確知道,開始狀態和結束狀態的具體數值,才能計算出中間狀態 transition的局限 transition的優點在于簡單易用,但是它有幾個很大的局限。 (1)transition需要事件觸發,所以沒法在網頁加載時自動發生。 (2)transition是一次性的,不能重復發生,除非一再觸發。 (3)transition只能定義開始狀態和結束狀態,不能定義中間狀態,也就是說只有兩個狀態。 (4)一條transition規則,只能定義一個屬性的變化,不能涉及多個屬性。
CSS Animation就是為了解決這些問題而提出的。
2.transform
rotate() 旋轉函數 取值度數 deg 度數 -origin 旋轉的基點 skew() 傾斜函數 取值度數 skewX() skewY() scale() 縮放函數 取值 正數、負數和小數 scaleX() scaleY() translate() 位移函數 translateX() translateY()
Transform 執行順序問題 — 后寫先執行
-webkit-transform:rotate(360deg); 旋轉原點可以是關鍵字+像素位置:相對于左上角作為零點:正為下,右 -webkit-transform-origin:right bottom; -webkit-transform-origin:200px 200px; 一個transform可以有多個值: -webkit-transform:rotate(360deg) scale(0.2); -webkit-transform:skewX(45deg); -webkit-transform:skewY(45deg); -webkit-transform:skew(15deg,30deg);
3.Animation 關鍵幀——keyFrames
只需指明兩個狀態,之間的過程由計算機自動計算
關鍵幀的時間單位
數字:0%、25%、100%等
字符:from(0%)、to(100%)
格式
@keyframes 動畫名稱 { 動畫狀態 } @keyframes miaov_test { from { background:red; } to { background:green; } }
可以只有to
必要屬性
animation-name 動畫名稱(關鍵幀名稱)
animation-duration 動畫持續時間
屬性:
animation-play-state 播放狀態( running 播放 和paused 暫停 )
animation-timing-function 動畫運動形式
linear 勻速。
ease 緩沖。
ease-in 由慢到快。
ease-out 由快到慢。
ease-in-out 由慢到快再到慢。
cubic-bezier(number, number, number, number): 特定的貝塞爾曲線類型,4個數值需在[0, 1]區間內
animation-delay 動畫延遲只是第一次
animation-iteration-count 重復次數/infinite為無限次
animation-direction 播放前重置/動畫是否重置后再開始播放
alternate 動畫直接從上一次停止的位置開始執行
normal 動畫第二次直接跳到0%的狀態開始執行
reverse
alternate-reverse
animation-fill-mode
forwards 讓動畫保持在結束狀態
none:默認值,回到動畫沒開始時的狀態。
backwards:讓動畫回到第一幀的狀態。
both: 根據animation-direction(見后)輪流應用forwards和backwards規則。
animation-play-state
paused
running
動畫播放過程中,會突然停止。這時,默認行為是跳回到動畫的開始狀態,想讓動畫保持突然終止時的狀態,就要使用animation-play-state屬性
大前端團隊 > 前端動畫實現 > image2017-11-28 14:29:8.png
animation也是一個簡寫形式
div:hover { animation: 1s 1s rainbow linear 3 forwards normal; }
分解成各個多帶帶的屬性
div:hover { animation-name: rainbow; animation-duration: 1s; animation-timing-function: linear; animation-delay: 1s; animation-fill-mode:forwards; animation-direction: normal; animation-iteration-count: 3; }
Animation與Js的結合
通過class,在class里加入animation的各種屬性
直接給元素加-webkit-animation-xxx樣式
animation的問題
寫起來麻煩
沒法動態改變目標點位置
animation的函數:
obj.addEventListener("webkitAnimationEnd", function (){}, false);
實例1:無縫滾動
animation的step
eg: http://dabblet.com/gist/1745856
animation-timing-function: steps(30, end)
1.什么時候使用:
animation默認以ease方式過渡,它會在每個關鍵幀之間插入補間動畫,所以動畫效果是連貫性的,除了ease,linear、cubic-bezier之類的過渡函數都會為其插入補間。但有些效果不需要補間,只需要關鍵幀之間的跳躍,這時應該使用steps過渡方式
大前端團隊 > 前端動畫實現 > image2017-11-28 14:29:45.png
線性動畫: http://sandbox.runjs.cn/show/...
幀動畫:http://sandbox.runjs.cn/show/...
2.step使用:
語法:
steps(number[, end | start])
參數說明:
number參數指定了時間函數中的間隔數量(必須是正整數)
第二個參數是可選的,可設值:start和end,表示在每個間隔的起點或是終點發生階躍變化,如果忽略,默認是end。
大前端團隊 > 前端動畫實現 > image2017-11-28 14:30:37.png
橫軸表示時間,縱軸表示動畫完成度(也就是0%~100%)。
第一個圖,steps(1, start)將動畫分為1段,跳躍點為start,也就是說動畫在每個周期的起點發生階躍(即圖中的空心圓 → 實心圓)。由于只有一段,后續就不再發生動畫了。
第二個圖,steps(1, end)同樣是將動畫分為1段,但跳躍點是end,也就是動畫在每個周期的終點發生階躍,也是圖中的空心圓 → 實心圓,但注意時間,是在終點才發生動畫。
第三個圖,steps(3, start)將動畫分為三段,跳躍點為start,動畫在每個周期的起點發生階躍(即圖中的空心圓 → 實心圓)。在這里,由于動畫的第一次階躍是在第一階段的起點處(0s),所以我們看到的動畫的初始狀態其實已經是 1/3 的狀態,因此我們看到的動畫的過程為 1/3 → 2/3 → 1 。
第四個圖,steps(3, end)也是將動畫分為三段,但跳躍點為end,動畫在每個周期的終點發生階躍(即圖中的空心圓 → 實心圓)。雖然動畫的狀態最終會到達100%,但是動畫已經結束,所以100%的狀態是看不到的,因此我們最終看到的動畫的過程是0 → 1/3 → 2/3。
https://idiotwu.me/study/timi...
steps第一個參數的錯誤的理解:
第一個參數 number 為指定的間隔數,即把動畫分為 n 步階段性展示,估計大多數人理解就是keyframes寫的變化次數
@-webkit-keyframes circle { 0% {background-position-x: 0;} 100%{background-position-x: -400px;} }
@-webkit-keyframes circle { 0% {} 25%{} 50%{} 75%{} 100%{} }
如果有多個幀動畫
@-webkit-keyframes circle { 0% {background-position-x: 0;} 50% {background-position-x: -200px;} 100%{background-position-x: -400px;} }
0-25 之間變化5次, 25-50之間 變化5次 ,50-75 之間變化5次,以此類推
應用:
Sprite 精靈動畫 2D游戲
https://idiotwu.me/css3-runni...
4.3D轉換
父容器:
transform-style(preserve-3d) 建立3D空間
Perspective 景深
Perspective- origin 景深基點
子元素:
Transform 新增函數
rotateX()
rotateY()
rotateZ()
translateZ()
scaleZ()
實例1:3D盒子
http://beiyuu.com/css3-animation
使用實例:
requestAnimationFrame
是什么
js的一個API
該方法通過在系統準備好繪制動畫幀時調用該幀,從而為創建動畫網頁提供了一種更平滑更高效的方法
使用
var handle = setTimeout(renderLoop, PERIOD);
var handle = window.requestAnimationFrame(renderLoop);
window.cancelAnimationFrame(handle);
為什么出現
css:
統一的向下兼容策略 IE8, IE9之流
CSS3動畫不能應用所有屬性 scrollTop值。如果我們希望返回頂部是個平滑滾動效果
CSS3支持的動畫效果有限 CSS3動畫的貝塞爾曲線是一個標準3次方曲線
緩動(Tween)知識:
Linear:無緩動效果
Quadratic:二次方的緩動(t^2)
Cubic:三次方的緩動(t^3)
Quartic:四次方的緩動(t^4)
Quintic:五次方的緩動(t^5)
Sinusoidal:正弦曲線的緩動(sin(t))
Exponential:指數曲線的緩動(2^t)
Circular:圓形曲線的緩動(sqrt(1-t^2))
Elastic:指數衰減的正弦曲線緩動
超過范圍的三次方緩動((s+1)t^3 – st^2)
指數衰減的反彈緩動
js:
1.延遲時間固定導致了動畫過度繪制,浪費 CPU 周期以及消耗額外的電能等問題
2.即使看不到網站,特別是當網站使用背景選項卡中的頁面或瀏覽器已最小化時,動畫都會頻繁出現
大前端團隊 > 前端動畫實現 > image2017-11-28 14:31:6.png
相當一部分的瀏覽器的顯示頻率是16.7ms
搞個10ms setTimeout,就會是下面一行的模樣——每第三個圖形都無法繪制
顯示器16.7ms刷新間隔之前發生了其他繪制請求(setTimeout),導致所有第三幀丟失,繼而導致動畫斷續顯示(堵車的感覺),這就是過度繪制帶來的問題
requestAnimationFrame 與setTimeout相似,都是延遲執行,不過更智能,跟著瀏覽器的繪制走,如果瀏覽設備繪制間隔是16.7ms,那我就這個間隔繪制;如果瀏覽設備繪制間隔是10ms, 我就10ms繪制,瀏覽器(如頁面)每次要重繪,就會通知(requestAnimationFrame)
頁面最小化了,或者被Tab切換當前頁面不可見。頁面不會發生重繪
兼容性
Android設備不支持,其他設備基本上跟CSS3動畫的支持一模一樣
https://developer.mozilla.org...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102297.html
摘要:返回頂部這里初始狀態的返回頂部為不可見,通過判斷頁面滾動高度切換顯示隱藏,的樣式可以自己設計。 showImg(https://segmentfault.com/img/bVGDef?w=1390&h=540); 返回頂部的按鈕大家并不陌生,針對長滾動條的信息流頁面添加返回頂部的按鈕可以給用戶良好的體驗,而返回頂部的實現也是多種多樣,本文分享幾個案例并給出評價 作為引子講一個常用的案例...
摘要:返回頂部這里初始狀態的返回頂部為不可見,通過判斷頁面滾動高度切換顯示隱藏,的樣式可以自己設計。 showImg(https://segmentfault.com/img/bVGDef?w=1390&h=540); 返回頂部的按鈕大家并不陌生,針對長滾動條的信息流頁面添加返回頂部的按鈕可以給用戶良好的體驗,而返回頂部的實現也是多種多樣,本文分享幾個案例并給出評價 作為引子講一個常用的案例...
摘要:道阻且長啊前端面試總結前端面試筆試面試騰訊一面瀏覽器工作原理瀏覽器的主要組件包括用戶界面包括地址欄后退前進按鈕書簽目錄瀏覽器引擎用來查詢及操作渲染引擎的接口渲染引擎渲染界面和是基于兩種渲染引擎構建的,使用自主研發的渲染引擎,和都使用網絡用來 道阻且長啊TAT(前端面試總結) 前端 面試 筆試 面試 騰訊一面 1.瀏覽器工作原理 瀏覽器的主要組件包括: 用戶界面- 包括地址欄、后退/前...
摘要:道阻且長啊前端面試總結前端面試筆試面試騰訊一面瀏覽器工作原理瀏覽器的主要組件包括用戶界面包括地址欄后退前進按鈕書簽目錄瀏覽器引擎用來查詢及操作渲染引擎的接口渲染引擎渲染界面和是基于兩種渲染引擎構建的,使用自主研發的渲染引擎,和都使用網絡用來 道阻且長啊TAT(前端面試總結) 前端 面試 筆試 面試 騰訊一面 1.瀏覽器工作原理 瀏覽器的主要組件包括: 用戶界面- 包括地址欄、后退/前...
閱讀 1061·2023-04-26 02:02
閱讀 2401·2021-09-26 10:11
閱讀 3553·2019-08-30 13:10
閱讀 3743·2019-08-29 17:12
閱讀 719·2019-08-29 14:20
閱讀 2187·2019-08-28 18:19
閱讀 2229·2019-08-26 13:52
閱讀 954·2019-08-26 13:43