摘要:貝塞爾曲線貝塞爾曲線是應(yīng)用于二維圖形應(yīng)用程序的數(shù)學(xué)曲線。通過調(diào)整控制點(diǎn),貝塞爾曲線的形狀會(huì)發(fā)生變化。讓我們看看貝塞爾曲線的工作原理。貝塞爾曲線需要四個(gè)值,或者更準(zhǔn)確地說它需要兩對(duì)數(shù)字。每對(duì)描述立方貝塞爾曲線控制點(diǎn)的和坐標(biāo)。
這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 13 篇。
如果你錯(cuò)過了前面的章節(jié),可以在這里找到它們:
JavaScript 是如何工作的:引擎,運(yùn)行時(shí)和調(diào)用堆棧的概述!
JavaScript 是如何工作的:深入V8引擎&編寫優(yōu)化代碼的5個(gè)技巧!
JavaScript 是如何工作的:內(nèi)存管理+如何處理4個(gè)常見的內(nèi)存泄漏 !
JavaScript 是如何工作的:事件循環(huán)和異步編程的崛起+ 5種使用 async/await 更好地編碼方式!
JavaScript 是如何工作的:深入探索 websocket 和HTTP/2與SSE +如何選擇正確的路徑!
JavaScript 是如何工作的:與 WebAssembly比較 及其使用場景 !
JavaScript 是如何工作的:Web Workers的構(gòu)建塊+ 5個(gè)使用他們的場景!
JavaScript 是如何工作的:Service Worker 的生命周期及使用場景!
JavaScript 是如何工作的:Web 推送通知的機(jī)制!
JavaScript是如何工作的:使用 MutationObserver 跟蹤 DOM 的變化!
JavaScript是如何工作的:渲染引擎和優(yōu)化其性能的技巧!
JavaScript是如何工作的:深入網(wǎng)絡(luò)層 + 如何優(yōu)化性能和安全!
想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你!
概述你肯定知道,動(dòng)畫在創(chuàng)建引人注目的 Web 應(yīng)用程序中扮演著重要的角色。隨著用戶越來越多地將注意力轉(zhuǎn)移到用戶體驗(yàn)上,商戶開始意識(shí)到完美、愉快的用戶體驗(yàn)的重要性,結(jié)果 Web 應(yīng)用程序變得越來越重,并具有更動(dòng)態(tài)交互的 UI。這一切都需要更復(fù)雜的動(dòng)畫,以便用戶在整個(gè)過程中更平穩(wěn)地進(jìn)行狀態(tài)轉(zhuǎn)換。今天,這甚至不被認(rèn)為是什么特別的事情。用戶正變得越來越挑剔,默認(rèn)情況下,他們期望的是具有高響應(yīng)性和交互性的用戶界面。
然而,界面的動(dòng)畫化并不一定是簡單的。什么是動(dòng)畫,什么時(shí)候該用動(dòng)畫,動(dòng)畫應(yīng)該有什么樣的視頻效果,這些都是棘手的問題。
JavaScript 和 CSS 動(dòng)畫比較創(chuàng)建 Web 動(dòng)畫的兩種主要方法是使用JavaScript和 CSS。選擇哪種沒有對(duì)或錯(cuò),這完全取決于你想要達(dá)到的效果。
CSS 動(dòng)畫用CSS制作動(dòng)畫是讓元素在屏幕上移動(dòng)的最簡單方法。
這里將從如何讓元素在 X 和 Y 軸上移動(dòng) 50px 簡單示例開始,通過持續(xù) 1 秒的 CSS 過渡來移動(dòng)元素。
.box { -webkit-transform: translate(0, 0); -webkit-transition: -webkit-transform 1000ms; transform: translate(0, 0); transition: transform 1000ms; } .box.move { -webkit-transform: translate(50px, 50px); transform: translate(50px, 50px); }
當(dāng)元素加上 move 類時(shí),改變 transform 的值然后開發(fā)發(fā)生過渡效果。
除了轉(zhuǎn)換持續(xù)時(shí)間外,還有 easing 屬性,這實(shí)際上就是動(dòng)畫的運(yùn)動(dòng)速度方式,該參數(shù)會(huì)在之后詳細(xì)介紹。
如果像上面的代碼片段一樣,創(chuàng)建多帶帶的 CSS 類來實(shí)現(xiàn)動(dòng)畫,當(dāng)然也可以使用 JavaScript 來切換每個(gè)動(dòng)畫。
如下元素:
div class="box"> Sample content.
然后,使用 JavaScript 來切換每個(gè)動(dòng)畫。
var boxElements = document.getElementsByClassName("box"), boxElementsLength = boxElements.length, i; for (i = 0; i < boxElementsLength; i++) { boxElements[i].classList.add("move"); }
上面的代碼片段是為所有包含 box 類的元素為其添加 move 類以觸發(fā)動(dòng)畫。
這樣做可以為你的應(yīng)用提供良好的平衡。 你可以專注于使用 JavaScript 管理狀態(tài),只需在目標(biāo)元素上設(shè)置適當(dāng)?shù)念悾尀g覽器處理動(dòng)畫。 如果沿著這條路線前進(jìn),你可以在元素上監(jiān)聽 transitionend 事件,但前提是放棄舊版 Internet Explorer 的支持:
監(jiān)聽 transitionend 觸發(fā)的事件如下所示:
var boxElement = document.querySelector(".box"); boxElement.addEventListener("transitionend", onTransitionEnd, false); function onTransitionEnd() { // Handle the transition finishing. }
除了使用 CSS 過渡之外,你還可以使用 CSS 動(dòng)畫,CSS 動(dòng)畫可以讓你更好地控制多帶帶的動(dòng)畫關(guān)鍵幀,持續(xù)時(shí)間以及循環(huán)次數(shù)。
關(guān)鍵幀用于指示瀏覽器 CSS 屬性在給定時(shí)間點(diǎn)上應(yīng)有的 CSS 屬性,然后填充空白。
來個(gè)簡單的例子:
.box { /* 動(dòng)畫的名字 */ animation-name: movingBox; /* 動(dòng)畫的持續(xù)時(shí)間 */ animation-duration: 2300ms; /* 動(dòng)畫的運(yùn)行次數(shù) */ animation-iteration-count: infinite; /* 設(shè)置對(duì)象動(dòng)畫在循環(huán)中是否反向運(yùn)動(dòng)的方法 */ animation-direction: alternate; } @keyframes movingBox { 0% { transform: translate(0, 0); opacity: 0.4; } 25% { opacity: 0.9; } 50% { transform: translate(150px, 200px); opacity: 0.2; } 100% { transform: translate(40px, 30px); opacity: 0.8; } }
效果示例: https://sessionstack.github.i...
使用CSS動(dòng)畫,你可以獨(dú)立于目標(biāo)元素定義動(dòng)畫本身,并使用 animation-name 屬性來選擇所需的動(dòng)畫。
CSS 動(dòng)畫在某種程度仍然需要加瀏覽器前綴的,在 Safari、Safari Mobile 和 Android 中都使用了 -webkit。 Chrome、 Opera、Internet Explorer 和 Firefox 都不需要添加前綴。許多工具可以幫助你創(chuàng)建所需 CSS 的前綴,這樣就不需要在源文件中帶樣式前綴。
JavaScript 動(dòng)畫和 CSS 過渡或者 CSS 動(dòng)畫相比,使用 JavaScript 創(chuàng)建動(dòng)畫更加復(fù)雜,但它通常為開發(fā)人員提供了更強(qiáng)大的功能。
JavaScript 動(dòng)畫是作為代碼的一部分內(nèi)聯(lián)編寫的。你還可以將它們封裝在其他對(duì)象中。以下為用 JavaScript 來實(shí)現(xiàn)最開始的 CSS 過渡的代碼:
var boxElement = document.querySelector(".box"); var animation = boxElement.animate([ {transform: "translate(0)"}, {transform: "translate(150px, 200px)"} ]) animation.addEventListener("finish", function() { boxElement.style.transform = "translate(150px, 200px)"; })
默認(rèn)情況下,Web 動(dòng)畫僅修改元素的展示效果。 如果要將對(duì)象停留在移動(dòng)后的位置,則應(yīng)在動(dòng)畫完成時(shí)修改其基礎(chǔ)樣式。 這就是為什么在上面的例子中監(jiān)聽 finish 事件,并將 box.style.transform 屬性設(shè)置為 translate(150px, 200px),該屬性值和 CSS 動(dòng)畫執(zhí)行的第二個(gè)樣式轉(zhuǎn)換是一樣的。
使用 JavaScript 動(dòng)畫,你可以在每一步完全控制元素的樣式。 這意味著你可以放慢動(dòng)畫速度,暫停動(dòng)畫,停止它們,翻轉(zhuǎn)它們,并根據(jù)需要操縱元素。 如果你正在構(gòu)建復(fù)雜的面向?qū)ο蟮膽?yīng)用程序,這尤其有用,因?yàn)槟憧梢哉_地封裝你想要的動(dòng)畫行為。
Easing 定義自然過渡效果會(huì)讓你的用戶對(duì)你的 Web 應(yīng)用程序感覺更舒服,從而帶來更好的用戶體驗(yàn)。
當(dāng)然,沒有任何東西從一個(gè)點(diǎn)到另一個(gè)點(diǎn)線性移動(dòng)。 實(shí)際上,當(dāng)事物在我們周圍的物理世界中移動(dòng)時(shí),事物往往會(huì)加速或減速,因?yàn)槲覀儾皇窃谡婵罩校⑶矣胁煌囊蛩貢?huì)影響這一點(diǎn)。 人類的大腦會(huì)期望感受這樣的移動(dòng),所以當(dāng)為網(wǎng)絡(luò)應(yīng)用制作動(dòng)畫的時(shí)候,利用此類知識(shí)會(huì)對(duì)自己會(huì)有好處。
以下是一些術(shù)語需要了解一下:
ease in —? 相對(duì)于勻速,開始的時(shí)候慢,之后快
ease out — 相對(duì)于勻速,開始時(shí)快,結(jié)束時(shí)候間慢
ease-in-out — 相對(duì)于勻速,開始和結(jié)束都慢)兩頭慢
Easing 關(guān)鍵字CSS 過渡和動(dòng)畫允許你選擇要使用的 easing 類型。 不同的關(guān)鍵字會(huì)影響動(dòng)畫的 easing,你也可以完全自定義 easing 方法。
以下為可以選擇用來控制 easing 的 CSS 關(guān)鍵字:
linear
ease-in
ease-out
ease-in-out
讓我們深入來了解一下這幾個(gè)兄弟,并看它們各自展示的效果是怎么樣。
Linear 動(dòng)畫easing 方法的的默認(rèn)為 linear,以下為 linear 過渡效果的圖示:
隨著時(shí)間增加,值等比增加,使用 linear 動(dòng)效,會(huì)讓動(dòng)畫不自然,一般來說,避免使用 linear 動(dòng)效。
以下是如何實(shí)現(xiàn)簡單的線性動(dòng)畫:
transition: transform 500ms linear;Ease-out 動(dòng)畫
如前所述,與線性動(dòng)畫相比,easing out 動(dòng)畫開始時(shí)快,結(jié)束時(shí)候間慢,過渡效果的圖示如下:
一般來說,easing out過渡效果是最適合做界面體驗(yàn)的,因?yàn)榭焖俚貑?dòng)會(huì)給人以快速響應(yīng)的動(dòng)畫的感覺,而結(jié)束時(shí)讓人感覺很平滑這得歸功于不一致的移動(dòng)速度。
有很多方法可以實(shí)現(xiàn) ease-out 效果,但最簡單的是 CSS 中的 ease-out 關(guān)鍵字:
transition: transform 500ms ease-out;Ease-in 動(dòng)畫
和 ease-out 動(dòng)畫相反-開始時(shí)快,結(jié)束時(shí)候間慢,過渡效果圖如下:
與 ease-out 動(dòng)畫相比, ease-in 可能會(huì)讓人感到不尋常,由于啟動(dòng)緩慢給人以反應(yīng)卡頓的感覺,因此會(huì)產(chǎn)生一種無反應(yīng)的感覺。 動(dòng)畫結(jié)束很快也會(huì)產(chǎn)生一種奇怪的感覺,因?yàn)檎麄€(gè)動(dòng)畫正在加速,而現(xiàn)實(shí)世界中的物體在突然停止時(shí)往往會(huì)減速。
和 ease-out 和 linear 動(dòng)畫類似,使用 CSS 關(guān)鍵字來實(shí)現(xiàn) ease-in 動(dòng)畫:
transition: transform 500ms ease-in;Ease-in-out 動(dòng)畫
該動(dòng)畫為 ease-in 和 ease-out 的合集,過渡效果圖如下:
不要使用太長的動(dòng)畫持續(xù)時(shí)間,因?yàn)樗鼈儠?huì)讓你的 UI 感覺沒有響應(yīng)。
用 ease-in-out CSS 關(guān)鍵字來實(shí)現(xiàn) ease-in-out 動(dòng)畫:
transition: transform 500ms ease-in-out;自定義 easing
你也可以定義自己的 easing 曲線,這可以更好地創(chuàng)建自己想要的動(dòng)畫效果。
實(shí)際上, ease-in,linear 及 ease 關(guān)鍵字映射到預(yù)定義 貝塞爾曲線 ,可以在 CSS transitions specification 和 Web Animations specification 中查找更多關(guān)于貝塞爾曲線的內(nèi)容。
貝塞爾曲線 (Bézier curves)Bézier curve(貝塞爾曲線)是應(yīng)用于二維圖形應(yīng)用程序的數(shù)學(xué)曲線。 曲線定義:起始點(diǎn)、終止點(diǎn)(也稱錨點(diǎn))、控制點(diǎn)。通過調(diào)整控制點(diǎn),貝塞爾曲線的形狀會(huì)發(fā)生變化。 1962年,法國數(shù)學(xué)家Pierre Bézier第一個(gè)研究了這種矢量繪制曲線的方法,并給出了詳細(xì)的計(jì)算公式,因此按照這樣的公式繪制出來的曲線就用他的姓氏來命名,稱為貝塞爾曲線。
CSS3 transition-timing-function 屬性,其語法如下:
transition-timing-function: linear|ease|ease-in|ease-out|ease-in-out|cubic-bezier(n,n,n,n);
總而言之可以用cubic-bezier(n,n,n,n)的形式來表示全部的屬性值,這里就涉及到貝塞爾曲線(Bézier curve)。
讓我們看看貝塞爾曲線的工作原理。 貝塞爾曲線需要四個(gè)值,或者更準(zhǔn)確地說它需要兩對(duì)數(shù)字。 每對(duì)描述立方貝塞爾曲線控制點(diǎn)的 X 和 Y 坐標(biāo)。貝塞爾曲線的起點(diǎn)有一個(gè)坐標(biāo) (0, 0) ,結(jié)束坐標(biāo)是 (1, 1)。 你可以設(shè)置兩個(gè)對(duì)號(hào),兩個(gè)控制點(diǎn)的 X 值必須在 [0,1] 范圍內(nèi),并且每個(gè)控制點(diǎn)的 Y 值可以超過 [0,1] 限制,盡管規(guī)定不清楚多少。
即使每個(gè)控制點(diǎn)的 X 和 Y 值稍有變化,也會(huì)得到完全不同的曲線。讓我們看兩張貝塞爾曲線的圖,兩張圖相近但坐標(biāo)的控制結(jié)點(diǎn)卻不同。
和
如您所見,兩張圖有很大的不同, 第一個(gè)控制點(diǎn)矢量差為 (0.045,0.183) 矢量差,而第二控制點(diǎn)矢量差為 (-0.427, -0.054) 。
第二條曲線的樣式為:
transition: transform 500ms cubic-bezier(0.465, 0.183, 0.153, 0.946);
前兩個(gè)數(shù)字是第一個(gè)控制點(diǎn)的 X 和 Y 坐標(biāo),后兩個(gè)數(shù)字是第二個(gè)控制點(diǎn)的 X 和 Y 坐標(biāo)。
性能優(yōu)化當(dāng)你在使用動(dòng)畫的時(shí)候,你應(yīng)該維持 60 幀每秒,否則會(huì)影響用戶體驗(yàn)。
和世界上的其他事物一樣,動(dòng)畫也會(huì)有性能的開銷。一些屬性的動(dòng)畫性能開銷相比其它屬性要小。例如,為元素的 width 和 height 做動(dòng)畫會(huì)更改其幾何結(jié)構(gòu)并且可能會(huì)造成頁面上的其它元素移動(dòng)或者大小的改變,這個(gè)過程稱為布局。我們在之前的一篇文章 中更詳細(xì)地討論了布局和渲染。
通常,你應(yīng)該避免動(dòng)畫觸發(fā)布局或重繪的屬性。 對(duì)于大多數(shù)現(xiàn)代瀏覽器,這意味著把動(dòng)畫局限于 opacity 和 transform 屬性。
Will-change你可以使用 will-change 知瀏覽器你打算更改元素的屬性,這允許瀏覽器在進(jìn)行更改之前進(jìn)行最適當(dāng)?shù)膬?yōu)化。但是,不要過度使用 will-change,因?yàn)檫@樣做會(huì)導(dǎo)致瀏覽器浪費(fèi)資源,從而導(dǎo)致更多的性能問題。
will-change 用法如下:
.box { will-change: transform, opacity; }
該屬性在 Chrome, Firefox,Opera 得到很好的兼容。
JavaScript 動(dòng)畫和 CSS 動(dòng)畫該如果抉擇根據(jù) Google Developer,渲染線程分為 主線程 (main thread) 和 合成線程 (compositor thread)。如果 CSS 動(dòng)畫只是改變 transforms 和 opacity,這時(shí)整個(gè) CSS 動(dòng)畫得以在 合成線程 完成(而JS動(dòng)畫則會(huì)在 主線程 執(zhí)行,然后觸發(fā)合成線程進(jìn)行下一步操作),在 JS 執(zhí)行一些昂貴的任務(wù)時(shí),主線程繁忙,CSS 動(dòng)畫由于使用了合成線程可以保持流暢
在許多情況下,也可以由合成線程來處理 transforms 和 opacity 屬性值的更改。
對(duì)于幀速表現(xiàn)不好的低版本瀏覽器,CSS3可以做到自然降級(jí),而JS則需要撰寫額外代碼。
CSS動(dòng)畫有天然事件支持(TransitionEnd、AnimationEnd,但是它們都需要針對(duì)瀏覽器加前綴),JS則需要自己寫事件。
如果有任何動(dòng)畫觸發(fā)繪畫,布局或兩者,則需要 “主線程” 才能完成工作。 這對(duì)于基于 CSS 和 JavaScript 的動(dòng)畫都是如此,布局或繪制的開銷可能會(huì)使與 CSS 或 JavaScript 執(zhí)行相關(guān)的任何工作相形見絀,這使得問題沒有實(shí)際意義。
CSS3有兼容性問題,而JS大多時(shí)候沒有兼容性問題。
總結(jié)如果動(dòng)畫只是簡單的狀態(tài)切換,不需要中間過程控制,在這種情況下,css 動(dòng)畫是優(yōu)選方案。它可以讓你將動(dòng)畫邏輯放在樣式文件里面,而不會(huì)讓你的頁面充斥 Javascript 庫。然而如果你在設(shè)計(jì)很復(fù)雜的富客戶端界面或者在開發(fā)一個(gè)有著復(fù)雜 UI 狀態(tài)的 APP。那么你應(yīng)該使用 js 動(dòng)畫,這樣你的動(dòng)畫可以保持高效,并且你的工作流也更可控。所以,在實(shí)現(xiàn)一些小的交互動(dòng)效的時(shí)候,就多考慮考慮 CSS 動(dòng)畫。對(duì)于一些復(fù)雜控制的動(dòng)畫,使用 javascript 比較可靠。
原文:
https://blog.sessionstack.com...
代碼部署后可能存在的BUG沒法實(shí)時(shí)知道,事后為了解決這些BUG,花了大量的時(shí)間進(jìn)行l(wèi)og 調(diào)試,這邊順便給大家推薦一個(gè)好用的BUG監(jiān)控工具 Fundebug。
你的點(diǎn)贊是我持續(xù)分享好東西的動(dòng)力,歡迎點(diǎn)贊!
交流干貨系列文章匯總?cè)缦拢X得不錯(cuò)點(diǎn)個(gè)Star,歡迎 加群 互相學(xué)習(xí)。
https://github.com/qq44924588...
我是小智,公眾號(hào)「大遷世界」作者,對(duì)前端技術(shù)保持學(xué)習(xí)愛好者。我會(huì)經(jīng)常分享自己所學(xué)所看的干貨,在進(jìn)階的路上,共勉!
關(guān)注公眾號(hào),后臺(tái)回復(fù)福利,即可看到福利,你懂的。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/101129.html
摘要:關(guān)鍵幀是用來通知瀏覽器在規(guī)定的時(shí)間點(diǎn)上應(yīng)有的屬性值然后填充空白。每一對(duì)數(shù)值內(nèi)包含表示三次貝塞爾曲線控制點(diǎn)的和坐標(biāo)。即使每個(gè)控制點(diǎn)的和值的微小差異都會(huì)輸出完全不同的貝塞爾曲線。 原文請查閱這里,本文采用知識(shí)共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第十三章。 概述 正如你所知,動(dòng)畫在...
摘要:關(guān)鍵幀是用來通知瀏覽器在規(guī)定的時(shí)間點(diǎn)上應(yīng)有的屬性值然后填充空白。每一對(duì)數(shù)值內(nèi)包含表示三次貝塞爾曲線控制點(diǎn)的和坐標(biāo)。即使每個(gè)控制點(diǎn)的和值的微小差異都會(huì)輸出完全不同的貝塞爾曲線。 原文請查閱這里,本文采用知識(shí)共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第十三章。 概述 正如你所知,動(dòng)畫在...
摘要:關(guān)鍵幀是用來通知瀏覽器在規(guī)定的時(shí)間點(diǎn)上應(yīng)有的屬性值然后填充空白。每一對(duì)數(shù)值內(nèi)包含表示三次貝塞爾曲線控制點(diǎn)的和坐標(biāo)。即使每個(gè)控制點(diǎn)的和值的微小差異都會(huì)輸出完全不同的貝塞爾曲線。 原文請查閱這里,本文采用知識(shí)共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第十三章。 概述 正如你所知,動(dòng)畫在...
摘要:為了方便大家共同學(xué)習(xí),整理了之前博客系列的文章,目前已整理是如何工作這個(gè)系列,可以請猛戳博客查看。以下列出該系列目錄,歡迎點(diǎn)個(gè)星星,我將更友動(dòng)力整理理優(yōu)質(zhì)的文章,一起學(xué)習(xí)。 為了方便大家共同學(xué)習(xí),整理了之前博客系列的文章,目前已整理 JavaScript 是如何工作這個(gè)系列,可以請猛戳GitHub博客查看。 以下列出該系列目錄,歡迎點(diǎn)個(gè)星星,我將更友動(dòng)力整理理優(yōu)質(zhì)的文章,一起學(xué)習(xí)。 J...
閱讀 1333·2021-09-04 16:40
閱讀 3460·2021-07-28 00:13
閱讀 2884·2019-08-30 11:19
閱讀 2619·2019-08-29 12:29
閱讀 3172·2019-08-29 12:24
閱讀 1127·2019-08-26 13:28
閱讀 2401·2019-08-26 12:01
閱讀 3451·2019-08-26 11:35