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 按钮 利用css3实现超酷下载按钮
Mar 18 HTML / CSS
Css3实现无缝滚动防抖
Sep 14 HTML / CSS
HTML5 canvas 基本语法
Aug 26 HTML / CSS
html5-websocket基于远程方法调用的数据交互实现
Dec 04 HTML / CSS
html5中canvas学习笔记2-判断浏览器是否支持canvas
Jan 06 HTML / CSS
html5弹跳球示例代码
Jul 23 HTML / CSS
HTML5 placeholder(空白提示)属性介绍
Aug 07 HTML / CSS
HTML5 创建canvas元素示例代码
Jun 04 HTML / CSS
HTML块级标签汇总(小篇)
Jul 13 HTML / CSS
Html5原生拖拽相关事件简介以及基础实现
Nov 19 HTML / CSS
CSS3 制作的书本翻页特效
Apr 13 HTML / CSS
css display table 自适应高度、宽度问题的解决
May 07 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管理依赖(dependency)关系工具 Composer的自动加载(autoload)
2014/08/18 PHP
php外部执行命令函数用法小结
2016/10/11 PHP
PHP新特性详解之命名空间、性状与生成器
2017/07/18 PHP
PHP利用pdo_odbc实现连接数据库示例【基于ThinkPHP5.1搭建的项目】
2019/05/13 PHP
jquery load事件(callback/data)使用方法及注意事项
2013/02/06 Javascript
jquery中获得元素尺寸和坐标的方法整理
2014/05/18 Javascript
深入探讨JavaScript、JQuery屏蔽网页鼠标右键菜单及禁止选择复制
2014/06/10 Javascript
JQuery显示、隐藏div的几种方法简明总结
2015/04/16 Javascript
jQuery构造函数init参数分析续
2015/05/13 Javascript
JQuery球队选择实例
2015/05/18 Javascript
javascript 动态修改css样式方法汇总(四种方法)
2015/08/27 Javascript
微信小程序  生命周期详解
2016/10/27 Javascript
react-native 封装选择弹出框示例(试用ios&amp;android)
2017/07/11 Javascript
vue.js异步上传文件前后端实现代码
2017/08/22 Javascript
vue路由懒加载的实现方法
2018/03/12 Javascript
10分钟上手vue-cli 3.0 入门介绍
2018/04/04 Javascript
mint-ui在vue中的使用示例
2018/04/05 Javascript
React组件内事件传参实现tab切换的示例代码
2018/07/04 Javascript
layui获取选中行数据的实例讲解
2018/08/19 Javascript
vue绑定事件后获取绑定事件中的this方法
2018/09/15 Javascript
基于VUE的v-charts的曲线显示功能
2019/10/01 Javascript
基于JavaScript或jQuery实现网站夜间/高亮模式
2020/05/30 jQuery
vue+elementUI动态增加表单项并添加验证的代码详解
2020/12/17 Vue.js
python类型强制转换long to int的代码
2013/02/10 Python
python编写朴素贝叶斯用于文本分类
2017/12/21 Python
python如何实现一个刷网页小程序
2018/11/27 Python
基于pygame实现童年掌机打砖块游戏
2020/02/25 Python
Canal官网:巴西女性时尚品牌
2019/10/16 全球购物
美国最大的在线生存商店:Survival Frog
2020/12/13 全球购物
如何整合JQuery和Prototype
2014/01/31 面试题
会计专业毕业生推荐信
2013/11/05 职场文书
马云北大演讲完整版:真心话,什么才是阿里的核心竞争力?
2014/04/04 职场文书
幼儿园区域活动总结
2014/05/08 职场文书
落实八项规定专题民主生活会对照检查材料
2014/09/15 职场文书
靠谱准确的求职信
2019/04/02 职场文书
教你怎么用python爬取爱奇艺热门电影
2021/05/20 Python