摘要:主要功能就是拖動標尺變動價格。整個標尺的長度為,步長為元。金額顯示首先,增加一個輸入框,然后獲取它。輸入金額移動標尺標尺的移動除了拖動以外,我們也希望通過金額輸入框來達到。
效果源碼
終于到年底了,再過兩天我也要回家過年了,想想就激動呢!今天給大家帶來一個基于移動端的canvas價格選擇效果。
主要功能就是拖動標尺變動價格。而且支付寶和京東金融的里也有這樣的效果(果然天下設計都是你抄我我抄你啊?)。
效果演示地址
1.實現思路整個效果的核心就是用canvas繪制的標尺。一共包括標尺主體,數字,和中間固定不變的標定軸,這幾個部分都用canvas繪制。最上面的大號價格文字,因為其他地方會需要用它來計算相關的收益。所以,我們就用個DOM來呈現,這樣比較方便獲取。
標尺拖動的距離與價格之間有有一個映射關系,是整個效果最不好處理的部分,在具體處理到相關問題的時候我們再做分析?,F在,我們先實現基礎的標尺繪制。
2.標尺屬性定義我們先定義一個類叫Rule.js, 其具體屬性如下。
現在我們來了解一下每個屬性的含義:
x, y: 標尺的坐標位置
vx: 標尺的移動速度
ax: 標尺移動加速度
color: 繪制標尺線條的顏色,與文字顏色
scaleX, scaleY: 縮放比
markShort, markLong: 標尺長短線的長度
textHeight: 文字距離標尺主體的高度
min, max: 要展示的最大值和最小值
width: 標尺的像素寬度
step: 步長
seg: 段數
pxStep: 在canvas上的實際步長(單位為px)
minPxStep: 每個pxStep分10小段,每小段的實際像素寬度
lineBottom: 底部橫線參數
lineRed: 標定軸參數
參數比較多,但真正需要傳入的參數其實并不是很多。這里我講解一下(8)~(15)這幾個參數的思路。
min, max : 參數的作用是設置需要顯示的最大金額和最小金額。這兩個參數是外部傳入的,比如設定用戶最小能存100元,最大能存100000萬元。那么min和max就分別對應100和100000。
width : 是整個標尺的實際屏幕長度,比如你只想標尺繪制1000px,那這里就傳1000就好了。
step : 步長的含義就是每隔多少分一段,比如我們設定的最大金額為10000元, 那設置step為1000就意味著,每隔1000元表示一個小段,這也是canvas上標尺刻度需要繪制的數據。
seg : 段數等于總金額max除以step。
pxStep : 為真正映射到canvas上的像素步長。
miniPxStep : 每個pxStep分為10小段,每小段的像素距離。
lineBottom : 獨立出來不和標尺刻度一起繪制,在繪制標尺的底部橫線時,我是這樣想的。底部橫線的寬度其實就是canvas的寬度,沒必要從標尺的初始畫到標尺的結尾。而且為了用戶體驗,刻度的初始位置和結束位置都位于整個canvas的中心。所以,如果合在一起繪制,你需要先繪制一段沒刻度的橫線,然后再繪制刻度,到最后還要繪制一段沒刻度的橫線。這給無疑讓繪制和后續的標尺移動變得相當麻煩。所以我把它抽出來,就是一條貫穿canvas的普通橫線。
lineRed : 標定軸,始終在canvas的中間,也獨立出來不和標尺刻度一起繪制。
屬性都有了,下面添加一個draw方法,把我們的標尺繪制出來。
2.標尺繪制a) 繪制標尺刻度部分
這里有個截圖錯誤,應該是i+=this.miniPxStep。這應該不難理解,就是每隔miniPxStep繪制一次線段,線段的類型根據n這個變量來確定。
b) 繪制標尺文字部分
文字的繪制不能以真實的屏幕像素為準,必須映射到金額上,所以,這里繪制的數字是(n/10)* this.step。同時,還做了一個特殊的處理,就是初始值是1,不是0。因為,我們的金額不允許輸入0元。如果你不需要這個,把這里注釋掉就ok了。
c) 繪制底部橫線
d) 繪制標定軸
這樣整個標尺就完成了,rule.js文件在頂部的github中?,F在我們調用一下這個文件,看看畫出來的效果怎樣。
這里我們設置了最大額度為100000元,最小額度為500元。整個標尺的長度為5000px,步長step為1000元。效果圖如下:
讓標尺偏移個200px, 比如設置: x: ruleX - 200, 效果如下:
設置步長step為500,效果如下:
ok,現在靜態標尺就繪制完成,下一步就要完成交互功能,讓標尺能夠跟隨鼠標滾動,并且展示當前拖動的金額。
3.拖動標尺現在我們開始實現標尺的拖動。標尺的拖動原理很簡單,就是讓標尺的位置跟隨鼠標移動。這里為了演示方便我換成了鼠標事件,到移動端換成touch事件即可。
首先引入我們的工具函數utils.js文件,然后定義幾個變量。
isMouseDown用來判斷鼠標是否抬起, oldX用來記錄上一次拖動的位置,mouse是使用captureMouse返回的對象,返回鼠標在canvas上的當前位置信息。
然后,監聽canvas的鼠標事件mousedown, mouseup, mousemove。并改變rule的位置。
當鼠標按下時,isMouseDown變為true, offsetX在上面忘記寫了,它的作用是記錄鼠標按下的位置與標尺位置之間的偏移量。然后在鼠標移動時標尺的位置rule.x = mouse.x - offsetX。如果不這樣做,在點擊canvas并拖動標尺的一瞬間,你會發現標尺的初始位置會瞬移到鼠標點擊位置,這樣體驗很不好,我們需要不管點擊哪,標尺都會在現有的位置跟隨鼠標移動。如果,無法體會,動手試一試去掉回事什么效果。
oldX也很好理解,就是記錄標尺上一次的位置,這里還沒有用到它,后面可能會用到。
現在我們把標尺的繪制寫進動畫函數中
看看動畫效果如何。
ok,現在我們已經實現了標尺跟隨鼠標的拖動。下一步,我們就把拖動的金額顯示出來。
4.金額顯示首先,增加一個input輸入框,然后獲取它。
這里設置了輸入框的最小值為標尺的最小額度,這里可以先不用管它。我們主要看onMouseMove函數
注意money的計算值,它為(centerX - rule.x)*rule.ratioScale。 (centerX - rule.x)比較好理解,因為,我們的標尺是從canvas的中心點繪制的。但rule.ratioScale在最開始的構造函數中并沒有定義。這里需要在構造函數中加上,它的含義是每像素代表多少錢,可以認為是圖形比例尺。
this.ratioScale = Math.floor(this.max / this.width) //比列尺
那么自然,移動距離乘以比例尺就得出錢數了。我們看看效果。
注意到上面的效果中金額顯示出現了負數,所以我們需要對移動范圍做限制。讓其只能在限定的最大和最小金額之間移動。
5.移動范圍限定對一定范圍的限定主要分為兩部分。一、標尺范圍的限定。二、金額顯示的限定。這兩部分我們放在一起做。
1)重設標尺的初始位置
假設我們設置的最小金額為500元,那么初始標定軸的位置應該就是500元的位置。所以初始化標尺的位置后,我們給它重置為最小金額的位置。這時候需要把金額換算一下。
rule.x = centerX - rule.min / rule.ratioScale;
就是把金額值得計算倒一下。
2)限定標尺的移動范圍
這里定義了一個檢測邊界值得函數,當金額小于最小投資金額時,標尺的位置為初始位置start(注意這個初始位置是已經被重置過的), 并且設置金額為最小額度。最大位置同理。
然后,在onMouseMove中調用。
看看效果圖。
6.輸入金額移動標尺標尺的移動除了拖動以外,我們也希望通過金額輸入框來達到。即輸入金額,標尺便移動到目標金額的位置。
同時我們也做了邊界限定,當輸入的金額小于或者大于設定值時會,設置標尺的位置和輸入框的顯示為邊界值,看看效果。
7.來個速度吧現在拖動的還比較不自然,我們想要手指離開后標尺還會繼續移動,直到速度慢慢減為0。為此,新建兩個變量。
var speed = 0, fl = 0.95; //初始速度, 摩擦系數
新建一個move函數,在動畫循環中調用。
至此,拖動輸入的核心功能就開發完了。如果你要在項目中使用,另一個需要注意的事情是canvas在移動端的模糊問題,這個已經有了很多的解決方案,你只需要耐心調試就好。最后還是祝大家新年快樂,源碼在頭部地址哦。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107420.html
摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入匯總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業務工作時也會不定期更...
摘要:前端每周清單第期支付寶前端構建工具發展用加快網頁響應速度餓了么升級實踐前端前端每周清單前端每周清單專注前端領域內容,分為新聞熱點開發教程工程實踐深度閱讀開源項目巔峰人生等欄目。 前端每周清單第 12 期:支付寶前端構建工具發展、LinkedIn用Brotli加快網頁響應速度、餓了么PWA 升級實踐 為InfoQ中文站特供稿件,首發地址為這里;如需轉載,請與InfoQ中文站聯系。從屬于筆...
閱讀 3322·2021-11-22 12:04
閱讀 2705·2019-08-29 13:49
閱讀 482·2019-08-26 13:45
閱讀 2237·2019-08-26 11:56
閱讀 998·2019-08-26 11:43
閱讀 586·2019-08-26 10:45
閱讀 1265·2019-08-23 16:48
閱讀 2157·2019-08-23 16:07