小程序canvas画环形百分比进度图
组件封装
component/canvas-ring目录下
canvas-ring.js
<canvas style="width:{{canvasWidth}}px;height:{{canvasWidth}}px; margin:0 auto;position:relative" type="2d" id="myCanvas">
<view class="circle-bar" style="height:{{canvasWidth}}px;">
<view class="title_val" style="color: {{valueColor}}; font-weight:{{f_weight}}; margin-top:{{show_tip?'10':'0'}}rpx;font-size:{{f_size}}px">
{{value}}
<p style="font-size: 10px;display: inline;">
{{suffix}}
</p>
</view>
<view class="title_name" style="color: {{lineColor}};">
{{title}}
</view>
</view>
</canvas>
canvas-ring.json
{
"component": true,
"usingComponents": {}
}
canvas-ring.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;
}
.circle-bar .title_val{
color: #333333;
}
canvas-ring.js
var windWidth = wx.getSystemInfoSync().windowWidth; //这里获取下设备的屏幕宽度
Component({
/**
* 组件的属性列表
*/
properties: {
//画布的宽度 默认占屏幕宽度的0.4倍
canvasWidth: {
type: Number,
value: windWidth * 0.4
},
//线条宽度 默认10
lineWidth: {
type: Number,
value: 10
},
//线条颜色
lineColor: {
type: String,
value: "#3696FA"
},
//标题 默认“完成率”
title: {
type: String,
value: "完成率"
},
//当前的值 默认45
value: {
type: Number,
value: 50
},
//值的颜色 默认””
valueColor: {
type: String,
value: "#333"
},
//值的字体的大小颜色 默认
f_size: {
type: Number,
value: 14
},
f_weight: {
type: String,
value: "500"
},
//最大值 默认100
maxValue: {
type: Number,
value: 100
},
//最小值 默认0
minValue: {
type: Number,
value: 0
},
//当前值的后缀名
suffix: {
type: null,
value: "%"
},
//从什么角度开始 0~360之间 (12点方向为0,18点方向为180,0点方向为360)
startDegree: {
type: Number,
value: 0
}
},
data: {
canvasWidth: windWidth * 0.4, //默认创建的环形图宽度为屏幕宽度的40%
show_tip: true
},
methods: {
drawCanvasRing() {
//没标题的时候去掉margin-top的值
if (this.data.title.replace(/(^\s*)|(\s*$)/g, "").length == 0) {
this.setData({
show_tip: false
})
}
//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(() => {})
const dpr = wx.getSystemInfoSync().pixelRatio
canvas.width = res[0].width * dpr
canvas.height = res[0].height * dpr
ctx.scale(dpr, dpr);
// 大小值的计算
var circle_r = this.data.canvasWidth / 2; //画布的一半,用来找中心点和半径
var startDegree = this.data.startDegree; //从什么角度开始
var maxValue = this.data.maxValue; //最大值
var minValue = this.data.minValue; //最小值
var value = this.data.value; //当前的值
var lineColor = this.data.lineColor; //线条颜色
var lineWidth = this.data.lineWidth; //线条宽度
var percent = 360 * ((value - minValue) / (maxValue - minValue)); //计算结果
//定义起始点
ctx.translate(circle_r, circle_r);
//灰色圆弧
ctx.beginPath();
ctx.strokeStyle = "#ebebeb";
ctx.lineWidth = lineWidth;
ctx.arc(0, 0, circle_r - 10, 0, 2 * Math.PI, true);
ctx.stroke();
ctx.closePath();
//有色彩的圆弧
ctx.beginPath();
ctx.strokeStyle = lineColor;
ctx.lineWidth = lineWidth;
ctx.arc(0, 0, circle_r - 10, startDegree * Math.PI / 180 - 0.5 * Math.PI, percent * Math.PI / 180 + startDegree * Math.PI / 180 - 0.5 * Math.PI, false);
ctx.stroke();
ctx.closePath();
console.log(this.data.value);
}
}
})
使用
父页面
canvas.js
/**
* 页面的初始数据
*/
data: {
completePercent: 10, //圆环A的动态值
completePercent2: 60 //圆环B的动态值
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: async function (options) {
await tools.request('/main/mainTest', {
id: 1,
}, 'get').then((res) => {
if (res.data.code == 1) {
this.setData({
completePercent: res.data.data.score.before,
completePercent2: res.data.data.score.finish,
})
} else {
wx.showToast({
title: res.data.msg,
icon: 'none',
})
}
})
await this.getRingsA();
await this.getRingsB();
},
方法
getRingsA() {
this.canvasRing = this.selectComponent("#canringA");
this.canvasRing.drawCanvasRing() //绘制圆环A
},
getRingsB() {
this.canvasRing2 = this.selectComponent("#canringB");
this.canvasRing2.drawCanvasRing() //绘制圆环B
},
canvas.wxml
<canvas2d-ring type="2d" id="canringA" canvasWidth="{{120}}" f_weight="bold" value="{{completePercent}}" lineColor="#EA0000" f_size="21" lineWidth="{{10}}" title="{{'施工前'}}"></canvas2d-ring>
canvas.json
{
"navigationStyle":"custom",
"component": true,
"usingComponents": {
"canvas2d-ring": "/component/canvas-ring/canvas-ring"
}
}