时隔多日,我重振旗鼓再次出现在掘金啦!!!🎉🎉🎉
首先还是要感谢大家对之前文章的点赞以及阅读,在过去的一年里,由于自己的认知偏差,内心总认为一些满处都存在的知识没有必要再次总结,只要虚心学习到就可以了,但是新的一年有了新的见解,掘金不仅是可以共享自己所学的平台,其实也完全可以作为自己积累的学习工具。
所以,在年我会继续努力,尽可能输出自己所思,并不断学习总结各种知识、工作所悟等等
言归正传,今天带来了一篇具有可实施性但目前并未真实使用的技术专利,此专利已经通过公司审核、代理人撰写阶段,目前已提审国家专利局,处于审核阶段。
前言
在页面开发过程中,我们通常会根据设计稿中元素的大小、字体、颜色等一些列已经由UI设计师设计出来的标准进行开发,但是对于font-family属性,如果要呈现出UI设计师所需要的字体,那么我们就需要下载特殊字体并进行引用,否则不管有无此属性,都会发现字体样式是不会发生变化的。
针对特殊字体的实现目前已有解决方案,但是综合现有的技术,我总结了一些现有技术的缺点,并结合Node、Canvas技术提出了一种新型的决绝方案。
专利实现方案
1.现有技术
现有的实现网页中引入特殊字体的方式可以采用以下几种:
(1)UI设计图:目前在前端Web页面中使用特殊字体的需求,一般是设计师将特殊字体转换成位图进行导出,然后将图片文件提供给前端开发人员,前端开发人员用指定前端语言标签嵌入到页面中;
(2)特殊字体:在前端Web页面中直接使用特殊字体,需要通过CSS层叠样式指定特殊字体的网络路径去进行加载,加载成功后方可进行文本的渲染展示。
2. 现有技术的缺点
现有的实现网页中引入特殊字体的方式具有以下缺点:
(1)由设计师通过制图软件生成的图片会造成发布Web应用时产生过多的静态资源文件,不仅会造成应用包体积过大,更会造成用户在访问页面时需要过多的网络流量去加载这些资源文件,会造成网络请求频繁,服务器资源占用过多的情况。如果一个应用中多处采用特殊字体,又恰巧此应用为微信小程序,则会受到文件大小的限制,除此之外,图片加载可能会受网络等因素造成一定的延迟,进而降低用户体验;
(2)使用CSS层叠样式中的属性@font-face①加载外部字体时,英文字体包会比较小,但中文字体包会相对较大,因此当用户打开网页时,因为需要较长的时间来下载字体,导致用户体验不好,除此之外,对于CSS层叠样式中的属性@font-face①而言,会存在各浏览器所能识别字体的兼容性问题。
(3)特殊文本的展示很可能是动态内容,也就是Web端页面并不会预先知道要展示的文字内容,因为这些内容可能是通过网络接口获取的,这样一来,就无法只针对固定的文字内容进行切图或者只加载某一个文本范围的字体文件,因此很难做到对静态资源的有效控制。
3.本发明技术方案
3.1 本发明所要解决的技术问题(即发明目的)
本发明主要解决Web前端页面需要展示特定字体的文本内容时,现有的技术手段会造成静态资源过多,引用特殊字体文件又会造成页面加载慢等诸多缺点。此发明利用NodeJS服务端技术在处理高并发请求时的良好性能特点以及NodeJS具有对图形处理的天然优势,通过搭建NodeJS服务(比如Egg.js或Express.js等框架)结合node-canvas②来对文本进行动态渲染,并通过二分查找的算法实现对文字换行、标点符号不出现首行以及英文单词不拆分等细节问题,再使用canvas对象上的toDataURL()方法输出图片的base64格式,最终通过对NodeJS服务实现的接口进行包装,对用户暴露一个只需要传递特定参数的方法。
此技术方案将特殊字体文件放在服务器端,一定程度上降低了前端加载这些文件的性能消耗,同时最终返回的为图片的base64格式,也避免了静态资源文件过多或应用包体积过大而造成的问题。
3.2 本发明的完整技术方案
3.2.1 系统原理图、结构说明图或流程图
3.2.2 技术方案详细描述
本技术方案是给Web前端应用提供一个基于NodeJS服务的通用型网络接口,实现简单且方便的展示特殊字体的效果,并在一定程度上能尽量降低服务端以及客户端的性能消耗,使用户体验更佳。该特殊字体实现的主要细节如下:
(1)使用NodeJS技术开启一个服务,并定义一个可接收text(文本内容)、fontSize(字体大小)、color(字体颜色)、x(文本起始x坐标)、y(文本起始y坐标)、width(图片宽度)、height(图片高度)、lineHeight(文本行高)、fontFamily(字体格式)参数的post接口,最终返回一个图片的base64;
(2)在服务端安装下载所有字体文件,方便之后实现过程中加载特殊字体,以达到方案的最终目的;
(3)安装node-canvas②插件,通过其内部方法createCanvas创建一个canvas画布,canvas画布即为一种用Web前端实现图形和文本绘制的底层显示对象,本方案用到的node-canvas②插件可以实现在服务端动态创建这种绘制对象,画布宽高由传入的width、height两个参数决定,之后通过getContext创建一个context对象,context对象即为通过canvas获取的绘图上下文对象;
(4)使用canvas提供的fillText( lineHeight , x , y )方法向canvas画布中写入文本,并通过参数决定文本的行高、起始位置、字体颜色以及字体大小;
(5)自定义字体需要使用canvas.registerFont(‘字体文件’,{family:‘字体名称’})方法进行引入并命名,registerFont是canvas画布提供的方法,是用来注册服务端指定的特殊字体,并用于后续的文本绘制阶段,之后使用context.fontFamily= ‘fontSize(字体大小) “字体名称”’设定字体的大小以及特殊格式,fontFamily是绘图上下文对象context的属性,通过其属性可以设置已经注册的特殊字体,同时可以精确控制字号,用于文本内容的绘制。
(6)使用二分查找算法对文字进行折行,算法实现思想为:如果某一个位置之前的文字宽度小于等于设定的宽度,并且它之后一个字之前的文字宽度大于设定的宽度,此位置点即折行点,之后对整个文本进行循环查找,直到不存在这样的换行点为止。测量文本宽度可以借助canvas提供的measureText方法,文本换行后的新位置x即为传入的x初始值,y值为传入的y值+传入的lineHeight值;
(7)处理标点字符不出现首行,可以采用正则表达式匹配折行位置点的后一个字(1)符是否为标点符号,若是,则将折行位置点向前移动一个字符,并进行换行,若不是,则进行正常的折行操作;
(8)处理英文单词不拆分,可以采用正则表达式在折行点位置向前匹配是否为空格,若不是,则向前一直匹配直到匹配到空格并记录向前匹配的字符数n,之后将折行点位置向前移动n个位置,并进行换行,若是,则进行正常的换行操作;
(9)使用canvas.toDataURL()方法将形成的文本画布输出为base64格式的图片文件,并作为结果返回至客户端,客户端直接使用image标签元素加载即可;
(10)将此接口封装为一个对外方法,如:specialFont( text, fontSize, color, x, y, width, height, lineHeight, fontFamily),specialFont为本技术发明自定义的方法名称,同时此方法接收前端开发人员传入的必要参数,即文本内容、字体大小、字体颜色、字体起始x轴位置、字体起始y轴位置、画布的宽度、画布的高度、文本的行高、文本的特殊字体格式,客户端在想使用此技术方案实现特殊字体时即可直接调用此方法,为了兼容没有传入参数的问题,默认fontSize:16px,color:#ffffff,x:0,y:0,with和height为canvas默认宽高即300*150,lineHeight和fontFamily为canvas默认行高以及字体;
(11)最终将本方案的技术手段发布为一个通用型网络接口,部署在生产环境的底层接口服务上,方便任何Web前端应用随时调用,真正实现了按需调用,保证了网络资源的合理利用。
3.3 本发明希望保护的技术创新点
(1)基于NodeJS技术结合服务端画布canvas对于特殊字体文本的绘制便捷性实现Web端的动态文本渲染技术,降低了客户端本地存储字体文件导致的性能消耗,同时返回base64格式图片;
(2)使用二分查找算法处理文本换行、标点符号不出现首行以及英文单词不拆分等问题。
3.5 交底书中技术术语的名词解释
① @font-face允许网页开发者为其网页指定在线字体。通过这种自备字体的方式,@font-face 可以消除对用户电脑字体的依赖。 @font-face 不仅可以放在在CSS的最顶层, 也可以放在 @规则的条件规则组中。
② node-canvas即为一种在服务端可以使用canvas前端绘图技术的插件。
个人总结
日常工作中接触的东西可能会很多,但是由于时间限制又没有机会深入学习,但是即使有些了解,那么也可以结合工作中遇到的难点痛点,发散个人思维来进行“天马行空”的猜想,随着技术不断的发展,万一哪天实现了呢?梦想也即如此。