翼度科技»论坛 编程开发 JavaScript 查看内容

Fabric.js 拖放元素进画布

8

主题

8

帖子

24

积分

新手上路

Rank: 1

积分
24
本文简介

点赞 + 关注 + 收藏 = 学会了

学习 Fabric.js,我的建议是看文档不如看 demo。
本文实现的功能:将元素拖进到画布中并生成对应的图形或图片。
效果如下图所示:



思路

要实现以上效果,需要考虑以下几点:

  • 元素有拖拽功能。
  • 能在画布中生成对应的元素。
  • 画布有可能缩放。
  • 画布有可能移动。
  • 画布的位置可能在页面的某处。
  • 在3和4情况下还能在准确的位置生成元素。

基于以上几点,我得出以下解法。

  • 解1:要让 HTML 元素具备拖拽功能,只要将 draggable 属性设置为 true 即可。
  • 解2:Fabric.js 创建元素可看 《Fabric.js 从入门到膨胀》的基础图形篇,要创建图片可以看 图片篇
  • 解3:缩放画布我在 《Fabric.js 缩放画布》 里讲解过。
  • 解4:移动画布我在 《Fabric.js 拖拽平移画布》 里讲解过。
  • 解5:画布的左上角不一定在body的左上角,也就是鼠标当前位置可能和画布对应的坐标不一样,需要通过加减法计算一下。
  • 解6:Fabric.js 提供了一个方法可以将鼠标当前坐标转换为画布对应的真实坐标,这个方法叫 restorePointerVpt 。


动手

我分几个步骤慢慢实现上述功能。我知道你很急,但你先别急

创建画布及元素

  1.   
  2.    
  3.    
  4.    
  5.   
  6.   <canvas id="c" ></canvas>
复制代码
上面的代码使用了 Fabric.js 绑定了页面上的画布,并创造了一个粉红色的矩形。
按住 alt 后,使用鼠标在画布上可以拖拽画布。
在画布上滚动鼠标滚轮可以缩放画布。
左侧的元素列表也将 draggable 属性设置为 true,元素具备拖拽功能了。

监听元素放进画布

我们还需要使用一个变量来记录当前拖拽的是什么元素。
  1.   
  2.   
  3.   
复制代码
前面的代码已经知道拖拽时需要生成什么类型的元素了,现在还需要知道生成到画布的哪个地方(x和y坐标)
松开鼠标时,需要计算鼠标在画布的坐标。这里的坐标是指画布在页面中的位置转换出来的坐标,而且还要计算画布拖拽和缩放过的情况。
我的做法是通过 canvas 元素的 getBoundingClientRect() 方法返回的对象中获取到 top 和 left 两个数据。这两个数据就是 canvas 元素距离页面顶部和左侧的距离。
然后通过鼠标当前坐标减去 canvas 距离页面顶部或左侧的距离,计算出鼠标点击画布的真实坐标。
但画布有可能拖拽和缩放,所以需要通过 Fabric.js 提供的 restorePointerVpt() 方法将坐标转换一下。
于是有了下面的代码。
  1. // 省略部分代码......
  2. canvas.on('drop', function(opt) {
  3.   // 画布元素距离浏览器左侧和顶部的距离
  4.   let offset = {
  5.     left: canvas.getSelectionElement().getBoundingClientRect().left,
  6.     top: canvas.getSelectionElement().getBoundingClientRect().top
  7.   }
  8.     // 鼠标坐标转换成画布的坐标(未经过缩放和平移的坐标)
  9.   let point = {
  10.     x: opt.e.x - offset.left,
  11.     y: opt.e.y - offset.top,
  12.   }
  13.   // 转换后的坐标,restorePointerVpt 不受视窗变换的影响
  14.   let pointerVpt = canvas.restorePointerVpt(point)
  15. })
复制代码
生成对应的元素

上面的代码最后得出的 pointerVpt 就是转换后最终的坐标,我们在这个坐标上生成元素即可。
  1. // 省略部分代码......canvas.on('drop', function(opt) {  // 省略部分代码......  switch (currentType) {    case 'rect':  
  2.   
  3.   createRect(pointerVpt.y, pointerVpt.x)  
  4.   
  5.   break    case 'circle':  
  6.   
  7.   createCircle(pointerVpt.y, pointerVpt.x)  
  8.   
  9.   break    case 'img':  
  10.   
  11.   createImg(pointerVpt.y, pointerVpt.x)    break  }  // 创建完元素,把当前操作的元素类型设置回 null  currentElType = null})// 创建矩形function createRect(top, left) {  canvas.add(new fabric.Rect({    top,    left,    width: 60,    height: 60,    fill: 'pink'  }))}// 创建圆形function createCircle(top, left) {  canvas.add(new fabric.Circle({    top,    left,    radius: 30,    fill: 'pink'  }))}// 创建图片元素function createImg(top, left) {  fabric.Image.fromURL('./picture.jpg', oImg => {    oImg.top = top    oImg.left = left    canvas.add(oImg)  })}
复制代码

代码仓库

前面都是碎碎念,代码一段一段的。如果需要完整版代码可以打开链接自取。
Fabric.js 拖拽创建元素


推荐阅读



来源:https://www.cnblogs.com/k21vin/p/17039823.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具