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实现照片墙效果
Dec 26 HTML / CSS
详解css position 5种不同的值的用法
Jul 30 HTML / CSS
CSS3 文字动画效果
Nov 12 HTML / CSS
值得收藏的HTML5资源(学习html5的朋友可以收藏下)
Jul 20 HTML / CSS
使用canvas绘制超炫时钟
Dec 17 HTML / CSS
HTML5 Canvas绘制五星红旗
May 04 HTML / CSS
HTML5新增属性data-*和js/jquery之间的交互及注意事项
Aug 08 HTML / CSS
Html5页面中的返回实现的方法
Feb 26 HTML / CSS
HTML5的postMessage的使用手册
Dec 19 HTML / CSS
萌新HTML5 入门指南(二)
Nov 09 HTML / CSS
HTML5单选框、复选框、下拉菜单、文本域的实现代码
Dec 01 HTML / CSS
HTML+CSS制作心跳特效的实现
May 26 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 通过Socket收发十六进制数据的实现代码
2013/08/16 PHP
php面向对象中static静态属性和静态方法的调用
2015/02/08 PHP
PHP中把错误日志保存在系统日志中(Windows系统)
2015/06/23 PHP
[原创]PHP获取数组表示的路径方法分析【数组转字符串】
2017/09/01 PHP
javascript Discuz代码中的msn聊天小功能
2008/05/25 Javascript
javascript 有用的脚本函数
2009/05/07 Javascript
Javascript 中文字符串处理额外注意事项
2009/11/15 Javascript
js 设置选中行的样式的实现代码
2010/05/24 Javascript
自己动手制作jquery插件之自动添加删除行功能介绍
2011/10/14 Javascript
用jquery实现输入框获取焦点消失文字
2013/04/27 Javascript
JS实现仿新浪微博发布内容为空时提示功能代码
2015/08/19 Javascript
实例详解angularjs和ajax的结合使用
2015/10/22 Javascript
js实现C#的StringBuilder效果完整实例
2015/12/22 Javascript
JS实现兼容各种浏览器的高级拖动方法完整实例【测试可用】
2016/06/21 Javascript
jQuery版AJAX简易封装代码
2016/09/14 Javascript
jQuery实现拖拽可编辑模块功能代码
2017/01/12 Javascript
详解ES6 Fetch API HTTP请求实用指南
2018/11/14 Javascript
jQuery实现的鼠标拖动画矩形框示例【可兼容IE8】
2019/05/17 jQuery
微信小程序template模板与component组件的区别和使用详解
2019/05/22 Javascript
vue指令v-html使用过滤器filters功能实例
2019/10/25 Javascript
vue使用echarts实现水平柱形图实例
2020/09/09 Javascript
解决win64 Python下安装PIL出错问题(图解)
2018/09/03 Python
Python3 读取Word文件方式
2020/02/13 Python
python3安装OCR识别库tesserocr过程图解
2020/04/02 Python
Python命令行参数定义及需要注意的地方
2020/11/30 Python
文科教师毕业的自我评价
2014/01/16 职场文书
警察先进个人事迹材料
2014/05/16 职场文书
纪律教育学习月活动总结
2014/08/27 职场文书
安全在我心中演讲稿
2014/09/01 职场文书
2015年个人实习工作总结
2014/12/12 职场文书
毕业生个人总结
2015/02/28 职场文书
关于实现中国梦的心得体会
2016/01/05 职场文书
nginx结合openssl实现https的方法
2021/07/25 Servers
Python中的tkinter库简单案例详解
2022/01/22 Python
Win10开机修复磁盘错误怎么跳过?Win10关闭开机磁盘检查的方法
2022/09/23 数码科技
mysql序号rownum行号实现方式
2022/12/24 MySQL