很久以前寫過一個可拖拽圓形進度條的dome,中間有網友反饋過一些問題,最近比較閒有時間修改了一些問題也作了一些優化,並封裝成組件,基於canvas實現,只需傳入放置組件dom容器,任何框架都可直接使用;html
codepen 示例以下:codepen.io/pangyongshe…git
執行 npm i drag-arc -S 或 cnpm i drag-arc -Sgithub
import DragArc from 'drag-arc'; new DragArc({ el: dom, value: 10, change: (v) => { console.log(v) }, ...})複製代碼
其中dom爲放置組件HTML容器,可經過ref獲取;npm
項目地址:github.com/pangyongshe…
npm地址:www.npmjs.com/package/dra…canvas
Name | Description | Type | Default | Required |
---|---|---|---|---|
el | 放置組件的DOM元素 | Element | none | Y |
change | 當前值變化時觸發的事件,回調參數爲當前進度值Number(0-100) | Function | ()=>{} | N |
startDeg | 滑動圓弧的起始弧度 | Number | 0 | N |
endDeg | 滑動圓弧的結束弧度 | Number | 1 | N |
value | 默認值 | Number (0-100) | 0 | N |
textShow | 顯示文字 | Boolean | true | N |
color | 外側圓弧顏色 | String,Array | ["#06dabc", "#33aaff"] | N |
slider | 滑塊半徑 | Number | #FFF | N |
innerColor | 內側弧度的顏色 | String | #ccc | N |
outColor | 外側圓弧背景顏色 | String,Array | #ccc | N |
innerLineWidth | 內側弧線寬 | Number | 1 | N |
outLineWidth | 外側弧線寬 | Number | 20 | N |
counterclockwise | 逆時針方向 | Boolean | true | N |
sliderColor | 滑塊顏色 | String | #CCC | N |
sliderBorderColor | 滑塊邊框顏色 | String | #fff | N |
如圖所示,以canvas畫布中心點創建座標系,則有:bash
由圓的參數方程得出
x=rcosφ
y=rsinφ框架
經過事件回調參數 咱們能夠得到 鼠標mousemove事件或者移動端touchmove事件的x,y座標,可計算tan值爲
tanφ = y/x;
再經過反三角函數有可得:
φ=arctan(tanφ)dom
以上基本的位置關係已經得出;ide
因爲上述位置關係是基於中心座標實現的,而canvas繪製座標是以左上角爲原點實現的,故須要實現兩種座標的轉化關係;函數
下圖是canvas的弧度位置剛好與咱們正常計算的方向是相反的,一樣需考慮弧度的轉換;
因爲Math.atan() 函數返回一個數值的反正切[- π/2 , π/2 ],
而實際中咱們須要得到到[0-2π]直接的值,因此在經過鼠標位置獲取弧度值時須要經過Math.atan(y/x)和xy在中心座標的正負綜合判斷其所在象限從何獲取實際的獲取弧度值;
因爲鼠標移動觸發繪圖方法是較爲連續的動畫效果,而進度是間隔的,
這裏咱們須要實現個相似d3js中domain和range的比例關係。
這裏咱們將值[0,100]對應弧度比例爲[startDeg, endDeg]
因爲鼠標移動的位置是任意的,可能致使滑塊到達終點後因爲鼠標移動到了起點時,滑塊也直接從終點移動到起點,故需對起點終點作判斷,到達起點後不可再向後滑動,到達終點後不可再向前滑動;