明天分享一个环形进度条的写法,当然这只是一个可动的动态进度条,如果你喜爱能够退出后盾数据。这种进度条非常简单的写法到处都有,只不过更多的只是写个样子,咱们这个能够动哟。
前提是 canvas 的属性、办法和一些根底的 js API 你都晓得,当然为了保障一些遗记的小伙伴一下想起来,我会在后面列个表。
属性和办法 | 形容 |
---|---|
getContext() | 返回一个用于在画布上绘图的环境 |
strokeStyle | 画笔(绘制图形)色彩或者款式的属性 |
lineWidth | 设置线段厚度的属性 |
save() | 保留 canvas 全副状态的办法(入栈) |
beginPath() | 创立一个新的门路的办法 |
arc(原点 x, 原点 y, 半径, 起始角度, 完结角度, 默认 false 顺时针) | 绘制圆弧门路的办法 |
stroke() | 绘制门路的办法 |
closePath() | 闭合绘制门路 |
restore() | 复原到最近的保留状态的办法(出栈) |
fillStyle | 色彩和款式的属性 |
font | 以后字体款式的属性 |
toFixed(num) | 把 Number 四舍五入为指定小数位数的数字 |
回顾完上表开始绘制图形,图形的绘制除了 canvas 元素之外还有以下几个局部,我先离开把代码按局部写出:
(1)创立 canvas 元素
先创立一个 canvas 的标签给出宽高,绘制环形进度宽高统一就能够,之后获取元素,并创立画布。留神 canvas 元素这里起名 mycanvas,绘制的画布对象叫 ctx。
<canvas id="mycanvas" width="200" height="200"></canvas>
// 以下为 js 代码
var mycanvas = document.getElementById('mycanvas');
var ctx = mycanvas.getContext('2d');
(2)绘制的筹备工作
绘制之前须要做一些筹备工作
- 找到“画布的中心点”的,进度条
- 将进度条依照进度的比例分成 100 份,依照 100% 实现
- 指定初始加载步长(长度),留神这是初始化前期能够改成 0
// 找到画布的中心点
var canvasX = mycanvas.width / 2;
var canvasY = mycanvas.height / 2;
// 进度条是 100%,所以要把一圈 360 度分成 100 份
var progress = Math.PI * 2 / 100;
// 指定初始加载步长
var steps = 0.5;
(3)绘制环形底层
先把进度的环形底层浅灰色的环绘制进去,它是进度的门路。能够先把绘制的色彩和线宽指定好,这两个属性对上面的办法程序起不到影响。
ctx.strokeStyle = '#dddddd';
ctx.lineWidth = 20;
ctx.save();
ctx.beginPath();
ctx.arc(canvasX, canvasY, 90, 0, Math.PI * 2, false)
ctx.stroke();
ctx.closePath();
ctx.restore();
(4)绘制进度层
进度层绘制的色彩须要定义进去,另外进度条的粗细与底层环形的粗细雷同。这里最重要的一句是,在完结角度的时候退出了“steps progress”步长 进度。steps 数值越小乘成数之后减少的角度就少,steps 数值大乘数之后进度减少的就多。
ctx.strokeStyle = "#47cab0";
ctx.lineWidth = 20;
ctx.save();
ctx.beginPath();
ctx.arc(canvasX,canvasY,90, -Math.PI/2, -Math.PI/2+steps*progress,false);
ctx.stroke();
ctx.closePath();
ctx.restore();
(5)绘制字体并指定地位
环形的进度百分比文字显示须要应用 canvas 的文字绘制,这里须要留神数字是从 1 位到 3 位的跨度,还要退出 %,因而地位须要变动。当数字到 100 时文字占宽就更大因而要扭转绘制终点。
ctx.fillStyle = "#000000"; // 可改
ctx.font = "bold 26px Arial"; // 可改
ctx.save();
// canvasX-30, canvasY+10 中的加减的数值可改
if (steps.toFixed(0).length == 3) {ctx.fillText(steps.toFixed(0) + '%', canvasX - 30, canvasY + 10);
} else {ctx.fillText(steps.toFixed(0) + '%', canvasX - 20, canvasY + 10);
}
ctx.restore();
写到这里动态的一个进度就会呈现,然而咱们还须要让他动起来,大家可能想到的定时器。但咱们却应用了另一种编写循环动画的办法。
(6)进度动画
显示器的刷新频率通常是 50~60hz,1000ms/60≈16.6ms,相当于每秒钟重绘 60 次,大多数浏览器都不会超过显示器的重绘频率。之前的文章咱们已经提到过 setTimeout() 和 setInterval() 这两种循环其实并不那么精准智能,即便应用 setTimeout() 以自调的形式模仿循环定时器,也不能确保解决线程能够依照现实之行。
window.requestAnimationFrame()
window.requestAnimationFrame() 通知浏览器——你心愿执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该办法须要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。回调函数执行次数通常是每秒 60 次,但在大多数遵循 W3C 倡议的浏览器中,回调函数执行次数通常与浏览器屏幕刷新次数相匹配。为了进步性能和电池寿命,因而在大多数浏览器里,当 requestAnimationFrame() 运行在后盾标签页或者暗藏的 <iframe> 里时,requestAnimationFrame() 会被暂停调用以晋升性能和电池寿命。
因而为了保障平滑渲染,咱们应用,window.requestAnimationFrame(),在该办法的参数一个回调函数中做几件事:
1. 判断实现整个环形步长的完结值,如:100,其实就是走到 100% 的地位,75 就是走到 75% 的地位
2. 在抉择的步长范畴内调用增长的函数
window.requestAnimationFrame(function () {
// 判断步子最终走多远的边界值,此值能够改
if (steps < 90) {// 该函数在边界内能够调用函数,减少步长并且绘制图形给这个函数起个名字}
})
因为有函数的自调用,所以咱们把这部分写在一起,不拆分写了。难度就在此处!
第一步:要先做,把之前所有的绘制图形代码放入新创建的函数 DrawShape 中,并且须要接管两个参数。一个是要绘制的对象,因为一个页面上不止一个画布对象。第二个参数就是每次会扭转的步长。
// 绘制形态函数, 传入画布对象和每次都会扭转的步长
function DrawShape(ctx,steps) {
// 画圆
画底层圆形的代码...
// 画进度环
画进度条的代码...
// 绘制字体并指定地位
绘制字体的代码...
}
第二步:创立 animate 函数用来执:平滑动画、行步长的减少、绘制图形三件重要事宜。
// 初始调用动画函数
animate();
// 动画函数
function animate() {
// 执行平滑动画
window.requestAnimationFrame(function () {
// 判断步子最终走多远的边界值,此值能够改
if (steps < 90) {
// 该函数在边界内能够调用
animate();}
});
// 清空绘制内容
ctx.clearRect(0, 0, mycanvas.width, mycanvas.height);
// 每次减少的步长,数值越大步子越大跑的越快,数值越小走的越慢
steps += 0.5;// 可改
// 调用绘制形态函数,传入参数绘制对象,环形进度步长
DrawShape(ctx,steps);
};
以上代码是全副代码只是没有合并整顿格局,大家能够本人整顿,但因代码有 82 行不便于放在公众号内,因而曾经将代码放入百度云盘。
编写文章不易心愿大家能加公众号 amber-web,之后可凭朋友圈或转发截图分割并发给管理员微信号:“zyn-amber”取得整顿清晰并附有具体正文的代码链接。