導航:首頁 > 編程語言 > js彈性運動

js彈性運動

發布時間:2024-12-06 09:59:53

『壹』 物理學的 H5 應用:模擬慣性滑動

在移動端 H5 中,時間選擇器( date-picker )、省市區選擇器( area-picker )等組件經常會使用這樣的交互效果:

這個 gif 是在【微信錢包 - 賬單】中錄制的 ios 原生時間選擇器。可見, 當用戶手指在選擇器上先是滑動再從屏幕上移開,內容會繼續保持一段時間的滾動效果,並且滾動的速度和持續的時間是與滑動手勢的強烈程度成正比。 這種交互思路源於 ios 系統原生元素的滾動回彈( momentum-based scrolling ),來看 H5 的一個普通列表在 ios 上的滾動表現:

社區上大部分的移動端組件庫的選擇器組件都採取了這種交互方式,看看效果:

weui 的選擇器實現了慣性滑動,但滑動動畫結束得有稿掘點突兀,效果一般。

vant 的選擇器壓根沒有做慣性滑動,當手指從屏幕上移開後,選擇器的滑動會立刻停止。可見這樣的交互體驗是比較差的。

接下來我會從設計層面剖析和模擬慣性滑動的交互效果。

不難想像,慣性滑動非常貼合現實生活中的一些場景,如汽車剎車等。除此之外,與物理力學中的滑塊模型也十分相似,由此我會參考滑塊模型來剖析慣性滑動的全過程。

慣性 來源於物理學中的慣性定律(即 牛頓第一定律 ):一切物體在沒有受到力的作用的時候,運動狀態不會發生改變,物體所擁有的這種性質就被稱為慣性。我們不妨把慣性滑動模擬成滑動滑塊然後釋放的過程(以下討論中用戶滑動的目標皆模擬成 滑塊 ),主要劃分為兩個階段:

描述滑塊的慣性滑動,首先需要求出滑動的距離。在上述二階段中,滑塊受摩擦力 作 勻減速直線運動 。假設滑動距離為 ,初速度為 ,末速度為 。根據位移公式

加速度公式

可以仔昌算出慣性滑動距離

由於勻減速運動的加速度為負,不妨設一個加速度常量 ,使其滿足 ,那麼

這里 為正數。也就是說,我們只需要求出初始速度即可。

關注第一個階段,假設用戶滑動滑塊的距離為 ,滑動的持續時間是 ,那麼二階段的初速度 可以根據位移公式求得

綜上,求慣性滑動的距離我們需要記錄用戶滑動滑塊的 距離 持續時間 ,並設置一個合理的 加速度常量 。念敬扒

注意,這里的距離和持續時間並不是用戶滑動滑塊的總距離和時長,而是觸發慣性滑動范圍內的距離和時長,詳見【慣性滑動的啟動條件】。

針對二階段的勻減速直線運動,時間段 產生的位移差 ,其中 。也就是說時間越往後,同等時間間距下通過的位移越來越小,也就是動畫的推進速度越來越慢。

這與 CSS3 transition-timing-function 中的 ease-out 速度曲線相吻合, ease-out (即 cubic-bezier(0, 0, .58, 1) )的貝塞爾曲線為

上圖來自 在線繪制貝塞爾曲線網站 。圖表中的縱坐標是指 動畫推進的進程 ;橫坐標是指 時間 ;原點坐標為 (0, 0) ,終點坐標為 (1, 1) ,假設動畫持續時間為2秒, (1, 1) 坐標點則代表離動畫開始2秒時動畫執行完畢(100%)。根據圖表可以得出,時間越往後動畫進程的推進速度越慢,符合勻減速直線運動的特性。

然而這樣的速度曲線過於線性平滑,減速效果不明顯。我們基於 ios 滾動回彈的效果,調整貝塞爾曲線的參數為 cubic-bezier(.17, .89, .45, 1) 。

滑塊滑動不是無邊界的,我們來考慮這樣的場景:當滑塊向下滑動,其頂部正要接觸容器上邊界時速度還沒有降到 ,此時如果讓滑塊瞬間停止運動,這樣的交互效果是不理想的。

