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实现简易版的刮刮乐效果
Sep 27 HTML / CSS
CSS3 开发工具收集
Apr 17 HTML / CSS
CSS3 :nth-child()伪类选择器实现奇偶行显示不同样式
Nov 05 HTML / CSS
多重CSS背景动画实现方法示例
Apr 04 HTML / CSS
CSS3+JavaScript实现炫酷呼吸效果的示例代码
Jun 15 HTML / CSS
利用html5 file api读取本地文件示例(如图片、PDF等)
Mar 07 HTML / CSS
HTML5的hidden属性兼容老浏览器的方法
Apr 23 HTML / CSS
HTML5利用约束验证API来检查表单的输入数据的代码实例
Dec 20 HTML / CSS
canvas实现圆形进度条动画的示例代码
Dec 26 HTML / CSS
three.js模拟实现太阳系行星体系功能
Sep 03 HTML / CSS
HTML5表单验证特性(知识点小结)
Mar 10 HTML / CSS
AmazeUI 图标的示例代码
Aug 13 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
百事可乐也出咖啡了 双倍咖啡因双倍快乐
2021/03/03 咖啡文化
如何使用PHP批量去除文件UTF8 BOM信息
2013/08/05 PHP
php中rename函数用法分析
2014/11/15 PHP
PHP整合七牛实现上传文件
2015/07/03 PHP
PHP文件操作之获取目录下文件与计算相对路径的方法
2016/01/08 PHP
PHP+iframe图片上传实现即时刷新效果
2016/11/18 PHP
PHP+MYSQL实现读写分离简单实战
2017/03/13 PHP
Javascript 类与静态类的实现
2010/04/01 Javascript
jQuery中element选择器用法实例
2014/12/29 Javascript
Angular.JS中指令ng-if、ng-show/ng-hide和ng-switch的使用教程
2017/05/07 Javascript
前端把html表格生成为excel表格的实例
2017/09/19 Javascript
基于js中this和event 的区别(详解)
2017/10/24 Javascript
Vue SPA 初次进入加载动画实现代码
2019/11/14 Javascript
在Linux系统上通过uWSGI配置Nginx+Python环境的教程
2015/12/25 Python
教你用Type Hint提高Python程序开发效率
2016/08/08 Python
使用requests库制作Python爬虫
2018/03/25 Python
python 读取txt中每行数据,并且保存到excel中的实例
2018/04/29 Python
django的ORM模型的实现原理
2019/03/04 Python
对python中的装包与解包实例详解
2019/08/24 Python
Django 实现Admin自动填充当前用户的示例代码
2019/11/18 Python
PyTorch学习:动态图和静态图的例子
2020/01/06 Python
如何利用python 读取配置文件
2021/01/06 Python
Fairyseason:为个人和批发商提供女装和配件
2017/03/01 全球购物
马来西亚网上购物:Youbeli
2018/03/30 全球购物
最好的商品表达自己:Cafepress
2019/09/04 全球购物
eharmony澳大利亚:网上约会服务
2020/02/29 全球购物
全球最大化妆品零售网站:SkinStore
2020/10/24 全球购物
房地产出纳岗位职责
2013/12/01 职场文书
自我评价如何写好?
2014/01/05 职场文书
销售顾问工作计划书
2014/09/15 职场文书
领导班子整改措施
2014/10/24 职场文书
承诺函格式模板
2015/01/21 职场文书
留学推荐信中文范文
2015/03/26 职场文书
爱心捐赠活动简讯
2015/07/20 职场文书
关于Python OS模块常用文件/目录函数详解
2021/07/01 Python
Vue3实现简易音乐播放器组件
2022/08/14 Vue.js