项目实践|青训营笔记

56 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第5天

我们的项目是做一个静态网页的画板。上次说了几个问题和解决方法之后,仍然有一些问题还没有解决 ,下面让我一一道来

首先是撤回功能的问题,我们最开始的想法都是使用一个栈来保存图片数据,然后在每一次点击的时候就回到栈顶的图片,方案是很好的,但是执行却有各种问题,一个是栈中的元素要用const来保存的问题,如果不用const来保存,会报错显示type不是image,导致整个程序不能运行,还有一个是框架涉及的问题,我在设置监听器的时候,mouseup设置的是全局的,这就导致了我在canvas外面也会调用相关的函数,同时也会加入image到栈顶上,这里的问题就比较严重而且不容易复现,因为我们在canva外部每一次的点击,都会保存一个当前的图片,可是我们并没有对canvas中的内容进行操作,也就是说,栈中会保存很多个相同的图片信息。单从撤回的逻辑来看就会显得特别奇怪,我们点击撤回按键之后,撤回到上一个图片,同时又保存一个当前图片 ,继续撤回就会出现要按很多次撤回按钮才能撤回的情况,解决的方法也比较简单,就是添加一个判断函数,判断当前鼠标的pos是否在canvas中,如果是才保存当前的信息,否则就只执行其他点击相关的函数。

其次就是后来要补充的图片填充功能,这里的问题就更多了,一个困扰了我很久的问题就是二维数组的创建,听起来很奇怪对吧,二维数组不是直接new Array().fill(new Array().fill(0));就可以了嘛,怎么不困扰呢,这看起来很对,但是在实际使用的时候,我们每一次对数组某一个元素赋值,都会对那一列的所有元素赋值,具体原因就是使用这种方法创建的二维数组中间保存的都是同一个对象,每一次操作都是对同一个对象操作,所以这种创建方法就不可取,那什么方法可取呢

image.png

我们对于图片填充的算法是通过bfs算法来探测的,有线条经过的区域就是边界,这样又有一个边界判定的问题在里面,我们是设置一个和canvas相同大小的二数组组来判定的,那么赋值算法自然就是重中之重,其中也有几个困难,第一个就是,我们在使用画笔的时候,是使用贝塞尔曲线来近似点集合的,所以会出现不匹配的情况,我们的解决方案是手写一个贝塞尔曲线的算法,然后算出经过的点再加入到集合中。

image.png