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显示隐藏一个div特效的具体实现
Feb 10 HTML / CSS
你应该知道的30个css选择器
Mar 19 HTML / CSS
IE浏览器单独写CSS样式的几种方法
Oct 14 HTML / CSS
详解CSS3中Media Queries的相关使用
Jul 17 HTML / CSS
CSS3 实现弹跳的小球动画
Oct 26 HTML / CSS
HTML5 Web 存储详解
Sep 16 HTML / CSS
基于 HTML5 Canvas实现 的交互式地铁线路图
Mar 05 HTML / CSS
html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点
Jan 09 HTML / CSS
HTML5在IE10、火狐下中文乱码问题的解决方法
Nov 18 HTML / CSS
HTML5+lufylegend实现游戏中的卷轴
Feb 29 HTML / CSS
HTML5视频播放插件 video.js介绍
Sep 29 HTML / CSS
canvas简单连线动画的实现代码
Feb 04 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中for循环语句的几种变型
2006/11/26 PHP
javascript 小型动画组件与实现代码
2010/06/02 PHP
php中explode与split的区别介绍
2012/10/03 PHP
Laravel框架中VerifyCsrfToken报错问题的解决
2017/08/30 PHP
详细解读php的命名空间(二)
2018/02/21 PHP
laravel 5.5 关闭token的3种实现方式
2019/10/24 PHP
利用javascript判断文件是否存在
2013/12/31 Javascript
基于jQuery实现文本框缩放以及上下移动功能
2014/11/24 Javascript
jQuery实现流动虚线框的方法
2015/01/29 Javascript
nodejs实现获取某宝商品分类
2015/05/28 NodeJs
浅谈js内置对象Math的属性和方法(推荐)
2016/09/19 Javascript
jquery操作select取值赋值与设置选中实例
2017/02/28 Javascript
基于vue.js实现侧边菜单栏
2017/03/20 Javascript
javascript作用域链与执行环境详解
2017/03/25 Javascript
Vue.js实战之通过监听滚动事件实现动态锚点
2017/04/04 Javascript
js插件实现图片滑动验证码
2020/09/29 Javascript
layui点击按钮添加可编辑的一行方法
2018/08/15 Javascript
微信小程序自定义toast弹窗效果的实现代码
2018/11/15 Javascript
如何优雅的在一台vps(云主机)上面部署vue+mongodb+express项目
2019/01/20 Javascript
微信小程序 wx:for遍历循环使用实例解析
2019/09/09 Javascript
微信小程序获取地理位置及经纬度授权代码实例
2019/09/18 Javascript
微信小程序实现禁止分享代码实例
2019/10/19 Javascript
教你如何将 Sublime 3 打造成 Python/Django IDE开发利器
2014/07/04 Python
使用Python脚本对Linux服务器进行监控的教程
2015/04/02 Python
Python干货:分享Python绘制六种可视化图表
2018/08/27 Python
python简单贪吃蛇开发
2019/01/28 Python
Python英文文章词频统计(14份剑桥真题词频统计)
2019/10/13 Python
pytorch实现seq2seq时对loss进行mask的方式
2020/02/18 Python
利用keras使用神经网络预测销量操作
2020/07/07 Python
Python将字典转换为XML的方法
2020/08/01 Python
python 写一个水果忍者游戏
2021/01/13 Python
html5 input输入实时检测以及延时优化
2018/07/18 HTML / CSS
司马光教学反思
2014/02/01 职场文书
教育教学工作反思
2016/02/24 职场文书
python使用glob检索文件的操作
2021/05/20 Python
解决IDEA翻译插件Translation报错更新TTK失败不能使用
2022/04/24 Python