我們可以把上邊界想像成一條與滑塊緊密貼合的固定彈簧, 當滑塊到達臨界點而速度還沒有降到 時,滑塊會繼續滑動並拉動彈簧使其往下形變,同時會受到彈簧的反拉力作減速運動(動能轉化為內能);當滑塊速度降為 ,此時彈簧的形變數最大,由於彈性特質彈簧會恢復原狀(內能轉化成動能),從而拉動滑塊反向運動

回彈過程也可以分為兩個階段:

根據上述分析,回彈的第一階段作加速度越來越大的變減速直線運動,設此階段的初速度為 ,可以與 建立以下關系

那麼回彈距離為

微積分都來了,簡直沒法算好吧…

我們可以根據運動模型來簡化 的計算,由於該階段的加速度大於 非回彈慣性滑動 的加速度,設 非回彈慣性滑動 的總距離為 ,那麼

所以可以設置一個合理的常量 ,使其滿足

整個觸發回彈的慣性滑動模型包括三個運動階段:

然而把 階段a 和 階段b 描繪成 CSS 動畫是有一定復雜度和風險的:

出於簡化的考慮,可以將 階段a、b 合並為一個運動階段:

對於合並後的 階段a 末段,由於反向加速度越來越大,因此滑塊減速的效率會比 非回彈慣性滑動 同期更大,對應的貝塞爾曲線末段也會更陡,參數調整為 cubic-bezier(.25, .46, .45, .94) 。

在 階段b 中,滑塊先變加速後變減速,嘗試 ease-in-out 的動畫曲線:

可以看出,由於 階段b 初始的 ease-in 曲線使 階段a、b 的銜接段稍有停留,效果體驗一般。所以我們選擇只描繪變減速運動這一段,調整貝塞爾曲線為 cubic-bezier(.165, .84, .44, 1) 。

一次慣性滑動可能會出現兩種情況:

慣性滑動的啟動需要有足夠的動量。我們可以簡單地認為,當用戶滑動的距離足夠大(大於 15px )和持續時間足夠短(小於 300ms )時,即可產生慣性滑動。也就是說,最後一次 touchmove 事件觸發的時間和 touchend 事件觸發的時間間隔小於 300ms ,且兩者產生的距離差大於 15px 時認為啟動慣性滑動。

當慣性滑動未結束(包括處於回彈過程),用戶再次觸碰滑塊時會暫停滑塊的運動。原理上是通過 getComputedStyle 和 getPropertyValue 方法獲取當前的 transform: matrix() 矩陣值,抽離出水平 y 軸偏移量後重新調整 translate 的位置。

demo 基於 vuejs 實現,預覽地址: https://codepen.io/JunreyCen/pen/arRYem

閱讀全文

與js彈性運動相關的資料

熱點內容
哪個軟體可以編程手機軟體 瀏覽:554
如東如何學數控編程培訓 瀏覽:5
微信h5頁面怎麼修改 瀏覽:931
手機怎麼無法打開視頻文件夾 瀏覽:840
抖音如何上直播網站 瀏覽:887
錄屏截圖大師保存的文件在哪裡 瀏覽:751
紅河谷第二個版本 瀏覽:895
c語言如何讓整型數據的商為小數 瀏覽:863
怎樣下東西不要密碼 瀏覽:320
小米手機拍照後文件名要怎麼設置 瀏覽:429
每年程序員就業形勢 瀏覽:425
安卓手機如何卸載程序 瀏覽:955
相機能用qq不能用 瀏覽:319
win10如何設置成xp配置文件 瀏覽:748
蘋果隔空傳遞以後文件在哪裡 瀏覽:927
打開ps顯示文件名無效 瀏覽:379
做推廣哪個網站靠譜 瀏覽:588
qq飛車如何綁定好友 瀏覽:873
php編程語言在哪裡 瀏覽:302
矢量文件有哪些格式 瀏覽:790

友情鏈接