静态画圆

canvas 唯一标识canvas-id

画圆效果图

1
2
<canvas canvas-id="clock_bg" class="clock_bg"></canvas>
<canvas canvas-id="clock_active" class="clock_active"></canvas>
1
2
3
4
5
6
7
8
9
10
11
12
let lineWidth = 10 / this.data.rate//需要转换为像素单位,但不能直接使用像素单位
let ctx = wx.createCanvasContext('clock_bg')
ctx.setLineWidth(lineWidth);
ctx.setStrokeStyle('#000000');
ctx.setLineCap('round');//填充边界的头形状
ctx.beginPath();

ctx.arc(400 / this.data.rate / 2, 400 / this.data.rate / 2,
400 / this.data.rate / 2 - 2 * lineWidth, 0, 2 * Math.PI, false)

ctx.stroke();//填充路径
ctx.draw();

解释一下this.data.rate是rpx/px的一种比例,如果使用rpx就可以不用去转换比例,可以根据不同的手机来改变相应的宽度。但是这里需要px像素单位,不能自适应,因此需要通过这种this.data.rate来改变,且像素单位

  1. createCanvasContext canvas 组件的绘图上下文。CanvasContext 是旧版的接口, 新版 Canvas 2D 接口与 Web 一致。

  2. setLineWidth 线条的宽度,单位px

  3. setStrokeStyle 描边的颜色,默认颜色为 black。

  4. setLineCap0 设置线条的端点样式

    说明
    butt 向线条的每一个末端添加平直的边缘
    round 添加圆形线帽
    square 正方形线帽
  5. beginPath 开始创建一个路径。需要调用 fill 或者 stroke 才会使用路径进行填充或描边

  6. arc 创建一条弧线。

    • 创建一个圆可以指定起始弧度为 0,终止弧度为 2 * Math.PI。

    • stroke 或者 fill 方法来在 canvas 中画弧线。

  7. draw 将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中。

动态画圆

其实原理和静态圆一样,只是动态圆需要设置一个延时器,一小段一小段的画。根据当前的时间,进行绘制

1
2
// 设置延时器,100毫秒绘制一次,时间越短,绘制越精细
let timer = setInterval(() => {},100)
1
2
3
4
let _this = this
let timer = setInterval(() => {
// 当前使用的箭头函数,没有作用域,因此我们获取的是外面函数的this
},100)
1
2
3
4
5
// 一部分数据
data:{
time: 5,
mTime: 300000
}

圆:右边是初始点,四分之一圆是 0.5 * Math.IP,上边是1.5 * Math.IP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
setInterval(() => {
// angle 根据时间的变化,改变成相应的大小
let angle = 1.5 + 2 * (_this.data.time * 60 * 1000 - _this.data.mTime) /
(_this.data.time * 60 * 1000)
// 100++ / mtime 假设当前绘制圆时间是10s,然后和总时间比例10s/mTime = rate,
//用rate*2,得出接下需要绘制多少弧度的圆。其实每次绘制都是从顶部零开始
// mTime会随着绘制的圆次数,而减少时间
let currentTime = _this.data.mTime - 100
_this.setData({
mTime: currentTime
})

if(angle < 3.5){
// 在这个范围内可以绘制,否则停止绘制

}
else{
// 停止绘制
clearInterval(timer)
}
},100)
1
2
3
4
5
6
7
8
9
10
11
12
13
// if(angle < 3.5) 内,绘制一个圆内
let lineWidth = 10 / this.data.rate//需要转换为像素单位,但不能直接使用像素单位
let ctx = wx.createCanvasContext('clock_active')
ctx.setLineWidth(lineWidth);
ctx.setStrokeStyle('#fff');
ctx.setLineCap('round');//填充边界的头形状
ctx.beginPath();

ctx.arc(400 / this.data.rate / 2, 400 / this.data.rate / 2,
400 / this.data.rate / 2 - 2 * lineWidth, 1.5 * Math.PI, angle * Math.PI, false)

ctx.stroke();//填充路径
ctx.draw();
1
……400 / this.data.rate / 2 - 2 * lineWidth, 1.5 * Math.PI, angle * Math.PI, false)

画圆方法封装

1
2
3
4
5
6
7
8
9
10
11
12
 drawYuan(lineWidth,canvas_id,canvas_color,width,start,end){
// 创建canvas路径
let ctx = wx.createCanvasContext(canvas_id)
ctx.setLineWidth(lineWidth/this.data.rate)
ctx.setStrokeStyle(canvas_color)
ctx.setLineCap('round')
ctx.beginPath()
ctx.arc(width/this.data.rate/2,width/this.data.rate/2,
width/this.data.rate/2-6,start,end,false)
ctx.stroke();//填充路径
ctx.draw();
},
  1. lineWidth 存放在data里面的数据,方法里面会自动转换比例
  2. canvas_id canvas的唯一标识canvas-id,而不是id
  3. canvas_color 路径填充颜色
  4. width 圆形的宽度,和长度
  5. start 花园的起始点,1.5 * Math.PI
  6. end 结束点

动态画圆其实一直是从起始点开始画,而不是接上之前的。

像素单位自适应

lineWidth 是像素px单位,因此微信小程序中无法使用px,但是使用rpx这种画圆方法不支持。

1
2
3
4
const res = wx.getSystemInfoSync();
console.log(res);//获取手机信息宽度啥的
const rate = 750 / res.windowWidth
console.log(rate);// 获取比例 小程序是宽度为750rpx

根据不同的手机信息,来获取不同的宽度比例,将lineWidth 转换为像素单位,且达到自适应效果