阅读 389

Fabric.js 自由绘制矩形(逐一分析4种操作方向带来的影响)

本文简介

在阅读本文前,你首先需要知道什么是 Fabric.js,还需要知道 Fabric.js 是如何创建矩形的。

如果你还没满足上面2个条件,推荐阅读 《Fabric.js从入门到____》


我在 Fabric.js 使用 框选操作 创建矩形。

接下来的几篇文章我会写如何自由绘制 圆形、椭圆形、三角形、线段、折线、多边形


本文不做任何 CSS 相关的美化,只讲解实现原理。

下图是本文的要实现的效果。

01.gif


使用 Fabric.js 这类框架,是要注意版本的。

本文所用版本: Fabric.js 4.6.0



原理

核心原理

用 “框选” 的方式生成矩形,其核心就2点:

  1. 鼠标 点击抬起 时获取坐标点,也就是 起始点结束点

  2. 鼠标抬起后,第1点  获取到的2个坐标计算出矩形的长、宽和位置。


鼠标点击:canvas.on('mouse:down', fn)

鼠标抬起: canvas.on('mouse:up', fn)


需要考虑的因素

理解了上面的核心点,接下来需要考虑的是鼠标框选的 方向

  1. 左上右下 框选

  2. 右下左上 框选

  3. 左下右上 框选

  4. 右上左下 框选


上面这4种情况会影响生成出来的矩形的 位置


生成矩形的代码

new fabric.Rect({     top: 0, // 矩形左上角在y轴的位置     left: 0, // 矩形左上角在x轴的位置     width: 100, // 矩形的宽     height: 100, // 矩形的高     fill: 'transparent', // 填充色     stroke: '#000' // 边框颜色 }) 复制代码


接下来逐一说说这4种操作带来的影响。


左上右下 框选

02.gif

这种情况是最好处理的。

此时 起始点 就是矩形的左上角,结束点 就是矩形的右下角。

起始点x 和 y 坐标 都小于 结束点,( 起始点x < 结束点x;起始点y < 结束点y ) :

  • 矩形的宽:结束点x坐标 - 起始点x坐标(也可以说是 (起始点x - 结束点x)的绝对值 )。

  • 矩形的高:结束点y坐标 - 起始点y坐标(也可以说是 (起始点y - 结束点y)的绝对值 )。

  • 左上角在x轴的位置:起始点的x轴坐标

  • 左上角在y轴的位置:起始点的y轴坐标


右下左上 框选

03.gif

起始点x > 结束点x; 起始点y > 结束点y

  • 宽:起始点x - 结束点x

  • 高:起始点y - 结束点y

  • 左上角在x轴的坐标:结束点x

  • 左上角在y轴的坐标:结束点y


左下右上 框选

04.gif

起始点x < 结束点x; 起始点y > 结束点y

  • 宽:(起始点x - 结束点y)的绝对值

  • 高:起始点y - 结束点y

  • 左上角在x轴的坐标:起始点x (比较x坐标,取小的那个,可以用 Math.min 方法)。

  • 左上角在y轴的坐标:结束点y (比较y坐标,取小的那个)。


右上左下 框选

05.gif

起始点x > 结束点x; 起始点y < 结束点y

  • 宽:起始点x - 结束点x

  • 高:(起始点y - 结束点y)的绝对值

  • 左上角在x轴的坐标:结束点x (比较x坐标,取小的那个,可以用 Math.min 方法)。

  • 左上角在y轴的坐标:起始点y (比较y坐标,取小的那个)。


总结公式

分析完上面4种情况,最后总结出来这几个参数的公式。

我将 起始点 命名为 downPoint结束点 命名为 upPoint

矩形的几个参数计算公式如下:

new fabric.Rect({     top: Math.min(downPoint.y, upPoint.y),     left: Math.min(downPoint.x, upPoint.x),     width: Math.abs(downPoint.x - upPoint.x),     height: Math.abs(downPoint.y - upPoint.y),     fill: 'transparent',     stroke: '#000' }) 复制代码


Math.min:两者之中取小值

Math.abs:返回绝对值

这两个都是 JS 提供的方法,如果不理解的建议去百度一下。



动手实现

我在这里贴出用 原生方式 实现的代码和注释。

如果你想知道在 Vue3 环境下如何实现 Fabric.js 自由绘制矩形,可以在 代码仓库 里查找。

<!-- 工具栏 --> <div class="toolbar">   <select onchange="typeChange(this.options[this.options.selectedIndex].value)">     <option value="default">默认(框选)</option>     <option value="rect">矩形</option>   </select> </div> <!-- 画布 --> <canvas id="canvas" width="800" height="800"></canvas> <!-- 引入fabric.js --> <script src="https://cdn.bootcdn.net/ajax/libs/fabric.js/460/fabric.js"></script> <script> let canvas = null // 画布对象 let currentType = 'default' // 当前操作模式(默认 || 创建矩形) let downPoint = null // 按下鼠标时的坐标 let upPoint = null // 松开鼠标时的坐标 // 初始化画板 function initCanvas() {   canvas = new fabric.Canvas('canvas')   canvas.on('mouse:down', canvasMouseDown)   // 鼠标在画布上按下   canvas.on('mouse:up', canvasMouseUp)       // 鼠标在画布上松开 } // 画布操作类型切换 function typeChange(opt) {   currentType = opt   switch(opt) {     case 'default': // 默认框选模式       canvas.selection = true // 允许框选       canvas.selectionColor = 'rgba(100, 100, 255, 0.3)' // 选框填充色:半透明的蓝色       canvas.selectionBorderColor = 'rgba(255, 255, 255, 0.3)' // 选框边框颜色:半透明灰色       canvas.skipTargetFind = false // 允许选中       break     case 'rect': // 创建矩形模式       canvas.selectionColor = 'transparent' // 选框填充色:透明       canvas.selectionBorderColor = 'rgba(0, 0, 0, 0.2)' // 选框边框颜色:透明度很低的黑色(看上去是灰色)       canvas.skipTargetFind = true // 禁止选中       break   } } // 鼠标在画布上按下 function canvasMouseDown(e) {   // 鼠标左键按下时,将当前坐标 赋值给 downPoint。{x: xxx, y: xxx} 的格式   downPoint = e.absolutePointer } // 鼠标在画布上松开 function canvasMouseUp(e) {   // 绘制矩形的模式下,才执行下面的代码   if (currentType === 'rect') {     // 松开鼠标左键时,将当前坐标 赋值给 upPoint     upPoint = e.absolutePointer     // 调用 创建矩形 的方法     createRect()   } } // 创建矩形 function createRect() {   // 如果点击和松开鼠标,都是在同一个坐标点,不会生成矩形   if (JSON.stringify(downPoint) === JSON.stringify(upPoint)) {     return   }   // 创建矩形   // 矩形参数计算(前面总结的4条公式)   let top = Math.min(downPoint.y, upPoint.y)   let left = Math.min(downPoint.x, upPoint.x)   let width = Math.abs(downPoint.x - upPoint.x)   let height = Math.abs(downPoint.y - upPoint.y)   // 矩形对象   const rect = new fabric.Rect({     top,     left,     width,     height,     fill: 'transparent', // 填充色:透明     stroke: '#000' // 边框颜色:黑色   })   // 将矩形添加到画布上   canvas.add(rect)   // 创建完矩形,清空 downPoint 和 upPoint。当然,你也可以不做这步。   downPoint = null   upPoint = null } // 页面加载的生命周期,在此执行 初始化画布 的操作 window.onload = function() {   initCanvas() } </script>


作者:德育处主任
链接:https://juejin.cn/post/7058093223566114847


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