前言
大家好,我是南木元元,热衷分享有趣实用的文章。最近在做项目使用canvas绘图的时候遇到了一个问题,这里就分享出来并说一说自己的解决思路。
问题场景
项目中需要用canvas绘制多个要素,并且这几个要素要同时叠加在同一个canvas上,但这时出现了不是按照代码的顺序显示,即先绘制的显示在下面,后绘制的显示在上面。现在想要在canvas同一个区域同时叠加绘制如下四个要素:
- 矩形网格(600 × 600)
- 红色图形(400 × 400)
- 绿色图形(200 × 200)
- 蓝色线条
按照上面的顺序依次进行绘制,但是,却出现了下面的效果。
上图中,是先绘制了矩形网格,然后绘制蓝色线条和绿色图形,最后绘制的红色图形,所以出现了绿色图形和蓝色线条被后绘制的红色部分遮挡的问题。
问题分析和解决思路
既然出现了上述问题,那必然是先执行了绘制蓝色线条和绿色图形的函数,最后再执行绘制红色图形的函数,导致的遮挡。
- 那为什么会出现这样的问题呢?
仔细思考了下,由于每个要素我都是采取异步绘制的方式,但由于图片大小不同导致绘制或加载的时间不一样,那么就会导致先加载完的先画,后加载完的后画,就不是按照自己想要的顺序进行绘制了,于是就产生了遮挡问题。既然找出了问题,那么,如何解决这个问题,使得要素之间不发生遮挡,按照自己想要的顺序进行绘制呢?
- 控制函数的执行顺序
通过函数数组的方式。定义一个数组,用来保存所有绘制元素的方法函数,这样就可以通过数组方法来操作这些函数,然后对函数按照我们自己想要的顺序进行排序,先执行的放前面,后执行的放后面,最后再遍历数组依次执行其中的每个绘制方法即可。
解决代码
接下来就开始动手实现一下上面的思路。
- 自定义绘制顺序。
const DrawIndex = {
red: 1,
green: 2,
mesh: 3,
line: 4,
};
红色图形对应1,代表最先绘制,蓝色线条对应4,代表最后绘制。
- 定义drawList数组,保存所有需要绘制的函数。
const drawList = [];
- 分别添加需要绘制的函数、相应参数列表以及需要绘制的顺序到数组中。
//1.添加绘制网格函数
drawList.push({
func: this.drawMesh, //绘制网格函数
value: [width, height], //绘制需要的参数列表
index: DrawIndex.mesh, //绘制顺序
});
//2.添加绘制红色部分函数
drawList.push({
func: this.drawRed,
value: [width, height, color],
index: DrawIndex.red, //绘制顺序
});
//3.添加绘制绿色部分函数
drawList.push({
func: this.drawGreen,
value: [width, height, color],
index: DrawIndex.green, //绘制顺序
});
//4.添加绘制蓝色线条函数
drawList.push({
func: this.drawLine,
value: [lineWidth, lineColor],
index: DrawIndex.line, //绘制顺序
});
- 对数组进行按照自定义的顺序进行排序。
drawList.sort((a, b) => a.index - b.index);
- 遍历函数数组并依次执行其中的函数。
drawList.forEach((draw) => {
draw.func.apply(this, draw.value);
});
这样就可以按照我们自定义的顺序来进行绘制了,解决了上述出现的遮挡问题。修改后的效果:
结语
🔥如果此文对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论,支持一下博主~