• Fabric.js 复制粘贴元素


    本文简介

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


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


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

    这次就讲讲这个 demo。

    file



    实现思路

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

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

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

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



    动手编码

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


    复制单个元素

    file

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

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

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

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

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


    复制组

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

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

    file

    // 省略部分代码
    
    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)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

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


    复制框选的元素

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

    file

    因为选中的不止一个元素,所以在粘贴的时候要遍历所有元素出来,用到 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)
      })
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

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

    获取到当前选中对象后有个 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()
      })
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

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

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



    代码仓库

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

    复制粘贴元素



    推荐阅读

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

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

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

    👍《Fabric.js 自定义控件》

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

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


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

  • 相关阅读:
    AI绘画:StableDiffusion实操教程-诛仙-碧瑶(附高清图下载)
    Spring MVC的主要组件?
    MCE | 打破 Western Blot 玄学操作
    【华为OD机试】处理器问题
    谷粒商城实战(008 缓存)
    CSP-J 2022年8月第一轮模拟赛 1
    如何将几张图片转换为GIF动图?
    6.11.面图层(Polygon)
    C++ 作业 24/3/11
    产品经理必备的能力有哪些?
  • 原文地址:https://blog.csdn.net/weixin_39415598/article/details/134080420