微信小程序利用canvas绘制一个动画百分比圆圈
在一次项目开发中,有个应用需求,就是不仅展示用户答题之后的分数和测评等级,还要利用动画圆圈的形式展示用户完成比。首先一般先想到的就是利用canvas绘图,因为如果用CSS来制作的话会很麻烦,而且还要配合脚本一起完成才行。HTML5 <canvas> 标签用于绘制图像(通过脚本,通常是 JavaScript)。不过,<canvas> 元素本身并
在一次项目开发中,有个应用需求,就是不仅展示用户答题之后的分数和测评等级,还要利用动画圆圈的形式展示用户完成比。
首先一般先想到的就是利用canvas绘图,因为如果用CSS来制作的话会很麻烦,而且还要配合脚本一起完成才行。
HTML5 <canvas> 标签用于绘制图像(通过脚本,通常是 JavaScript)。
不过,<canvas> 元素本身并没有绘制能力(它仅仅是图形的容器) - 您必须使用脚本来完成实际的绘图任务。
getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性。
getContext("2d") 对象属性和方法,可用于在画布上绘制文本、线条、矩形、圆形等等。
具体可查看w3c官网文档里给出的介绍:http://www.w3school.com.cn/tags/html_ref_canvas.asp
还有小程序官网平台给出的文档:https://developers.weixin.qq.com/miniprogram/dev/component/canvas.html?search-key=arc
好,现在开始正式绘制这个需求。
canvas其中有一个属性是绘图的关键,那就是它的arc属性,具体是这样的:
let cxt_arc = wx.createCanvasContext('canvasArc');//创建并返回绘图上下文context对象。
/*
cxt_arc.arc(x, y, r, sAngle, eAngle, counterclockwise);
x Number 圆的x坐标
y Number 圆的y坐标
r Number 圆的半径
sAngle Number 起始弧度,单位弧度(在3点钟方向)
eAngle Number 终止弧度
counterclockwise Boolean 可选。指定弧度的方向是逆时针还是顺时针。默认是false,即顺时针。
*/
这里尤其要特别注意的是第四个参数,第四个参数代表绘图的起始弧度,并且默认是从三点钟方向开始的,所以如果想从12点钟方向开始绘图的话,需要将第四个参数设置为:- Math.PI * 1 / 2。意思很明显,因为第六个参数是指绘图的方向,如果设置为false,那就是顺时针,一般也设置为顺时针,因为12点钟是在3点钟的逆时针方向上,所以第四个参数应该为负数,即需要负整个圆的四分之一,因为2*PI代表的是整个圆,那么1/2就是四分之一圆了,所以要想从12点钟开始绘图,那么第四个参数需设置为:- Math.PI * 1 / 2。
好,接下来直接上代码:
上代码之前,这里给三个个提示:
1.就是脚本里面设置的一些关系像素的数据默认都是px,而现在小程序为了兼容各个移动终端,给出了一个新的像素单位,就是rpx。但是canvas绘图是与脚本一起完成的,所以这里建议大家还是统一像素单位比较好;
2.下面我是用定时器setInterval实现的,一定要注意的是,一旦启用定时器,那么在实现你的功能之后,一定要记得关闭;
3.微信小程序里有一个用于展示进度的组件<progress>,大家可以直接调用,但是比较局限。链接:https://developers.weixin.qq.com/miniprogram/dev/component/progress.html?search-key=progress
HTML部分:
<view class='circleBar'>
<view class="wrap">
<view class="top">
<canvas class="cir" style=' width:106px; height:106px;' canvas-id="canvasArc"></canvas>
<view class="centerWord">{{resultComment}}</view>
</view>
</view>
</view>
CSS部分:
/* 圆形进度条 */
.circleBar {
width: 100%;
height: auto;
overflow: hidden;
position: relative;
}
.cir {
display: inline-block;
background-color: #fff;
border-radius: 100%;
}
.top {
text-align: center;
}
.centerWord {
width: 100%;
position: absolute;
top: 40px;
left: 0;
text-align: center;
color: #3686ff;
}
JS部分:
Page({
/**
* 页面的初始数据
*/
data: {
timer: ''
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 页面初始化 options为页面跳转所带来的参数
let that = this;
// 以下两个是测试数据
let totalItems = 100;
let rightItems = 80;
let completePercent = parseInt((rightItems / totalItems) * 100);
that.getResultComment(completePercent);
that.showScoreAnimation(rightItems, totalItems);
},
showScoreAnimation: function (rightItems, totalItems) {
/*
cxt_arc.arc(x, y, r, sAngle, eAngle, counterclockwise);
x Number 圆的x坐标
y Number 圆的y坐标
r Number 圆的半径
sAngle Number 起始弧度,单位弧度(在3点钟方向)
eAngle Number 终止弧度
counterclockwise Boolean 可选。指定弧度的方向是逆时针还是顺时针。默认是false,即顺时针。
*/
let that = this;
let copyRightItems = 0;
that.setData({
timer: setInterval(function () {
copyRightItems++;
if (copyRightItems == rightItems) {
clearInterval(that.data.timer)
} else {
// 页面渲染完成
// 这部分是灰色底层
let cxt_arc = wx.createCanvasContext('canvasArc');//创建并返回绘图上下文context对象。
cxt_arc.setLineWidth(6);//绘线的宽度
cxt_arc.setStrokeStyle('#d2d2d2');//绘线的颜色
cxt_arc.setLineCap('round');//线条端点样式
cxt_arc.beginPath();//开始一个新的路径
cxt_arc.arc(53, 53, 50, 0, 2 * Math.PI, false);//设置一个原点(53,53),半径为50的圆的路径到当前路径
cxt_arc.stroke();//对当前路径进行描边
//这部分是蓝色部分
cxt_arc.setLineWidth(6);
cxt_arc.setStrokeStyle('#3ea6ff');
cxt_arc.setLineCap('round')
cxt_arc.beginPath();//开始一个新的路径
cxt_arc.arc(53, 53, 50, -Math.PI * 1 / 2, 2 * Math.PI * (copyRightItems / totalItems) - Math.PI * 1 / 2, false);
cxt_arc.stroke();//对当前路径进行描边
cxt_arc.draw();
}
}, 20)
})
},
getResultComment: function (completePercent) {
let that = this;
switch (true) {
case completePercent < 60:
that.setData({
resultComment: "渣渣"
})
break;
case completePercent >= 60 && completePercent <= 69:
that.setData({
resultComment: "学弱"
})
break;
case completePercent >= 70 && completePercent < 80:
that.setData({
resultComment: "中等"
})
break;
case completePercent >= 80 && completePercent < 90:
that.setData({
resultComment: "良好"
})
break;
case completePercent >= 90 && completePercent < 95:
that.setData({
resultComment: "优秀"
})
break;
case completePercent >= 95 && completePercent < 100:
that.setData({
resultComment: "学霸"
})
break;
case completePercent >= 100:
that.setData({
resultComment: "学神"
})
break;
}
},
})
下来是效果展示图:
更多推荐
所有评论(0)