Canvas 文字碰撞检测并抽稀的方法


Posted in HTML / CSS onMay 27, 2019

需求背景

一般在做地图相关的需求是才会用到文字抽稀,我也是在为公司的地图引擎实现一个功能时才实现了该方法,在这里将其简化了,就在普通的 Canvas 上进行操作,并没有引入地图概念

效果

Canvas 文字碰撞检测并抽稀的方法

碰撞检测

计算文字在 canvas 中所占据的范围

// 计算文字所需的宽度
var p = {
  x: 10,
  y: 10,
  name: "测试文字"
};
var measure = ctx.measureText(p.name);
// 求出文字在 canvas 画板中占据的最大 y 坐标
var maxX = measure.width + p.x;
// 求出文字在 canvas 画板中占据的最大 y 坐标
// canvas 只能计算文字的宽度,并不能计算出文字的高度。所以就利用文字的宽度除以文字个数计算个大概
var maxY = measure.width / p.name.length + p.y;

var min = { x: p.x, y: p.y };
var max = { x: maxX, y: maxY };
// bounds 为该文字在 canvas 中所占据的范围。
// 在取点位坐标作为最小范围时,textAlign、textBaseline 按照以下方式设置会比较准确。
// 如设置在不同的位置展示,范围最大、最小点也需进行调整
// ctx.textAlign = "left";
// ctx.textBaseline = "top";
var bounds = new Bounds(min, max);

Bounds 范围对象

/**
 * 定义范围对象
 */
function Bounds(min, max) {
  this.min = min;
  this.max = max;
}

/**
 * 判断范围是否与另外一个范围有交集
 */
Bounds.prototype.intersects = function(bounds) {
  var min = 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;

  return xIntersects && yIntersects;
};

检测

// 每次绘制之前先与已绘制的文字进行范围交叉检测
// 如发现有交叉,则放弃绘制当前文字,否则绘制并存入已绘制文字列表
for (var index in _textBounds) {
  // 循环所有已绘制的文字范围,检测是否和当前文字范围有交集,如果有交集说明会碰撞,则跳过该文字
  var pointBounds = _textBounds[index];
  if (pointBounds.intersects(bounds)) {
    return;
  }
}

_textBounds.push(bounds);
ctx.fillStyle = "red";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText(p.name, p.x, p.y);

示例、代码地址

示例地址:示例

具体可查看完整代码:Github 地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
CSS3制作翻转效果_动力节点Java学院整理
Jul 11 HTML / CSS
css3背景_动力节点Java学院整理
Jul 11 HTML / CSS
css sprite简单实例
May 23 HTML / CSS
详解Html5中video标签那些属性和方法
Jul 01 HTML / CSS
使用css创建三角形 使用CSS3创建3d四面体原理及代码(html5实践)
Jan 06 HTML / CSS
HTML中fieldset标签概述及使用方法
Feb 01 HTML / CSS
12个不为大家熟知的HTML5设计小技巧
Jun 02 HTML / CSS
canvas 阴影和图形变换的示例代码
Jan 02 HTML / CSS
AmazeUI在模态框中嵌入表单形成模态输入框
Aug 20 HTML / CSS
CSS3实现指纹特效代码
Mar 17 HTML / CSS
flex弹性布局详解
Mar 20 HTML / CSS
CSS使用SVG实现动态分布的圆环发散路径动画
Dec 24 HTML / CSS
利用canvas实现图片下载功能来实现浏览器兼容问题
May 31 #HTML / CSS
HTML5印章绘制电子签章图片(中文英文椭圆章、中文英文椭圆印章)
Jun 03 #HTML / CSS
详解利用canvas实现环形进度条的方法
Jun 12 #HTML / CSS
Html5 实现微信分享及自定义内容的流程
Aug 20 #HTML / CSS
前端canvas动画如何转成mp4视频的方法
Jun 17 #HTML / CSS
详解FireFox下Canvas使用图像合成绘制SVG的Bug
Jul 10 #HTML / CSS
canvas实现有递增动画的环形进度条的实现方法
Jul 10 #HTML / CSS
You might like
php按百分比生成缩略图的代码分享
2014/05/10 PHP
php实现对象克隆的方法
2015/06/20 PHP
PHP实现链式操作的核心思想
2015/06/23 PHP
PHP Echo字符串的连接格式
2016/03/07 PHP
关于使用 jBox 对话框的提交不能弹出问题解决方法
2012/11/07 Javascript
JS中setInterval、setTimeout不能传递带参数的函数的解决方案
2013/04/28 Javascript
javascript放大镜效果的简单实现
2013/12/09 Javascript
JQuery实现鼠标移动到图片上显示边框效果
2014/01/09 Javascript
jQuery应用之jQuery链用法实例
2015/01/19 Javascript
JavaScript中实现单体模式分享
2015/01/29 Javascript
js实现Select列表各项上移和下移的方法
2015/08/14 Javascript
JS+CSS实现DIV层的展开、收缩效果
2016/01/28 Javascript
Bootstrap导航条的使用和理解3
2016/12/14 Javascript
Vue中的字符串模板的使用
2018/05/17 Javascript
d3.js实现自定义多y轴折线图的示例代码
2018/05/30 Javascript
vue js秒转天数小时分钟秒的实例代码
2018/08/08 Javascript
JS实现的冒泡排序,快速排序,插入排序算法示例
2019/03/02 Javascript
vue中使用props传值的方法
2019/05/08 Javascript
从零撸一个pc端vue的ui组件库( 计数器组件 )
2019/08/08 Javascript
layui使用button按钮 点击出现弹层 弹层中加载表单的实例
2019/09/04 Javascript
jquery将信息遍历到界面上实例代码
2020/01/21 jQuery
如何用python整理附件
2018/05/13 Python
利用Python如何制作好玩的GIF动图详解
2018/07/11 Python
对python requests的content和text方法的区别详解
2018/10/11 Python
django Admin文档生成器使用详解
2019/07/22 Python
pytorch torch.nn.AdaptiveAvgPool2d()自适应平均池化函数详解
2020/01/03 Python
Python基于traceback模块获取异常信息
2020/07/23 Python
Python使用tkinter制作在线翻译软件
2021/02/22 Python
html5使用canvas绘制一张图片
2014/12/15 HTML / CSS
公务员平时考核实施方案
2014/03/11 职场文书
2014年党支部承诺书
2014/05/30 职场文书
群众路线剖析材料(四风)
2014/11/05 职场文书
2015年幼儿园安全工作总结
2015/05/12 职场文书
围城读书笔记
2015/06/26 职场文书
Python 流媒体播放器的实现(基于VLC)
2021/04/28 Python
Vue实现下拉加载更多
2021/05/09 Vue.js