最近在开发小程序项目中用到slider滑块,配合canvas实现小程序环形进度条。
样式如下:
说明:slider是基础组件,比较简单,这里不做过多阐述
但是,如果想要了解如上关于
(1) slider加粗问题;
(2) slider刻度添加,和最终滑块值计算问题
(3) slider与环形进度条配合动态展示问题
可以私聊
(1)wxml
//创建画布
<canvas canvas-id="runCanvas" id="runCanvas" class='canvas'></canvas>
(2)js
//初始化画布
const ctx2 = wx.createCanvasContext(id);
//确定圆心
wx.createSelectorQuery().select('#'+id).boundingClientRect(function (rect) {
//监听canvas的宽高
console.log(rect);
var w = parseInt(rect.width / 2); //获取canvas宽的的一半
var h = parseInt(rect.height / 2); //获取canvas高的一半,
}).exec();
//画图开始
run(c, w, h) {
//c是圆环进度百分比 w,h是圆心的坐标
let that = this;
var num = (2 * Math.PI / 100 * c) - 0.5 * Math.PI;
//圆环的绘制
ctx2.arc(w, h, w - 8, -0.5 * Math.PI, num); //绘制的动作
ctx2.setStrokeStyle("#ff5000"); //圆环线条的颜色
ctx2.setLineWidth("16"); //圆环的粗细
ctx2.setLineCap("butt"); //圆环结束断点的样式 butt为平直边缘 round为圆形线帽 square为正方形线帽
ctx2.stroke();
//开始绘制百分比数字
ctx2.beginPath();
ctx2.setFontSize(40); // 字体大小 注意不要加引号
ctx2.setFillStyle("#ff5000"); // 字体颜色
ctx2.setTextAlign("center"); // 字体位置
ctx2.setTextBaseline("middle"); // 字体对齐方式
ctx2.fillText(c + "%", w, h); // 文字内容和文字坐标
ctx2.draw();
},
//实现动画
//实现动画效果其实使用定时器控制run方法一直执行。
canvasTap(start, end, time, w, h) {
//传入开始百分比和结束百分比的值,动画执行的时间,还有圆心横纵坐标
var that = this;
start++;
if (start > end) {
return false;
}
that.run(start, w, h); //调用run方法
setTimeout(function () {
that.canvasTap(start, end, time, w, h);
}, time);
},
canvas 是原生组件,所以z-index对其无效。
canvas 绘制使用的单位都是 px 所以设置 宽高应该都是 px 。或者全部都是用自定义比例
export default{
data: {
percentage: '', //百分比
animTime: '', // 动画执行时间
},
options:{
// 绘制圆形进度条方法
run(c, w, h) {
let that = this;
// var num = (2 * Math.PI / 100 * c) - 0.5 * Math.PI;
var num = (2 * Math.PI / 100 * c) - 1.2 * Math.PI;
console.log(num,'看下num')
// that.data.ctx2.arc(w, h, w - 8, -0.5 * Math.PI, num); //每个间隔绘制的弧度
that.data.ctx2.arc(w, h, w - 8, -1.2 * Math.PI, num); //每个间隔绘制的弧度
that.data.ctx2.setStrokeStyle("#169171");
that.data.ctx2.setLineWidth("16");
that.data.ctx2.setLineCap("butt");
that.data.ctx2.stroke();
that.data.ctx2.beginPath();
that.data.ctx2.setFontSize(40); //注意不要加引号
that.data.ctx2.setFillStyle("#ff5000");
that.data.ctx2.setTextAlign("center");
that.data.ctx2.setTextBaseline("middle");
// 取出填充百分比
// that.data.ctx2.fillText(c + "%", w, h);
that.data.ctx2.draw();
},
/**
* start 起始百分比
* end 结束百分比
* w,h 其实就是圆心横纵坐标
*/
// 动画效果实现
canvasTap(start, end, time, w, h) {
var that = this;
start++;
if (start > end) {
return false;
}
that.run(start, w, h);
setTimeout(function () {
that.canvasTap(start, end, time, w, h);
}, time);
// that.canvasTap(start, end, time, w, h);
},
/**
* id----------------canvas画板id
* percent-----------进度条百分比
* time--------------画图动画执行的时间
*/
draw: function (id, percent, animTime) {
var that = this;
const ctx2 = wx.createCanvasContext(id);
that.setData({
ctx2:ctx2,
percentage:percent,
animTime: animTime
});
var time = that.data.animTime / that.data.percentage;
wx.createSelectorQuery().select('#'+id).boundingClientRect(function (rect) {
//监听canvas的宽高
var w = parseInt(rect.width / 2); //获取canvas宽的的一半
var h = parseInt(rect.height / 2); //获取canvas高的一半,
that.canvasTap(0, that.data.percentage, time, w, h)
}).exec();
},
}
}
(1) 引入
import Canvas from '../../utils/canvas.js'
(2) 解构
Page({
...Canvas.options,
data: {
...Canvas.data,
},
(3) 使用
onLoad: function (options) {
this.draw('runCanvas',100,1000);
},
本文重点内容是:canvas基本使用,方法封装及页面使用;
疑问解答:
(1)调用时更新传入数据页面可以重新绘制,可以,可以哦
(2)如果在电脑模拟器上效果完美,我设置的5s钟走完整个进度,但是手机(真机调试时)它需要走很久才能走完的问题;
解答:方案1,如果不是同时使用多个canvas,直接发布体验版查看即可(忽略性能为代价)
方案2,将封装的canvas.js中的定时器去掉,再尝试下就可以了
(3)关于canvas层级过高问题,请参考我的另一篇博文
canvas层级过高问题的解决方案
参考文章:https://blog.csdn.net/weixin_41257563/article/details/83542225;