静态画圆

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 转换为像素单位,且达到自适应效果