Fabric.js 复制粘贴元素

本文简介

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


当你要复制一个 fabric 的元素时,你考虑到的是什么?是深拷贝当前选中对象再添加到画布中?


其实,fabric.js 提供了一个克隆方法,在 fabric.js 官网的案例里也有这个demo:Fabric.js demos · Copy and Paste。

这次就讲讲这个 demo。

Fabric.js 复制粘贴元素_第1张图片



实现思路

动手之前,我们先理清思路。

  1. 要复制元素,首先就得有元素,所以我们在页面创建一些元素(好像再讲废话)。
  2. 复制前,肯定需要有被复制的目标,我们可以使用 canvas.getActiveObject() 方法获取当前被选中的元素。
  3. 复制时,可以使用 clone() 方法,将当前选中的元素对象克隆出来。
  4. 粘贴时,使用 canvas.add() 方法将克隆出来的元素添加到画布中。

当然,实际开发中还有很多需要注意的小点,比如选中一个组的时候要怎么复制粘贴?框选一堆元素时要怎么复制粘贴?

这些问题后面都会讲到,我们先学习如何复制1个元素。



动手编码

理解了前面的思路就能动手了!


复制单个元素

Fabric.js 复制粘贴元素_第2张图片

首先在页面中创建2个按钮和1个画布,在画布中创建一个元素。

JS 部分需要创建一个变量保存克隆对象,这个变量叫 _clipboard

在执行复制操作时要判断当前是否选中元素对象。

在执行粘贴操作时要判断当前是否克隆了元素对象。


复制组

其实复制组和复制单个元素时一样的。也是需要获取当前选中的对象,组可以看作是一个元素对象。

代码和上面的一样,只需把单个元素换成组即可,我引用 fabric.js 官网的 demo

Fabric.js 复制粘贴元素_第3张图片

// 省略部分代码

let circle1 = new fabric.Circle({
  radius: 65,
  fill: '#039BE5',
  left: 0
})

let circle2 = new fabric.Circle({
  radius: 65,
  fill: '#4FC3F7',
  left: 110,
  opacity: 0.7
})

let group = new fabric.Group([circle1, circle2, ], {
  left: 40,
  top: 250
})

canvas.add(group)

加上前面的复制粘贴代码即可。


复制框选的元素

复制框选元素的操作会相对复杂一丢丢,但也只是一丢丢而已。

Fabric.js 复制粘贴元素_第4张图片

因为选中的不止一个元素,所以在粘贴的时候要遍历所有元素出来,用到 fabric.js 提供的 forEachObject 方法。

// 省略部分代码

// 粘贴
function paste() {
  // 如果克隆对象不存在的话就终止粘贴执行
  if (!_clipboard) return

  _clipboard.clone(function(clonedObj) {
    // 适当的位移
    clonedObj.set({
      left: clonedObj.left + 10,
      top: clonedObj.top + 10,
      evented: true
    })

    // 遍历粘贴所有选中的元素
    clonedObj.canvas = canvas
    clonedObj.forEachObject(function(obj) {
      canvas.add(obj)
    })
    clonedObj.setCoords()

    // 适当的位移
    _clipboard.top += 10
    _clipboard.left += 10

    // 将新粘贴出来的元素全部选中
    canvas.setActiveObject(clonedObj)
  })
}

最后需要做的就是兼容选中单个元素或者框选多个元素的情况。

获取到当前选中对象后有个 type 属性,当框选多个元素时,type 的值会变成 activeSelection ,我们就可以通过这个来判断当前是选中单个元素还是框选了多个元素。

// 省略部分代码

// 粘贴
function paste() {
  // 如果克隆对象不存在的话就终止粘贴执行
  if (!_clipboard) return

  _clipboard.clone(function(clonedObj) {
    // 适当的位移
    clonedObj.set({
      left: clonedObj.left + 10,
      top: clonedObj.top + 10,
      evented: true
    })

    if (clonedObj.type === 'activeSelection') {
      // 框选了多个元素
      // 遍历粘贴所有选中的元素
      clonedObj.canvas = canvas
      clonedObj.forEachObject(function(obj) {
        canvas.add(obj)
      })
      clonedObj.setCoords()
    } else {
      // 选中一个元素
      canvas.add(clonedObj)
      _clipboard.top += 10
      _clipboard.left += 10
    }

    // 适当的位移
    _clipboard.top += 10
    _clipboard.left += 10

    // 将新粘贴出来的元素全部选中
    canvas.setActiveObject(clonedObj)
    // 刷新画布
    canvas.requestRenderAll()
  })
}

除了上面的鼠标操作外,我们还可以通过监听键盘的 ctrl + cctrl + v(mac监听 command) 来实现上面的效果。

这部分工作留给工友去实现吧,我先溜了。



代码仓库

本文完整代码可通过下方链接获取。

⭐ 复制粘贴元素



推荐阅读

《Fabric.js 从入门到_ _ _ _ _ _》

《Fabric.js 拖拽顶点修改多边形形状》

《Fabric.js 讲解官方demo:Stickman》

《Fabric.js 自定义控件》

《Fabric.js 样式不更新怎么办?》

《Fabric.js 图案画笔(笔刷)》


点赞 + 关注 + 收藏 = 学会了 代码仓库

你可能感兴趣的:(前端)