⼩程序利⽤canvas绘制⼀个动画百分⽐圆圈
在⼀次项⽬开发中,有个应⽤需求,就是不仅展⽰⽤户答题之后的分数和测评等级,还要利⽤动画圆圈的形式展⽰⽤户完成⽐。
⾸先⼀般先想到的就是利⽤canvas绘图,因为如果⽤CSS来制作的话会很⿇烦,⽽且还要配合脚本⼀起完成才⾏。
HTML5 <canvas> 标签⽤于绘制图像(通过脚本,通常是 JavaScript)。
不过,<canvas> 元素本⾝并没有绘制能⼒(它仅仅是图形的容器) - 您必须使⽤脚本来完成实际的绘图任务。
getContext() ⽅法可返回⼀个对象,该对象提供了⽤于在画布上绘图的⽅法和属性。
getContext("2d") 对象属性和⽅法,可⽤于在画布上绘制⽂本、线条、矩形、圆形等等。
好,现在开始正式绘制这个需求。
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实现的,⼀定要注意的是,⼀旦启⽤定时器,那么在实现你的功能之后,⼀定要记得关闭;
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.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();//对当前路径进⾏描边canvas动画
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;
}
},
})
下来是效果展⽰图:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。