0%

选点展示问题的分析与总结

工作中难免会遇到一些问题,当遭遇问题时,该如何分析并得到解决方案,是对程序员应对问题的能力和对知识的掌握程度的一次考验。我在工作时也遇到了问题,因此我把它记录下来,也算是成长的履历。

概述

本人所在公司业务为手机自动化测试平台,针对用例开发研发了一款用例编辑可视化工具。
用例编辑过程中有一个点击屏幕位置的功能。界面的交互是用户选择上传一张手机屏幕截图,或是点击界面上的截图按钮,后对手机截图展示在界面上。用户点击图片区域,点击位置的坐标便会保存在用例的逻辑流中,执行用例时,运行到这个step便会准确的点击设定的位置。
但是在查看用例的时候,只有一个区域坐标很难回溯当时的编辑内容。因此需要增加一个新功能:当点击item时,获取图片展示在页面上并获取坐标点展示在图片上。
实现上,定义一个组件,在props中定义两个参数imgSrc,selectPoint,并使用watch监听。imgSrc变化时将新图片替换原有图片,selectPoint变化时将之前在图片中标注的区域清除然后展示新的选点。但实际情况是图片展示但选点非被标记

问题分析

selectPoint的监听函数先执行?

watch函数监听的多个字段发生改变时,会从上到下依次执行。通过查看代码确认执行顺序没有问题。

1
2
3
4
5
6
7
8
watch: {
imgSrc (val) {
...
},
selectPointShow (val) {
...
}
}
图片加载过程是否异步进行?

图片加载属于耗时操作,js单线程执行肯定不能容忍。通过 review 确定了图片异步加载完成后会调用 onload 方法。onload指定了一个回调函数,声明canvas将图片绘制在画布上,选点操作是使用canvas将绘制选点区域在画布上。
如果选点和图片是一对一存在的,移除对selectPoint的监听,直接将选点展示写到onload逻辑中即可,但原本的需求可以允许对一张图片进行多个选点。因此selectPoint仍需存在。

问题确认

通过分析得知图片加载过程为异步加载,并不能确保selectPoint选点展示之前,图片已经加载完成并绘制完毕。

解决方案

图片展示和选点展示的交互分离

将图片展示和选点展示的交互分离,用户必须先选择图片,然后再选择之前点击的坐标在图片上进行展示。

缺点:增加了用户操作的复杂度,并且和之前实现逻辑不一致,改动较大。

selectPoint延时加载

通过使用 setTimeout 将 selectPoint 选点展示的逻辑包裹延时加载,保证展示的区域可以呈现。

缺点:延时加载的时间不能确定。

回调通知图片加载完毕

data中 定义 变量 picLoading = false,选点加载时,使用 setInterval 定时查看 picLoading === true。
图片异步加载完毕调用 onload 方法进行图片的绘制,调用 CanvasDrawImage.drawImage 方法。通过对 CanvasDrawImage.drawImage 设置回调函数,绘制完成后修改 picLoading = true 选点展示并销毁 setInterval。

功能示意图:
demo