1.首先因为最初绘制环形使用的是小程序canvas, wx.createCanvasContext
,但是由于canvas不支持同层渲染层级过高,并且wx.createCanvasContext
已停用。所以更改为type=2d,wx.createSelectorQuery()
来绘制环形进度条
此外:canvas2d真机同层渲染才生效,微信开发工具有问题
(1):wxml,wxss内容
<canvas style="width:{{canvasWidth}}rpx;height:{{canvasWidth}}rpx; position:relative" type="2d" id="myCanvas" >
<view class="circle-bar" style="height:{{canvasWidth}}rpx;">
<view class="title_name" style="color: {{valueColor}}; ">
{{title}}
</view>
<view class="title_val" style="color: {{valueColor}}; font-weight:{{f_weight}}; font-size:{{f_size}}rpx">
{{value}} {{suffix}}
</view>
</view>
</canvas>
//wxss内容
.circle-bar{
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
position: absolute;
top: 0;
}
.circle-bar .title_name{
max-height: 62rpx;
font-size: 26rpx;
overflow:hidden;
text-overflow:ellipsis;
display:-webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:2;
}
js内容
。
var windWidth = wx.getSystemInfoSync().windowWidth;
//为了适配所有屏幕,这里之前所有像素单位赋值之前都要换成以rpx为单位的大小乘以xs
const xs = windWidth / 750;
Component({
/**
* 组件的属性列表
*/
properties: {
//画布的宽度 默认占屏幕宽度的0.4倍
canvasWidth: {
type: Number,
value: windWidth * 0.4 *xs
},
//线条宽度 默认12,单位rpx
lineWidth: {
type: Number,
value: 8
},
//线条颜色
lineColor: {
type: String,
value: "#3696FA"
},
//进度条最大值 默认100
maxValue: {
type: Number,
value: 100
},
//进度条最小值
minValue:{
type: Number,
value: 0
},
//进度条的弧度大小,最小值为0,最大值为1,默认为1代表绘制一个圆的弧度也就是360°
radian: {
type: Number,
value: 3 / 4
},
//当前进度值的方向,只在radian为1时起作用,可填left(九点钟方向开始),top(12点钟方向开始),bottom(6点钟方向开始),right(3点钟方向开)
direction: {
type: String,
value: "top"
},
//标题
title: {
type: String,
value: "已抢"
},
//当前显示的文字值 默认45
value: {
type: Number,
value: 45
},
//值的颜色 默认""
valueColor:{
type: String,
value: "#E3AF6A"
},
//中间字体大小,单位rpx
f_size: {
type: Number,
value: 30
},
//当前值的后缀名
suffix: {
type: null,
value: "%"
},
f_weight:{
type: String,
value: "500"
},
},
/**
* 组件的初始数据
*/
data: {
canvasWidth:' windWidth * 0.4 * xs',
},
// observers 属性,设置需要监听的属性
observers:{
'value'(val){
this.drawCanvasRing();
},
},
lifetimes:{
attached(){
}
},
/**
* 组件的方法列表
*/
methods: {
drawCanvasRing() {
//canvas 2d
const query = wx.createSelectorQuery().in(this);
query.select('#myCanvas')
.fields({ node: true , size: true})
.exec(this.init.bind(this))
},
init(res){
const canvas = res[0].node
const ctx = canvas.getContext('2d');
//canvas.requestAnimationFrame(()=>{
// console.log('1111111111111111111111')
//})
const dpr = wx.getSystemInfoSync().pixelRatio
var radian = this.data.radian//弧度大小
radian=radian>1?1:radian //控制最大值为1
radian=radian<0?0:radian //控制最小值为0
canvas.width = res[0].width * dpr
canvas.height = res[0].height * dpr
ctx.scale(dpr, dpr);
// 大小值的计算
var circle_r = this.data.canvasWidth *xs / 2; //画布的一半,用来找中心点和半径
var maxValue = this.data.maxValue; //最大值
var minvalue= this.data.minvalue; //当前进度值
var lineColor = this.data.lineColor; //线条颜色
var lineWidth = this.data.lineWidth* xs; //线条宽度
//计算弧形的起点,这是为了保证起点和终点在同一水平线上
var startPath = Math.PI * (3 / 2 - radian)
var endPath = startPath + 2 * Math.PI * radian
//定义起始点
ctx.translate(circle_r, circle_r);
//灰色圆弧
ctx.beginPath();
ctx.strokeStyle="#ebebeb";
ctx.lineWidth=lineWidth;
ctx.arc(0, 0, circle_r - lineWidth / 2, startPath, endPath, false);
ctx.lineCap ="round" //末端圆弧
ctx.stroke();
ctx.closePath();
//计算当前进度弧形大小,环形总长度为Math.PI*2
var percent = 2 * Math.PI * radian * (minvalue/ maxValue)
var currStartPath = startPath //当前进度值的起点位置
//如果radian为1则使用自定义的起始位置
if (radian == 1) {
var direction = this.data.direction//当前进度值
switch (direction) {
case 'left':
currStartPath =Math.PI //九点钟方向
break
case 'top':
currStartPath = 3 / 2 * Math.PI //十二点钟方向
break
case 'right':
currStartPath = 0 //三点钟方向
break
case 'bottom':
currStartPath = 1 / 2 * Math.PI //六点钟方向
break
}
}
//有色彩的圆弧
ctx.beginPath();
ctx.strokeStyle=lineColor;
ctx.lineWidth=lineWidth;
ctx.arc(0, 0, circle_r - lineWidth / 2, currStartPath, percent + currStartPath, false);
ctx.lineCap ="round" //末端圆弧
ctx.stroke();
ctx.closePath();
}
}
})
父组件引用
<mycanvas canvasWidth="{{165}}" maxValue="{{item.kcqty}}" minValue="{{item.sales}}" value="{{(item.sales)/(item.kcqty)*100}}" lineColor="{{zt_color}}"></mycanvas>