需求背景一般情况下,文本细化用于地图相关的需求。我在给公司的地图引擎实现一个功能的时候也实现了这个方法。这里是Simplified,只是在普通的Canvas上操作,不引入地图概念效果碰撞检测计算文本在canvas中占据的范围//计算文本需要的宽度varp={x:10,y:10,name:"TestText"};varmeasure=ctx.measureText(p.name);//找到画布画板中文本所占的最大y坐标varmaxX=measure.width+p.x;//找到textinthecanvasartboard//canvas中占据的最大y坐标只能计算文本的宽度,不能计算文本的高度。所以用文字的宽度除以文字的条数,算出一个近似值varmaxY=measure.width/p.name.length+p.y;varmin={x:p.x,y:p.y};varmax={x:maxX,y:maxY};//bounds是画布中文字所占的范围。//当以点坐标为最小范围时,按如下方式设置textAlign和textBaseline更准确。//如果设置为不同位置显示,还需要调整范围的最大最小点//ctx.textAlign="left";//ctx.textBaseline="top";varbounds=newBounds(最小值,最大值);Boundsrangeobject/***定义范围对象*/functionBounds(min,max){this.min=min;this.max=max;}/***判断范围是否与另一个范围相交*/Bounds。prototype.intersects=function(bounds){varmin=this.min,max=this.max,min2=bounds.min,max2=bounds.max,xIntersects=max2.x>=min.x&&min2.x<=max.x,yIntersects=max2.y>=min.y&&min2.y<=max.y;返回xIntersects&&yIntersects;};检测//每次绘制前,与绘制的文本进行范围交集检测//如果存在交集,则放弃绘制当前文本,否则绘制并存入绘制文本列表for(varindexin_textBounds){//循环遍历所有绘制的文本范围,检查是否与当前文本范围有交集,如果有交集指令会发生碰撞,然后跳过文本varpointBounds=_textBounds[index];如果(pointBounds.intersects(bounds)){返回;}}_textBounds.push(bounds);ctx.fillStyle="red";ctx.textAlign="left";ctx.textBaseline="top";ctx.fillText(p.name,p.x,p.y);示例,代码地址示例地址:例如可以查看完整代码:Github地址阅读原文
