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地图动态实例代码(圆圈向外扩散)
Jun 15 HTML / CSS
css3 响应式媒体查询的示例代码
Sep 25 HTML / CSS
IE滤镜与CSS3效果(详细整理分享)
Jan 25 HTML / CSS
css 省略号 css3让多余的字符串消失并附加省略号的实现代码
Feb 07 HTML / CSS
使用JS+CSS3技术:让你的名字动起来
Apr 27 HTML / CSS
css3进行截取替代js的substring
Sep 02 HTML / CSS
CSS3动画效果回调处理详解
Dec 10 HTML / CSS
HTML5 Canvas像素处理使用接口介绍
Dec 02 HTML / CSS
使用html5+css3来实现slider切换效果告别javascript+css
Jan 08 HTML / CSS
HTML5 Canvas draw方法制作动画效果示例
Jul 11 HTML / CSS
HTML5 transform三维立方体实现360无死角三维旋转效果
Aug 22 HTML / CSS
HTML5实现移动端复制功能
Apr 19 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面向对象的方法重载两种版本比较
2008/09/08 PHP
php将fileterms函数返回的结果变成可读的形式
2011/04/21 PHP
具有时效性的php加密解密函数代码
2013/06/19 PHP
php通过PHPExcel导入Excel表格到MySQL数据库的简单实例
2016/10/29 PHP
ext for eclipse插件安装方法
2008/04/27 Javascript
JQuery与JSon实现的无刷新分页代码
2011/09/13 Javascript
重构Javascript代码示例(重构前后对比)
2013/01/23 Javascript
JQuery创建DOM节点的方法
2015/06/11 Javascript
js检测用户输入密码强度
2015/10/22 Javascript
angular2 ng build部署后base文件路径问题详细解答
2017/07/15 Javascript
Angular Excel 导入与导出的实现代码
2019/04/17 Javascript
解决包含在label标签下的checkbox在ie8及以下版本点击事件无效果兼容的问题
2019/10/27 Javascript
使用node.JS中的url模块解析URL信息
2020/02/06 Javascript
vue 使用v-for进行循环的实例代码详解
2020/02/19 Javascript
Python语言编写电脑时间自动同步小工具
2013/03/08 Python
python实现在windows服务中新建进程的方法
2015/06/30 Python
python snownlp情感分析简易demo(分享)
2017/06/04 Python
Python实现的十进制小数与二进制小数相互转换功能
2017/10/12 Python
python实现决策树
2017/12/21 Python
python实现手机通讯录搜索功能
2018/02/22 Python
Python格式化字符串f-string概览(小结)
2019/06/18 Python
Python 实用技巧之利用Shell通配符做字符串匹配
2019/08/23 Python
手动安装python3.6的操作过程详解
2020/01/13 Python
利用PyQt中的QThread类实现多线程
2020/02/18 Python
Python使用for生成列表实现过程解析
2020/09/22 Python
CSS3 rgb and rgba(透明色)的使用详解
2020/09/25 HTML / CSS
贝尔帐篷精品店:Bell Tent Boutique
2019/06/12 全球购物
struct和class的区别
2015/11/20 面试题
人力资源管理专业毕业生自我评价
2013/09/21 职场文书
给酒店员工的表扬信
2014/01/11 职场文书
运动会宣传口号
2014/06/09 职场文书
美术兴趣小组活动总结
2014/07/07 职场文书
2014年妇产科工作总结
2014/12/08 职场文书
培训通知书模板
2015/04/17 职场文书
公司行政管理制度范本
2015/08/05 职场文书
银行柜员工作心得体会
2016/01/23 职场文书