小程序Progress组件介绍
进度条。组件属性的长度单位默认为px,2.4.0起支持传入单位(rpx/px)。
属性
小程序所有可视的组件都可以绑定tap事件bindtap,即使没有在属性里面显示的标明。
小程序中Boolean属性如果为真则只需要写上属性名就好了,如果要设置成假,则需要写成属性名=“false”。
属性 | 类型 | 默认值 | 必填 | 说明 |
percent | number | 否 | 百分比0~100 | |
show-info | boolean | false | 否 | 在进度条右侧显示百分比 |
border-radius | number/string | 0 | 否 | 圆角大小 |
font-size | number/string | 16 | 否 | 右侧百分比字体大小 |
stroke-width | number/string | 6 | 否 | 进度条线的宽度(这是从进度条前进的方向上来看的,从表象上来看,其实就是组件的高度) |
color | string | #09BB07 | 否 | 进度条颜色(请使用activeColor) |
activeColor | string | #09BB07 | 否 | 已选择的进度条的颜色 |
backgroundColor | string | #EBEBEB | 否 | 未选择的进度条的颜色 |
active | boolean | false | 否 | 进度条从左往右的动画 |
active-mode | string | backwards | 否 | backwards: 动画从头播;forwards:动画从上次结束点接着播(实践中一般使用forwards) |
duration | number | 30 | 否 | 进度增加1%所需毫秒数 |
bindactiveend | eventhandle | 否 | 动画完成事件 |
小程序颜色设计规范
- #09BB07 是默认的activeColor颜色,是完成色。
- #353535 也叫Semi,是大段说明文字且属于主要内容的,例如正文。
- #888888 也叫Grey,用于次要内容。
- #576b95 链接色。
- #e64340 警告色。
- 纯黑色Black一般用于主内容。
- 浅黑色Light一般用于时间戳与表单缺省值。
- backgroundColor默认的颜色值#EBEBEB。
- 在Weui代码库中,默认按钮的底色是#F2F2F2。
常见问题
如何实现一个下载文件并显示动态进度条的功能?
- 启用Progress属性active和active-mode =“forwards”。
- 通过文件总大小和下载完成大小,可以实时计算出percent的数值。需要注意的是percent属性是动态绑定的,每次此数值变化后,我们需要显示使用setData触发视图更新。
Progress已产生的进度条如何设置圆角?
<progress border-radius="5" percent="20" show-info />
Progress组件的border-radius属性设置的是组件外部的圆角大小,它无法设置内部已经前进的进度条圆角。
直接改变小程序Progress组件的内部样式,进行覆盖。
当然此方法是野路子,如果有一天微信团队修改了此类名,也就不能用了。
.wx-progress-inner-bar {
width:0;
height: 100%;
}
.wx-progress-inner-bar {
border-radius:5px;
}
已经加载完的进度条Progress,如何单击某个按钮让他重新加载呢?
有两种实现方法,但是原理都是延迟一部分操作到下一个时间片(渲染周期)再执行。
方法一,使用nextTick函数,或者在不支持nextTick的版本中使用setTimeout函数。
此处setTimeout时间设置为17ms,是由于一般手机屏幕的刷新频率是大于等于60赫兹,所以一秒60帧刷新能保证一个比较流畅的视觉效果,1000/60 = 16.6666 ms。
方法二,调用两次setData,因为每次setData在底层都需要调用evaluateJavascript这个底层函数,这个函数它用于小程序的逻辑层与视图层之间的通讯。他的执行本身就需要时间。
具体代码如下:
<view class="gap">已经加载完的进度条Progress,如何单击某个按钮让他重新加载呢?</view>
<button bindtap="resetProgress">重置</button>
<button bindtap="resetProgressYet">重置YET</button>
<progress border-radius="5" active-mode="forwards" active show-info percent="{{percentValue}}"></progress>
Page({
/**
* 页面的初始数据
*/
data: {
percentValue: 20,
},
resetProgress() {
this.setData({
percentValue: 0
});
if (wx.canIUse('nextTick')) {
wx.nextTick(() => {
this.setData({
percentValue: 100
});
});
} else {
setTimeout(() => {
this.setData({
percentValue: 0
});
}, 17)
}
},
resetProgressYet(){
this.setData({
percentValue: 0
});
this.setData({
percentValue: 100
});
},
})
能否设计一个环形进度条?
使用Canvas创建自定义组件:原理是这样的,用css设计两个圆,一个灰色的大部外圆,和一个白色的内部小圆,然后根据percent值的变化,控制canvas进行已完成进度的绘制。
- 在自定义组件中使用wx.createCanvasContent创建画布的上下文绘制对象时,需要在第二个参数处传递this对象。这样才是在组件中查找画布。不然就会变成了在引用它的页面中查找。
- 使用wx.createSelectorQuery创建对象的select方法,以ID查找组件对象时,如果在自定义组件中,必须在查找前先调用一下他的in方法,把this对象传递进去,不然组件是查找不到的。默认组件查询也只是在主页面查找,不会去查引用组件中的子组件。
具体代码如下:
- 组件代码
// progress/circle-progress/index.js
Component({
runTimeid: 0,
behaviors: [],
/**
* 组件的属性列表
*/
properties: {
percent: {
type: Number,
value: 50,
observer: function (newVal, oldVal) {
this.draw(newVal);
}
}
},
/**
* 组件的初始数据,属于私有数据,可用于模板渲染
*/
data: {
//百分比
percentage: '',
//动画执行时间
animTime: ''
},
ready() {
if (this.data.percent) this.draw(this.data.percent);
},
/**
* 组件的方法列表
*/
methods: {
// 绘制圆形进度条方法
run(c,w,h){
let that = this;
var num = (2 * Math.PI / 100 * c) - 0.5 * Math.PI;
that.ctx2.arc(w, h, w - 8, -0.5 * Math.PI, num);
that.ctx2.setStrokeStyle('#09bb07');//绿色
that.ctx2.setLineWidth('16');
that.ctx2.setLineCap('butt');
that.ctx2.stroke();
that.ctx2.beginPath();
that.ctx2.setFontSize(40);//设置字体大小,不能加引号
that.ctx2.setFillStyle('#b2b2b2');//灰色字体
that.ctx2.setTextAlign('center');
that.ctx2.setTextBaseline('middle');
that.ctx2.fillText(c+' %',w,h);
that.ctx2.draw();
},
// 实现动画效果
canvasTap(start,end,time,w,h){
let that = this;
start++;
if(start>end){
return false;
}
that.run(start,w,h);
that.runTimerid=setTimeout(function(){
that.canvasTap(start,end,time,w,h);
},time);
},
draw(percent) {
const id = 'runCanvas';
const animTime = 500;
if(percent>100)return
if(!this.ctx2){
const ctx2=wx.createCanvasContext(id, this)
this.ctx2 = ctx2
}
let oldPercentValue = this.data.percentage;
this.setData({
percentage:percent,
animTime:animTime
});
var time = this.data.animTime/(this.data.percentage-oldPercentValue);
const query = wx.createSelectorQuery().in(this)
query.select('#'+id).boundingClientRect((res)=>{
var w = parseInt(res.width/2);
var h = parseInt(res.height/2);
if(this.runTimeid) clearTimeout(this.runTimeid)
this.canvasTap(oldPercentValue,percent,time,w,h)
}).exec()
}
}
})
<!-- progress/circle-progress/index.wxml -->
<view class="canvasBox">
<!-- 外部灰色的圆 -->
<view class="bigCircle"></view>
<!-- 内部白色的圆 -->
<view class="littleCircle"></view>
<canvas canvas-id="runCanvas" id="runCanvas" class="canvas"></canvas>
</view>
/* progress/circle-progress/index.wxss */
.canvasBox {
height: 500rpx;
position: relative;
background-color: white;
}
.bigCircle {
width: 420rpx;
height: 420rpx;
border-radius: 50%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto auto;
background-color: #f2f2f2;
}
.littleCircle {
width: 350rpx;
height: 350rpx;
border-radius: 50%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto auto;
background-color: white;
}
.canvas {
width: 420rpx;
height: 420rpx;
border-radius: 50%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto auto;
z-index: 99;
}
- 页面使用代码
引用组件申明
{
"usingComponents": {
"circle-progress": "./circle-progres/index"
}
}
具体使用
<view class="gap">能否设计一个环形进度条?</view>
<circle-progress id="progress1" percent="{{percentValue}}" />
<button bindtap="drawProgress">绘制</button>
// progress/progress.js
Page({
/**
* 页面的初始数据
*/
data: {
percentValue: 20,
},
drawProgress(){
if(this.data.percentValue>=100){
this.setData({percentValue:0})
}
this.setData({percentValue:this.data.percentValue+10})
}
})
Progress组件进度的百分比数字怎么设置?
有两种方法:
第一种,直接覆盖组件内部的样式,这属于全局改变。
<view class="gap">Progress组件进度的百分比数字怎么设置?</view>
<progress percent="40" stroke-width="5" show-info />
.wx-progress-info{
color:red;
}
第二种,使用内联样式。
<view class="gap">Progress组件进度的百分比数字怎么设置?</view>
<progress percent="40" stroke-width="5" show-info style="color:red"/>
Progress组件右侧的百分比文字,与左边离得太近了,可否增加一个边距?
直接覆盖组件内部的样式。
<view class="gap">Progress组件右侧的百分比文字,与左边离得太近了,可否增加一个边距?</view>
<progress percent="40" stroke-width="5" show-info />
.wx-progress-info{
margin-left: 5px;
}