同事要做个物联网小程序,可以通过小程序控制家里空调的温度设置(具体怎么实现以后研究)。温度控制界面上一个大大的环形,需求是拨动这个环形上的拖柄,可控制环形色条。
先来预设一些数值
- 暂定画布宽高为绝对值(500px * 500px)(实际情况可能需要做成自适应的尺寸)
- 轨道圆形的圆心为(250, 250),半径分别为100px、120px
- 上面两个条件之后轨道上的小圆型(滑柄)半径为20, 圆心坐标为(360,250)
这几个数值下面要用。
模板如下:
1 | <view style=""> |
data:
1 | objCanvas: null, // canvas画布对象 |
1. 设计思路
- 这样的需求只能选用canvas画布,div做出的环形无法控制颜色任意填充面积;
- 画布上的环形需要一个‘‘运动轨道’’ 和 一个可以用来拖拽的小圆(下文称为滑柄),小圆要在“轨道”上运动;
- 拖动的同时要限制小圆,不能脱离轨道,轨道填充颜色要和小圆一致;
2.我们先来完成初始状态绘制
1 |
|
大概样子如下:
3. 怎样让他能拖动呢?
(1)首先来复习一下三角函数
复习几个js的Math对象方法:
方法 | 描述 |
---|---|
abs(x) | 返回数的绝对值。 |
acos(x) | 返回数的反余弦值。 |
asin(x) | 返回数的反正弦值。 |
atan(x) | 以介于 -PI/2 与 PI/2 弧度之间的数值来返回 x 的反正切值。 |
atan2(y,x) | 返回从 x 轴到点 (x,y) 的角度(介于 -PI/2 与 PI/2 弧度之间)。 |
ceil(x) | 对数进行上舍入。 |
cos(x) | 返回数的余弦。 |
exp(x) | 返回 e 的指数。 |
floor(x) | 对数进行下舍入。 |
log(x) | 返回数的自然对数(底为e)。 |
max(x,y) | 返回 x 和 y 中的最高值。 |
min(x,y) | 返回 x 和 y 中的最低值。 |
pow(x,y) | 返回 x 的 y 次幂。 |
random() | 返回 0 ~ 1 之间的随机数。 |
round(x) | 把数四舍五入为最接近的整数。 |
sin(x) | 返回数的正弦。 |
sqrt(x) | 返回数的平方根。 |
tan(x) | 返回角的正切。 |
toSource() | 返回该对象的源代码。 |
valueOf() | 返回 Math 对象的原始值。 |
当然不会都用上,顺便复习其他的
(2)再来理一下思路
- canvas画布上的原始坐标轴以左上角为(0, 0)原点,原点为基础,右方位x轴正方向,下方为y轴正方向;
- 手指(或鼠标)在进入canvas画布就开始检测是否可以触发滑柄滑动;
- 根据手指的位置需要转换为滑柄在轨道上的准确位置;
手指在画布移动事件
1 | touchMove(e) { |
主要是如何获取滑柄在轨道上的准确位置
利用相似三角形定律和几个三角函数如下:
你看这个图他又丑又草,凑合着看版本
1 | // 判断是左还是右 |
基本上可以了,然后就是重新绘制画布:
1 |
|
最终效果如下:
4. 注意
小程序有自己的长度单位rpx,但是canvas是个例外,canvas只认px,所以,实际使用在小程序时,需要再处理一下单位,最好方案是响应式的单位(原理和rem类似)