很久以前写过一个可拖拽圆形进度条的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]
因为鼠标移动的位置是任意的,可能致使滑块到达终点后因为鼠标移动到了起点时,滑块也直接从终点移动到起点,故需对起点终点作判断,到达起点后不可再向后滑动,到达终点后不可再向前滑动;