Fabric.js图形裁切基础介绍

2018-11-28 12:14:49
3163次阅读
0个评论

裁切功能在一般图片编辑软体相当的常见,这边也能够透过 Fabricjs 来做图片裁切的功能,甚至可以做出让使用者自行决定裁切的位置,切出他们想要留下的范围,或是用一些特别的图形来做特别的裁切效果。


Fabricjs 提供的裁切功能,就在最近发布的 2.4.0 版本之后,能够直接使用 Fabricjs 创建出来的物件和物件重叠,再决定裁切的效果要如何。

而在 2.4.0 版本之前则需要使用物件中的 clipTo 属性,必须使用原生 canvas 的语法来做裁切的效果。

在 2.4.0 版本之后的这个改动,能够让我们更加简单的去使用 fabricjs 所提供的裁切功能,且不须要太多原生知识就能够执行了,不过还是保留了 2.4.0 版本之前的 clipTo 提供了更弹性的使用方法。

clipTo 属性介绍 (2.4.0 版本之前)

这边先来简单介绍一下 2.4.0 以前 clipTo 属性的使用,其实使用方法也很简单,只要将 clipTo 属性设定為 callBack function ,并且使用 ctx 来做绘画,使用 canvas 原生的绘图方式画出一个形状之后,fabricjs render 时就会自动做裁切了。

const imgEl = document.createElement('img')
imgEl.crossOrigin = 'Anonymous'
imgEl.src = 'https://i.imgur.com/1k9XjUn.jpg'
imgEl.onload = () => {
  const image = new fabric.Image(imgEl, {
    scaleX: 0.5,
    scaleY: 0.5,
    angle: 15,
    top: 60,
    left: 300,
    clipTo: function (ctx) {
      ctx.arc(0, 0, 200, 0, Math.PI * 2, true)
    }
  })
  canvas.add(image)
}



clipPath 属性介绍 (2.4.0 版本之后)

2.4.0 版本后,若要做裁切的功能,可以先新增一个物件暂存起来,再加入到想要裁切的物件中的 clipPath 属性中。

让我们来实作这部分。

先设定一个圆形来準备做裁切

这边因為是要来拿做裁切的物件,所以它的 top left 属性视参照於被裁切的物件,且被裁切物件起始点為物件的中心。

// 以被裁切物件的中心為起始点
const clipPath = new fabric.Circle({
  radius: 200,
  top: -200, // 被裁切物件中心点為基準的 -200
  left: -200 // 被裁切物件中心点為基準的 -200
})

设定 clipPath

透过设定被裁切物件的 clipPath 属性,指定為 clipPath 為上面新增的圆形,这样一来,就能做出裁切的效果,图片只显示圆形半径為 200 的部分,也就是两个物件所重叠的部分。

imgEl.onload = () => {
  const image = new fabric.Image(imgEl, {
    scaleX: 0.5,
    scaleY: 0.5,
    top: 60,
    left: 300,
    clipPath // 这个 clipPath 為设定裁切的关键
  })
  canvas.add(image)
}

结果会同上


使用群组裁切

新的裁切功能,可以更自由的使用裁切,能够透过群组物件 (group) ,作為裁切或是被裁切的物件。

接下来会来试试使用群组当做裁切遮罩,以及让群组被裁切。

裁切群组

做出组合当作裁切遮罩

如果你想要把裁切遮罩完美的对齐正中间,请将 originX originY 设定成 'center',且不需要再额外设定 left top
const groupClip = new fabric.Group([
  new fabric.Rect({ width: 50, height: 50 }),
  new fabric.Rect({ width: 50, height: 50, angle: 45 }),
  new fabric.Rect({ width: 50, height: 50, angle: 90 }),
  new fabric.Rect({ width: 50, height: 50, angle: 135 }),
  new fabric.Rect({ width: 50, height: 50, angle: 180 }),
  new fabric.Rect({ width: 50, height: 50, angle: 225 }),
  new fabric.Rect({ width: 50, height: 50, angle: 270 }),
  new fabric.Rect({ width: 50, height: 50, angle: 315 })
], {
  scaleX: 3,
  scaleY: 3,
  originX: 'center',
  originY: 'center'
})

再来一样设定 clipPath 指定為 groupClip 物件。

 
const groupImage = new fabric.Image(imgEl, {
    scaleX: 0.5,
    scaleY: 0.5,
    clipPath: groupClip
  })
  canvas.add(groupImage)

OK 完成


群组切群组

依照上面的逻辑,可以很间单的做出群组切群组的功能,只要好好地将 clipPath 设定好就行了。

const circleClip = new fabric.Group([
  new fabric.Circle({ radius: 50, top: -50, left: -50 }),
  new fabric.Line([0, 0, 100, 100], { strokeWidth: 5, fill: 'black', stroke: 'black' }),
  new fabric.Line([0, 0, 100, 100], { strokeWidth: 5, fill: 'black', stroke: 'black', angle: 90 }),
  new fabric.Line([0, 0, 100, 100], { strokeWidth: 5, fill: 'black', stroke: 'black', angle: 180 }),
  new fabric.Line([0, 0, 100, 100], { strokeWidth: 5, fill: 'black', stroke: 'black', angle: 270 })
])
const group = new fabric.Group([
    new fabric.Rect({ width: 100, height: 100, fill: 'red' }),
    new fabric.Rect({ width: 100, height: 100, fill: 'yellow', left: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'blue', top: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'green', left: 100, top: 100 })
  ], {
  clipPath: circleClip
})
canvas.add(group)



本日小结

今天介绍了几种裁切物件的方式,个人觉得在 2.4.0 版本过后 Fabricjs 所提供的 clipPath 实在是相当简单易用,尤其在群组裁切的部分,不需要自己再去用 canvas 原生 api 刻出复杂的图形,透过搭配 fabric.Group 功能就可以做到很方便的裁切。
收藏00

登录 后评论。没有帐号? 注册 一个。