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和jquery实现自定义checkbox和radiobox组件
Apr 22 HTML / CSS
浅谈CSS3 box-sizing 属性 有趣的盒模型
Apr 02 HTML / CSS
html5 touch事件实现触屏页面上下滑动(一)
Mar 10 HTML / CSS
HTML5之SVG 2D入门6—视窗坐标系与用户坐标系及变换概述
Jan 30 HTML / CSS
HTML5+JS实现俄罗斯方块原理及具体步骤
Nov 29 HTML / CSS
h5调用摄像头的实现方法
Jun 01 HTML / CSS
Canvas 像素处理之改变透明度的实现代码
Jan 08 HTML / CSS
浅析数据存储的三种方式 cookie sessionstorage localstorage 的异同
Jun 04 HTML / CSS
萌新HTML5 入门指南(二)
Nov 09 HTML / CSS
Html5新增了哪些功能
Apr 16 HTML / CSS
css实现两栏布局,左侧固定宽,右侧自适应的多种方法
Aug 07 HTML / CSS
仅仅使用 HTML/CSS 实现各类进度条的方式汇总
Nov 11 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生成条形码的图片的实例详解
2017/09/13 PHP
使用jQuery的ajax功能实现的RSS Reader 代码
2009/09/03 Javascript
ExtJS 入门
2010/10/29 Javascript
IE6浏览器下resize事件被执行了多次解决方法
2012/12/11 Javascript
JS JSON对象转为字符串的简单实现方法
2013/11/18 Javascript
jquery删除数据记录时的弹出提示效果
2014/05/06 Javascript
javascript几个易错点记录
2014/11/26 Javascript
js使用Array.prototype.sort()对数组对象排序的方法
2015/01/28 Javascript
jQuery判断checkbox选中状态
2016/05/12 Javascript
浅谈javascript运算符——条件,逗号,赋值,()和void运算符
2016/07/15 Javascript
angular ng-click防止重复提交实例
2017/06/16 Javascript
SVG动画vivus.js库使用小结(实例代码)
2017/09/14 Javascript
javascript获取元素的计算样式
2019/05/24 Javascript
微信小程序实现页面跳转传递参数(实体,对象)
2019/08/12 Javascript
JavaScript图像放大镜效果实现方法详解
2020/06/28 Javascript
Vue管理系统前端之组件拆分封装详解
2020/08/23 Javascript
[00:27]DOTA2战队VP、Secret贺新春
2018/02/11 DOTA
[01:00:49]DOTA2-DPC中国联赛 正赛 Ehome vs iG BO3 第二场 1月31日
2021/03/11 DOTA
Windows系统下使用flup搭建Nginx和Python环境的方法
2015/12/25 Python
TF-IDF与余弦相似性的应用(一) 自动提取关键词
2017/12/21 Python
python的pandas工具包,保存.csv文件时不要表头的实例
2018/06/14 Python
Python中pandas模块DataFrame创建方法示例
2018/06/20 Python
在cmder下安装ipython以及环境的搭建
2018/10/19 Python
学习Django知识点分享
2019/09/11 Python
pygame实现俄罗斯方块游戏(基础篇2)
2019/10/29 Python
python opencv实现gif图片分解的示例代码
2019/12/13 Python
Python常用GUI框架原理解析汇总
2020/12/07 Python
CSS3实现简易版的刮刮乐效果
2016/09/27 HTML / CSS
css3类选择器之结合元素选择器和多类选择器用法
2017/03/09 HTML / CSS
澳大利亚办公室装修:JasonL Office Furniture
2019/06/25 全球购物
Ajax和javascript的区别
2013/07/20 面试题
应届生保险求职信
2013/11/11 职场文书
监护人证明
2015/06/19 职场文书
html5调用摄像头实例代码
2021/06/28 HTML / CSS
Python实现制作销售数据可视化看板详解
2021/11/27 Python
mysql函数之截取字符串的实现
2022/08/14 MySQL