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 23 HTML / CSS
CSS3田字格列表的样式编写方法
Nov 22 HTML / CSS
纯CSS3实现鼠标滑过按钮动画第二节
Jul 16 HTML / CSS
CSS3只让背景图片旋转180度的实现示例
Mar 09 HTML / CSS
HTML5 canvas实现雪花飘落特效
Mar 08 HTML / CSS
canvas绘制文本内容自动换行的实现代码
Jan 14 HTML / CSS
html5定位并在百度地图上显示的示例
Apr 27 HTML / CSS
HTML5 Canvas中使用用路径描画圆弧
Jan 01 HTML / CSS
简单介绍HTML5中的文件导入
May 08 HTML / CSS
HTML5学习笔记之html5与传统html区别
Jan 06 HTML / CSS
HTML5中的进度条progress元素简介及兼容性处理
Jun 02 HTML / CSS
HTML5 Blob对象的具体使用
May 22 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
Ubuntu12下编译安装PHP5.3开发环境
2015/03/27 PHP
详解PHP PDO简单教程
2019/05/28 PHP
php菜单/评论数据递归分级算法的实现方法
2019/08/01 PHP
Prototype String对象 学习
2009/07/19 Javascript
javascript使用activex控件的代码
2011/01/27 Javascript
Javascript实现简单的富文本编辑器附演示
2014/06/16 Javascript
Javascript检查图片大小不要让大图片撑破页面
2014/11/04 Javascript
jQuery中:gt选择器用法实例
2014/12/29 Javascript
Bootstrap+jfinal退出系统弹出确认框的实现方法
2016/05/30 Javascript
js获取时间函数及扩展函数的方法
2016/10/30 Javascript
WebView启动支付宝客户端支付失败的问题小结
2017/01/11 Javascript
vue通过路由实现页面刷新的方法
2018/01/25 Javascript
vue2中使用less简易教程
2018/03/27 Javascript
NodeJS 中Stream 的基本使用
2018/07/30 NodeJs
jQuery实现购物车的总价计算和总价传值功能
2018/11/28 jQuery
jQuery-Citys省市区三级菜单联动插件使用详解
2019/07/26 jQuery
JavaScript实现图片上传并预览并提交ajax
2019/09/30 Javascript
nodejs实现的http、https 请求封装操作示例
2020/02/06 NodeJs
给Python中的MySQLdb模块添加超时功能的教程
2015/05/05 Python
Python WSGI的深入理解
2018/08/01 Python
利用Python小工具实现3秒钟将视频转换为音频
2019/10/29 Python
PyCharm 2020 激活到 2100 年的教程
2020/03/25 Python
python中字典增加和删除使用方法
2020/09/30 Python
HTML5在线预览PDF的示例代码
2017/09/14 HTML / CSS
马来西亚航空官方网站:Malaysia Airlines
2017/07/28 全球购物
美国在线家居装饰店:Belle&June
2018/10/24 全球购物
乌克兰排名第一的在线旅游超市:Farvater.Travel
2020/01/02 全球购物
android面试问题与答案
2016/12/27 面试题
万年牢教学反思
2014/02/15 职场文书
教师求职自荐信
2014/03/09 职场文书
服务承诺书
2015/01/19 职场文书
2015年学生资助工作总结
2015/05/25 职场文书
小学生安全教育心得体会
2016/01/15 职场文书
Nginx反爬虫策略,防止UA抓取网站
2021/03/31 Servers
sqlserver2017共享功能目录路径不可改的解决方法
2021/04/16 SQL Server
Spark SQL 2.4.8 操作 Dataframe的两种方式
2021/10/16 SQL Server