摘要:我們并不需要知道貝塞爾曲線背后的所有數(shù)學(xué)知識(shí)。我們可以使用相同的并設(shè)置并反轉(zhuǎn)貝塞爾曲線,這樣就實(shí)現(xiàn)了在正反兩個(gè)方向上使用同一個(gè)的效果。我們來(lái)看看如何計(jì)算反向的貝塞爾曲線。
首先來(lái)看一看我之前寫的一個(gè)CSS輪播動(dòng)畫效果,為了讓切換時(shí)動(dòng)畫的過(guò)渡更加的平滑我在animation-timing-function屬性中并沒(méi)有使用CSS提供的各種關(guān)鍵詞,而使用了cubic-bezier(貝塞爾)函數(shù)。
貝塞爾函數(shù)乍一看會(huì)讓人困惑摸不著頭腦,但如果使用得當(dāng),它可以為動(dòng)畫的用戶體驗(yàn)增添一種更棒的感覺(jué)。
在構(gòu)建這個(gè)輪播動(dòng)畫的時(shí)候,我意識(shí)到當(dāng)我給一頁(yè)添加了顯示的貝塞爾函數(shù)時(shí),它前一頁(yè)隱藏的貝塞爾函數(shù)則是反向的。我覺(jué)得我們分享這篇文章的內(nèi)容是非常值得的,因?yàn)閯?chuàng)建一個(gè)貝塞爾曲線并反轉(zhuǎn)它可能看起來(lái)很棘手,但實(shí)際上非常的簡(jiǎn)單。
了解基礎(chǔ)的easing首先,Easing這個(gè)詞用來(lái)描述元素動(dòng)畫在時(shí)間線上的加速與減速節(jié)奏。我們可以將其繪制成一個(gè)圖表,其中x軸是時(shí)間,y軸是動(dòng)畫的進(jìn)度。linear是沒(méi)有加速或減速(一直以相同的速度移動(dòng))的圖形,表現(xiàn)在圖上就是一條直線:
非線性的Easing會(huì)讓動(dòng)畫更自然、更逼真。我們可以對(duì)CSS中的transition和animation應(yīng)用各種的easing,我們可以將這些值設(shè)置在transition-timing-function或者animation-timing-function屬性上??偣灿形鍌€(gè)關(guān)鍵字可以設(shè)置:
linear – 上面已經(jīng)介紹了
ease-in – 動(dòng)畫開(kāi)始時(shí)很慢,并隨著它的進(jìn)行而加速。
ease-out – 動(dòng)畫開(kāi)始很快,最后減速。
ease-in-out – 動(dòng)畫開(kāi)始緩慢,中間加速,最后減速。
ease – 默認(rèn)值,與ease-in-out的動(dòng)畫過(guò)程相反。
了解cubic-bezier如果上面介紹的關(guān)鍵字值都不適合我們的動(dòng)畫,我們可以使用cubic-bezier貝塞爾函數(shù)創(chuàng)建自定義的曲線。下面是一個(gè)例子:
.my-element { animation-name: slide; animation-duration: 3s; animation-timing-function: cubic-bezier(0.45, 0.25, 0.60, 0.95); }
我們可以將這些屬性簡(jiǎn)寫為一個(gè),如下所示:
.my-element { animation: slide 3s cubic-bezier(0.45, 0.25, 0.60, 0.95); }
你會(huì)注意到cubic-bezier貝塞爾函數(shù)有四個(gè)值。這四個(gè)值是繪制曲線所需的兩對(duì)坐標(biāo)。這些坐標(biāo)代表什么意思呢?如果你使用過(guò)Illustrator,那么控制曲線大小和方向的向量點(diǎn)對(duì)你來(lái)說(shuō)就會(huì)很熟悉。這就是我們用cubic-bezier貝塞爾函數(shù)繪制曲線所必須的點(diǎn)。
我們并不需要知道貝塞爾曲線背后的所有數(shù)學(xué)知識(shí)。因?yàn)橛写罄袨槲覀儎?chuàng)建了方便的工具,例如LeaVerou的cubic-bezier.com,這個(gè)網(wǎng)站中我們可以可視化的創(chuàng)建一條貝塞爾曲線并復(fù)制它的坐標(biāo)點(diǎn)值。我的輪播效果的貝塞爾曲線就是用這個(gè)工具創(chuàng)建的,它看起來(lái)是這樣的:
在這里,可以看到我們需要的兩個(gè)點(diǎn):cubic-bezier(x1, y1, x2, y2)。
在正反兩個(gè)方向上應(yīng)用easing上面的輪播圖中應(yīng)用了正反兩個(gè)方向的動(dòng)畫 - 單擊左箭頭時(shí),當(dāng)前項(xiàng)目向右滑出視圖,同時(shí)下一個(gè)項(xiàng)目向左滑入;如果點(diǎn)擊右箭頭,就會(huì)發(fā)生相反的情況。我最初的假設(shè)是,可以簡(jiǎn)單地反轉(zhuǎn)動(dòng)畫使項(xiàng)目以相反方向滑出,如下所示:
.my-element--reversed { animation: slide 3s cubic-bezier(0.45, 0.25, 0.60, 0.95) reverse; }
這里有一個(gè)問(wèn)題:給animation添加reverse也反轉(zhuǎn)了easing曲線!所以,現(xiàn)在我的動(dòng)畫在一個(gè)方向看起來(lái)很好,但在反方向上是不對(duì)的。
下面的演示中,第一個(gè)框顯示正方向的動(dòng)畫,第二個(gè)框顯示添加reverse后的情況。
你可以看到這兩個(gè)動(dòng)畫的感覺(jué)完全不一樣。第一個(gè)盒子在開(kāi)始加速,并且隨著動(dòng)畫的進(jìn)展緩慢地減速,而第二個(gè)盒子開(kāi)始時(shí)相當(dāng)緩慢,然后在停止之前有一個(gè)加速的過(guò)程。
我們有兩種方法來(lái)解決這個(gè)問(wèn)題:
創(chuàng)建一個(gè)新的keyframe animation來(lái)顯示動(dòng)畫,然后設(shè)置為相同的easing。對(duì)于簡(jiǎn)單的動(dòng)畫這樣設(shè)置無(wú)可厚非,但是如果遇到復(fù)雜的動(dòng)畫該怎么辦呢?創(chuàng)建反向的動(dòng)畫需要做更多的工作,而且很容易出錯(cuò)。
我們可以使用相同的keyframe animation(并設(shè)置animation-direction:reverse)并反轉(zhuǎn)貝塞爾曲線,這樣就實(shí)現(xiàn)了在正反兩個(gè)方向上使用同一個(gè)easing的效果。這種方法并不難。
反轉(zhuǎn)貝塞爾曲線,對(duì)應(yīng)在坐標(biāo)軸中就是將整體圖形旋轉(zhuǎn)180度:
通過(guò)簡(jiǎn)單的數(shù)學(xué)計(jì)算就可以得到反轉(zhuǎn)后的點(diǎn)坐標(biāo),具體方法是:交換兩個(gè)坐標(biāo)點(diǎn),并將每個(gè)值都用1減去。
例如,正方向的坐標(biāo)是:
x1, y1, x2, y2
那么,反方向的坐標(biāo)就通過(guò)下面的公式得出:
(1 - x2), (1 - y2), (1 - x1), (1 - y1)
在下面的演示中,第三個(gè)框是我們需要的效果:元素向相反的方向滑動(dòng),但是它與正方向的動(dòng)畫曲線是一樣的。
我們來(lái)看看如何計(jì)算反向的貝塞爾曲線。
用CSS自定義屬性來(lái)計(jì)算反向曲線我們可以使用CSS自定義屬來(lái)計(jì)算新的曲線!首先將每個(gè)值賦給一個(gè)變量:
:root { --x1: 0.45; --y1: 0.25; --x2: 0.6; --y2: 0.95; --originalCurve: cubic-bezier(var(--x1), var(--y1), var(--x2), var(--y2)); }
然后我們可以使用這些變量來(lái)計(jì)算新值:
:root { --reversedCurve: cubic-bezier(calc(1 - var(--x2)), calc(1 - var(--y2)), calc(1 - var(--x1)), calc(1 - var(--y1))); }
現(xiàn)在,如果我們對(duì)第一組變量做任何的更改,反向曲線點(diǎn)將會(huì)被自動(dòng)計(jì)算出來(lái)。為了在檢查和調(diào)試代碼時(shí)更容易發(fā)現(xiàn)問(wèn)題,我喜歡將這些新值分配到它們自己的變量中:
:root { /* 正向原始值 */ --x1: 0.45; --y1: 0.25; --x2: 0.6; --y2: 0.95; --originalCurve: cubic-bezier(var(--x1), var(--y1), var(--x2), var(--y2)); /* 反向計(jì)算值 */ --x1-r: calc(1 - var(--x2)); --y1-r: calc(1 - var(--y2)); --x2-r: calc(1 - var(--x1)); --y2-r: calc(1 - var(--y1)); --reversedCurve: cubic-bezier(var(--x1-r), var(--y1-r), var(--x2-r), var(--y2-r)); }
現(xiàn)在剩下的就是將新的曲線應(yīng)用到反向動(dòng)畫中:
.my-element--reversed { animation: slide 3s var(--reversedCurve) reverse; }
為了更直觀并切可視化的做到這些,我創(chuàng)建了一個(gè)小工具來(lái)計(jì)算一個(gè)貝塞爾曲線的反向值。輸入原始坐標(biāo)值就可以自動(dòng)獲得反向曲線的值: Reverse cubic-bezier工具
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/104466.html
摘要:我們并不需要知道貝塞爾曲線背后的所有數(shù)學(xué)知識(shí)。我們可以使用相同的并設(shè)置并反轉(zhuǎn)貝塞爾曲線,這樣就實(shí)現(xiàn)了在正反兩個(gè)方向上使用同一個(gè)的效果。我們來(lái)看看如何計(jì)算反向的貝塞爾曲線。 首先來(lái)看一看我之前寫的一個(gè)CSS輪播動(dòng)畫效果,為了讓切換時(shí)動(dòng)畫的過(guò)渡更加的平滑我在animation-timing-function屬性中并沒(méi)有使用CSS提供的各種關(guān)鍵詞,而使用了cubic-bezier(貝塞爾)函...
摘要:我們并不需要知道貝塞爾曲線背后的所有數(shù)學(xué)知識(shí)。我們可以使用相同的并設(shè)置并反轉(zhuǎn)貝塞爾曲線,這樣就實(shí)現(xiàn)了在正反兩個(gè)方向上使用同一個(gè)的效果。我們來(lái)看看如何計(jì)算反向的貝塞爾曲線。 首先來(lái)看一看我之前寫的一個(gè)CSS輪播動(dòng)畫效果,為了讓切換時(shí)動(dòng)畫的過(guò)渡更加的平滑我在animation-timing-function屬性中并沒(méi)有使用CSS提供的各種關(guān)鍵詞,而使用了cubic-bezier(貝塞爾)函...
摘要:關(guān)鍵幀是用來(lái)通知瀏覽器在規(guī)定的時(shí)間點(diǎn)上應(yīng)有的屬性值然后填充空白。每一對(duì)數(shù)值內(nèi)包含表示三次貝塞爾曲線控制點(diǎn)的和坐標(biāo)。即使每個(gè)控制點(diǎn)的和值的微小差異都會(huì)輸出完全不同的貝塞爾曲線。 原文請(qǐng)查閱這里,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 這是 JavaScript 工作原理的第十三章。 概述 正如你所知,動(dòng)畫在...
摘要:關(guān)鍵幀是用來(lái)通知瀏覽器在規(guī)定的時(shí)間點(diǎn)上應(yīng)有的屬性值然后填充空白。每一對(duì)數(shù)值內(nèi)包含表示三次貝塞爾曲線控制點(diǎn)的和坐標(biāo)。即使每個(gè)控制點(diǎn)的和值的微小差異都會(huì)輸出完全不同的貝塞爾曲線。 原文請(qǐng)查閱這里,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 這是 JavaScript 工作原理的第十三章。 概述 正如你所知,動(dòng)畫在...
閱讀 2354·2021-11-10 11:35
閱讀 1060·2021-09-26 09:55
閱讀 2486·2021-09-22 15:22
閱讀 2376·2021-09-22 15:17
閱讀 3799·2021-09-09 09:33
閱讀 1881·2019-08-30 11:22
閱讀 1043·2019-08-30 10:57
閱讀 714·2019-08-29 16:10