1.整理下思路,要获取异步加载JS文件的进度要怎么做?
答:将需要异步载入的文件放进一个数组中。如下。
const scriptArr = ['./test_1.js', './test_3.js', './test_4.js', './test_5.js'];
然后动态创建script标签插入到body标签中。通过script.onload获取JS是否加载完毕
2.怎么绘制一个动态的canvas环形loading加载图?
答:需要用到的canvas 核心Api有:ctx.arc()。这是绘制园环的必须api.
3.既然能获取到加载完毕的回调函数,也能够创建一个canvas loading实例,如何把它们关联到一起整合到一块?
-
编写一个circleProgress类,用来创建环形loading实例
class CircleProgress { constructor(ctxs, width, height, arc) { this.ctx = ctxs this.width = width this.height = height this.arc = arc this.setArea(width, height) } //设置canvas的宽高 setArea(width, height) { this.ctx.canvas.width = width this.ctx.canvas.height = height } //清除画布 clearFill() { this.ctx.clearRect(0, 0, this.width, this.width); } //绘制环形进度图的背景 颜色是可配置的 fillBg() { this.ctx.beginPath(); this.ctx.lineWidth = this.arc; this.ctx.strokeStyle = '#ccc'; this.ctx.arc(this.width / 2, this.width / 2, 45, 0, 2 * Math.PI); this.ctx.stroke(); } //绘制进度条 fillArc(x) { this.ctx.beginPath(); this.ctx.lineWidth = this.arc; this.ctx.strokeStyle = 'yellow'; this.ctx.arc(this.width / 2, this.width / 2, 45, -90 * Math.PI / 180, (x * 3.6 - 90) * Math.PI / 180); this.ctx.stroke(); } //绘制中心数字展示 fillText(x) { this.ctx.font = '14px' + ' Arial'; this.ctx.fillStyle = 'red'; this.ctx.textBaseline = "middle"; this.ctx.textAlign = 'center'; this.ctx.fillText(x.toFixed(1) + '%', this.width / 2, this.width / 2); } //总绘制方法 fill(x) { this.fillBg(); this.fillArc(x); this.fillText(x); } }
大概就是这个样子
- 获取当前JS,加载进度
function jsProgress(circle, eachs, max, scriptArr) {
let currentIndex = 0;
//遍历所有文件名
for (let i = 0; i < scriptArr.length; i++) {
let scriptNode = document.createElement('script');
scriptNode.src = scriptArr[i];
//插入创建好的script引用节点
document.getElementById('bodys').appendChild(scriptNode);
//创建分布值 每个文件占据的进度值 比如4个文件 每个文件占据100/4=25
let steps = 0;
//插入的文件加载完毕后的回调
scriptNode.onload = function() {
//按照每20毫秒一帧渲染canvas画布 以展示出动态的加载效果
let ani = setInterval(function() {
//此处可以优化,有好的建议可以告诉我
if (steps <= max || steps == 100) {
circle.clearFill();
if (steps > 100) {
steps = 100
}
circle.fill(steps)
steps++
} else {
clearInterval(ani)
if (max <= 100) {
max = max + eachs
currentIndex++;
}
if (currentIndex == scriptArr.length) {
console.log(`全部JS加载完成`)
}
console.log(`sciprtNode${i}已加载完成`)
}
}, 20)
}
}
}
最终效果
附录:全部代码
<script>
class CircleProgress {
constructor(ctxs, width, height, arc) {
this.ctx = ctxs
this.width = width
this.height = height
this.arc = arc
this.setArea(width, height)
}
setArea(width, height) {
this.ctx.canvas.width = width
this.ctx.canvas.height = height
}
clearFill() {
this.ctx.clearRect(0, 0, this.width, this.width);
}
fillBg() {
this.ctx.beginPath();
this.ctx.lineWidth = this.arc;
this.ctx.strokeStyle = '#ccc';
this.ctx.arc(this.width / 2, this.width / 2, 45, 0, 2 * Math.PI);
this.ctx.stroke();
}
fillArc(x) {
this.ctx.beginPath();
this.ctx.lineWidth = this.arc;
this.ctx.strokeStyle = 'yellow';
this.ctx.arc(this.width / 2, this.width / 2, 45, -90 * Math.PI / 180, (x * 3.6 - 90) * Math.PI / 180);
this.ctx.stroke();
}
fillText(x) {
this.ctx.font = '14px' + ' Arial';
this.ctx.fillStyle = 'red';
this.ctx.textBaseline = "middle";
this.ctx.textAlign = 'center';
this.ctx.fillText(x.toFixed(1) + '%', this.width / 2, this.width / 2);
}
fill(x) {
this.fillBg();
this.fillArc(x);
this.fillText(x);
}
testFn() {
ctxs.beginPath();
ctxs.lineWidth = 10;
ctxs.strokeStyle = '#ccc';
ctxs.arc(50, 50, 45, 0, 2 * Math.PI);
ctxs.stroke();
}
}
function jsProgress(circle, eachs, max, scriptArr) {
let currentIndex = 0;
for (let i = 0; i < scriptArr.length; i++) {
let scriptNode = document.createElement('script');
scriptNode.src = scriptArr[i];
document.getElementById('bodys').appendChild(scriptNode);
let steps = 0;
scriptNode.onload = function() {
let ani = setInterval(function() {
if (steps <= max || steps == 100) {
circle.clearFill();
if (steps > 100) {
steps = 100
}
circle.fill(steps)
steps++
} else {
clearInterval(ani)
if (max <= 100) {
max = max + eachs
currentIndex++;
}
console.log(`sciprtNode${i}已加载完成`)
if (currentIndex == scriptArr.length) {
console.log(`全部JS加载完成`)
}
}
}, 20)
}
}
}
const scriptArr = ['./test_1.js', './test_3.js', './test_4.js', './test_5.js'];
let canvasNode = document.getElementById('canvas'),
ctxs = canvasNode.getContext("2d");
let circle = new CircleProgress(ctxs, 100, 100, 10),
eachs = parseInt(100 / scriptArr.length),
max = eachs
jsProgress(circle, eachs, max, scriptArr);
// circle.testFn()
</script>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。