乐趣区

关于javascript:可动的canvas进度条

明天分享一个环形进度条的写法,当然这只是一个可动的动态进度条,如果你喜爱能够退出后盾数据。这种进度条非常简单的写法到处都有,只不过更多的只是写个样子,咱们这个能够动哟。

前提是 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)绘制的筹备工作

绘制之前须要做一些筹备工作

  1. 找到“画布的中心点”的,进度条
  2. 将进度条依照进度的比例分成 100 份,依照 100% 实现
  3. 指定初始加载步长(长度),留神这是初始化前期能够改成 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”取得整顿清晰并附有具体正文的代码链接。

退出移动版