当前位置: 首页 > Web前端 > HTML5

我记得一个项目经历,距离上次写一篇用纯CSS实现大量小块绘图

时间:2023-04-05 23:41:38 HTML5

的文章已经过去很久了。这段时间,我一直很忙,因为我随着项目换了团队。当前项目是公司各组使用的查看器库。Viewer需要很多功能,其中之一就是提供一些常用的绘图API功能,比如当用户移动鼠标时绘制箭头,绘制圆圈,高亮选中的文本等。挑战目前的挑战是如何在canvas,SVG、DOM+CSS。canvas绘图方案已经完成,我们可以直接拿来添加到已有的Viewer中。但是,基于以下考虑,还不能得出主要使用哪种技术的结论。Canvas纠结点:1)各个部门之间的合作。如果使用canvas,其他部门在需要添加自定义图形操作时,需要了解Canvas开发。在现有的查看器画布上重绘。2)Canvas会丢失很多Element的原生属性,比如文本选择,aria标签,事件等。3)Viewer的文件可能非常大,可能有几千页,每一页管理自己的绘图。如果每页一个Canvas,性能会很差(采用了ViewVirtualization的思想,只渲染view需要的元素,这里是一个极限假设)。如果所有的图形都绘制在一个Canvas上,图形计算需要根据视图区域的页面属性重新绘制,开发成本会增加很多。4)Canvas只能在最底层使用,否则会覆盖其他元素(Viewer上面有很多层,绘图层需要能够管理事件而不丢失其他层的事件)。于是老大给了几天时间,让我们尝试用其他方式绘制各种图形,对比一下优劣(最后应该结合几种技术)。其中一种情况是高亮选中的文字,后端会发一堆高亮块大小和位置,前端绘制高亮部分。Canvas最适合这种有很多小区域的绘图,不过这几天就是想看看有没有其他的解决办法。大概长这个样子,亮点是无数小块。寻找解决方案Canvas有绘制高光的解决方案。我们首先想到的是将每个块渲染成一个span,但是因为可能有很多块需要高亮,而且它们可能是动态的。所以这涉及到DOM的频繁操作,性能很差。后来使用createDocumentFragment将其添加到DOM中,性能得到明显提升。当时我有一个很大胆的想法,如果只用一个span,然后把所有的块都加为背景,是否可以实现(考虑到css3已经有了多重背景重叠技术)。在寻找方法的时候,千百次觉得不可能。结果实现后,我再回去看看。其实原理很简单。全部使用css,使用linear-gradient绘制块(使用linear-gradient是因为可以重叠背景,如果有更好的方法,欢迎指教),background-position,background-size分别定位每个块,结束!性能当然是出奇的好,因为根本没有添加或删除元素,只是CSS重绘(Viewer有很多耗性能的滚动监听,操作可以无缝操作,Canvas有非常小的flash).这个试用好像是一个新天地,很多大的、简单的图形绘制都可以尝试纯css、代码实现。Angular模板Angularts文件this._subscription=this.highlights$.subscribe((highlights)=>{letbackground=``;letbackgroundSize=``;letbackgroundPosition=``;for(leti=0;i