您正在使用的尺度參數是二的倍數,所以當你使用線性動畫速度線性比例增加,但距離增加對數。
讓我們看看一些數字。首先,我們從規模到0.5
一個2
一圈,於是兩個的log 2步:
t=0 => scale(0.5)
t=0.25 => scale((0.75 * 0.5 + 0.25 * 2)) = scale(0.875)
t=0.5 => scale((0.5 * 0.5 + 0.5 * 2)) = scale(1.25)
t=0.75 => scale((0.25 * 0.5 + 0.75 * 2)) = scale(1.625)
t=1 => scale(2)
所以看起來起點和終點之間的大,線性過渡。我們可能認爲這意味着我們可以添加更多的圈子來做同樣的事情,但如果我們做到了,我們最終會得到對數行爲。讓我們看看爲什麼:假設我們添加一個縮放0.25
到1
。
t=0 => scale(0.25)
t=0.25 => scale((0.75 * 0.25 + 0.25)) = scale(0.4375)
t=0.5 => scale((0.5 * 0.25 + 0.5)) = scale(0.625)
t=0.75 => scale((0.25 * 0.25 + 0.75)) = scale(0.8125)
t=1 => scale(1)
這似乎好:在每一個時間間隔,大圓的半徑是小了一圈兩次......但是這不你想要什麼,因爲這也意味着,在較小的圓上一點在大圓上的一個點移動兩倍的距離(1.5個單位)時,只移動0.75個單位。我們看到一個簡單的2^t
公式後,一個圓圈開始越大,它在屏幕上移動得越快。
爲了抵消這種情況,您希望補償特定的對數增長,因爲參數不同,所以獨立於每個動畫。獲得一條單曲貝塞爾曲線來完成所有曲線在數學上是不可能的,但由於人類並不是完美的數學機器,因此您可以像屏幕一樣在一小部分屏幕上擺脫它 - 爲任何啓動「正確」 /結束參數集a
和b
您需要設置一個貝塞爾曲線,該曲線在間隔t=[a,b]
上近似於函數1/(2^t)
,這並不好玩:我們需要用貝塞爾曲線在特定間隔上近似series for 1/2^x up to order 2,然後使用這個座標給我們提供了三次簡化參數。
有兩種方法可以做到這一點 - 要麼找到一個貝塞爾曲線,從您的全局最小值到最大值找到最適合的函數,然後使用曲線分割來查找每個子區間的參數,或者找到每個子區間的貝塞爾曲線單獨的間隔。第一個(稍微)更容易,但由於1/2^x
的低階系列近似而容易出錯,第二個更好,但工作量很大,所以如果您想了解如何做到這一點,math.stackexchange.com是獲取更好的地方到這裏真正的數學底部。
大多數程序員將能夠使用的「Stackoverflow答案」是爲自己構建一個「某些間隔的某些曲線」的查找表,然後使用它們之間的插值來處理間隔位於間隔之間某處的間隔你曾經建立LUT:使用任何一種語言繪製間隔圖,然後只用cubic-bezier.com這樣的圖來覆蓋這個圖,然後通過目測控制點找到每個圖的「非常合適」。比如說,你使用了10個間隔時間,而且你很好。
這是肯定的少數學,你不能「節目」該解決方案作爲一個通用的解決方案,但它是高效:從用戶感知的角度來看,這個解決方案應該已經足夠多好感覺光滑。
手動調整參數和觀察目標是否看起來不錯,有什麼問題?這實際上是獲得「感覺正確」的唯一方法 - 數學無法告訴你一般人會遇到什麼樣的「最平滑的遍歷」(事實上,如果你是A/B測試這個) –
@ Mike'Pomax'Kamermans我認爲我最感興趣的是它背後的邏輯。 – pixelass
看過http://cubic-bezier.com?或者,如果你想要很多邏輯,https://pomax.github.io/bezierinfo? –