共计 1743 个字符,预计需要花费 5 分钟才能阅读完成。
好久之前写过一个可拖拽圆形进度条的 dome,中间有网友反馈过一些问题,最近比较闲有时间修改了一些问题也做了一些优化,并封装成组件,基于 canvas 实现,只需传入放置组件 dom 容器,任何框架均可直接使用;
codepen 示例如下:[https://codepen.io/pangyongsh…]
一、如何使用
npm 下载
执行 npm i drag-arc -S 或 cnpm i drag-arc -S
import DragArc from 'dragarc';
new DragArc({
el: dom,
value: 10,
change: (v) => {console.log(v)}
})
或者 也可从项目下载 dist/dist/drag-arc.min.js,直接通过 srcipt 标签引入
其中 dom 为放置组件 HTML 容器, 可通过 ref 获取;
主要属性方法(详见 github/npm)
项目地址:https://github.com/pangyongsheng/canvas-arc-draw
npm 地址:https://www.npmjs.com/package/drag-arc
Name | Description | Type | Default | Required |
---|---|---|---|---|
el | 放置组件的 DOM 元素 | Element | none | Y |
change | 当前值变化时触发的事件,回调参数为当前进度值 Number(0-100) | Function | ()=>{} | N |
startDeg | 滑动圆弧的起始弧度 | Number (0-2) | 0 | N |
endDeg | 滑动圆弧的结束弧度 | Number (0-2) | 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 |
二、实现方法简介
1、绘制位置几何关系
如图所示,以 canvas 画布中心点建立坐标系,则有:
滑块位置与弧度关系:
由圆的参数方程得出
x=rcosφ
y=rsinφ
鼠标移动位置与弧度关系:
通过事件回调参数 我们可以获得 鼠标 mousemove 事件或者移动端 touchmove 事件的 x,y 坐标,可计算 tan 值为
tanφ = y/x;
再通过反三角函数有可得:
φ=arctan(tanφ)
以上基本的位置关系已经得出;
2、js 实现中的几个问题
(1)坐标的转化方法
由于上述位置关系是基于中心坐标实现的,而 canvas 绘制坐标是以左上角为原点实现的,故需要实现两种坐标的转化关系;
(2)canvas 弧度位置与正常弧度位置的转化
下图是 canvas 的弧度位置恰好与我们正常计算的方向是相反的,同样需考虑弧度的转换;
(3)Math.atan 方法返回值与实际弧度的关系
由于 Math.atan() 函数返回一个数值的反正切 [- π/2 , π/2],
而实际中我们需要获得到 [0-2π] 直接的值,所以在通过鼠标位置获取弧度值时需要通过 Math.atan(y/x)和 xy 在中心坐标的正负综合判断其所在象限从何获取实际的获取弧度值;
(4)弧度与进度条值得关系
由于鼠标移动触发绘图方法是较为连续的动画效果,而进度是间隔的,
这里我们需要实现个类似 d3js 中 domain 和 range 的比例关系。
这里我们将值 [0,100] 对应弧度比例为[startDeg, endDeg]
(5)终点的判断
由于鼠标移动的位置是任意的,可能导致滑块到达终点后由于鼠标移动到了起点时,滑块也直接从终点移动到起点,故需对起点终点做判断,到达起点后不可再向后滑动,到达终点后不可再向前滑动;
3、详细实现方法可以参考这篇文章
https://www.cnblogs.com/pangys/p/6837344.html