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轻松实现圆角效果
Nov 09 HTML / CSS
纯CSS实现的大小渐变、渐远效果
Apr 15 HTML / CSS
详解移动端HTML5音频与视频问题及解决方案
Aug 22 HTML / CSS
html5指南-7.geolocation结合google maps开发一个小的应用
Jan 07 HTML / CSS
用HTML5实现网站在windows8中贴靠的方法
Apr 21 HTML / CSS
使用纯HTML5编写一款网页上的时钟的代码分享
Nov 16 HTML / CSS
使用phonegap播放音频的实现方法
Mar 31 HTML / CSS
详解HTML5中的picture元素响应式处理图片
Jan 03 HTML / CSS
HTML5新特性之type=file文件上传功能
Feb 02 HTML / CSS
做一个能自适应高度的textarea的示例代码
Sep 06 HTML / CSS
HTML5 FileReader对象的具体使用方法
May 22 HTML / CSS
HTML5之高度塌陷问题的解决
Jun 01 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
curl实现站外采集的方法和技巧
2014/01/31 PHP
thinkPHP中验证码的简单使用方法
2015/12/26 PHP
php实现每日签到功能
2018/11/29 PHP
PHP框架实现WebSocket在线聊天通讯系统
2019/11/21 PHP
读jQuery之十四 (触发事件核心方法)
2011/08/23 Javascript
jquery键盘事件使用介绍
2011/11/01 Javascript
检测input每次的输入是否合法遇到汉字输入就有问题
2012/05/23 Javascript
javascript常用对话框小集
2013/09/13 Javascript
css样式标签和js语法属性区别
2013/11/06 Javascript
jquery判断元素是否隐藏的多种方法
2014/05/06 Javascript
学习使用bootstrap3栅格系统
2016/04/12 Javascript
全面解析Bootstrap中tab(选项卡)的使用方法
2016/06/06 Javascript
JS与jQuery实现隔行变色的方法
2016/09/09 Javascript
vue ajax 拦截原理与实现方法示例
2019/11/29 Javascript
如何将Node.js中的回调转换为Promise
2020/11/10 Javascript
python 表达式和语句及for、while循环练习实例
2017/07/07 Python
解决Django layui {{}}冲突的问题
2019/08/29 Python
pandas使用之宽表变窄表的实现
2020/04/12 Python
解决reload(sys)后print失效的问题
2020/04/25 Python
Python 实现二叉查找树的示例代码
2020/12/21 Python
HTML5之SVG 2D入门12—SVG DOM及DOM操作介绍
2013/01/30 HTML / CSS
Canvas绘制浮动球效果的示例
2017/12/29 HTML / CSS
夏威夷航空官网:Hawaiian Airlines
2016/09/11 全球购物
澳大利亚领先的在线美容商城:Adore Beauty
2017/04/14 全球购物
Dr. Martens马汀博士法国官网:马丁靴鼻祖
2020/01/15 全球购物
酒店前台接待岗位职责
2013/12/03 职场文书
2014年班主任自我评价范文
2014/04/23 职场文书
2014年教师业务学习材料
2014/05/12 职场文书
幼儿园运动会口号
2014/06/07 职场文书
小学生放飞梦想演讲稿
2014/08/26 职场文书
学生偷窃检讨书
2014/09/25 职场文书
中国汉字听写大会观后感
2015/06/02 职场文书
董事会决议范本
2015/07/01 职场文书
婚礼必备主持词范本!
2019/07/23 职场文书
Django使用echarts进行可视化展示的实践
2021/06/10 Python
星际争霸 Light vs Action 一场把教主看到鬼畜的比赛
2022/04/01 星际争霸