Fabric.js图形裁切进阶

2018-11-28 12:20:34
1409次阅读
0个评论

接续昨天 Day 22 - Fabricjs 图形裁切基础介绍 继续来做一些图片裁切的进阶操作,一样使用 clipPath 来做更多的变化,以下是今天的大纲,。


文字做為裁切遮罩
巢状裁切
群组内巢状裁切
画布裁切
滑鼠应用
裁切动画
文字做為裁切遮罩

可以使用 fabric.Text 做為裁切遮罩来裁切物件,让文字的顏色更加丰富。

一样先使用 new fabric.Text 来建立物件,在建立一个群组将这个群组的 clipPath 设定成文字物件。

const textClip = new fabric.Text('参加铁人赛\n一天一篇文章\n有益身心健康', {
  left: -150,
  top: -100
})

const group = new fabric.Group([
  new fabric.Rect({ width: 150, height: 100, fill: 'red' }),
  new fabric.Rect({ width: 150, height: 150, fill: 'yellow', left: 150 }),
  new fabric.Rect({ width: 150, height: 100, fill: 'blue', top: 100 }),
  new fabric.Rect({ width: 150, height: 150, fill: 'green', left: 150, top: 100 })
], {
  clipPath: textClip
})

结果


巢状裁切

巢状遮罩也就是切了又切,可以先将图片做裁切,再将裁切后的物件拿去裁切别人。

这边先将两个圆形切齐的部分裁切出来,再拿来裁切群组矩形。

const clipPath = new fabric.Circle({radius: 100, top: -150, left: -100})
// 先切一遍
const innerClip = new fabric.Circle({radius: 100, top: 10, left: -100})
clipPath.clipPath = innerClip
// 再切一次
group.clipPath = clipPath



群组内巢状裁切

我们甚至可以将群组内的物件先做裁切后,再将群组物件被裁切,这样也是可行的。

const nestGroup2 = makeGroupRect(600, 0)
const circleClip = new fabric.Circle({radius: 100, top: -100, left: -100})
nestGroup2.item(0).clipPath = clipPath
nestGroup2.clipPath = circleClip



画布裁切

Fabricjs 竟然在 canvas 也让我们可以设定 clipPath 这个属性,所以我们也可以透过改变 canvas.clipPath 来做到裁切整张画布的效果!

clipPath 和一般物件裁切不同的地方,画布裁切绘画的起点会在左上角的位置
// 画布裁切
const canvasClip = new fabric.Circle({radius: 100})
canvas.clipPath = canvasClip


但这边发现超出去的画面控制项会不见,可以透过 canvas.controlsAboveOverlay = true 来显示被覆盖过去的控制项。

配合滑鼠

这边配合滑鼠事件让画布裁切跟著我们滑鼠来移动,会有点类似找东西的效果。

canvas.on('mouse:move', ops => {
  let e = ops.e
  canvasClip.set({
    left: e.offsetX - 100,
    top: e.offsetY - 100
  })
  canvas.renderAll()
})

结果


Day 8 - Fabricjs 事件
画布裁切动画

画布的裁切也能够配合动画效果来做,可以做出有趣的效果。

一样先做出裁切遮罩物件,在帮裁切物件加上动画就可以了。

// 画布裁切
const aniClip = new fabric.Circle({radius: 100, top: -100, left: -100})
// 建立画布裁切动画
nextMoving(aniClip)

canvas.clipPath = aniClip

canvas.add(aniGroup)

// 此部分同 Day 9 - Fabricjs 动画
function nextMoving (circle) {
  circle.animate('left', getRandomInt(0, canvas.width), {
    onChange: () => {
      canvas.renderAll()
    },
    easing: fabric.util.ease.easeInOutCubic,
    duration: getRandomInt(1000, 3000)
  })
  circle.animate('radius', getRandomInt(50, 100), {
    onChange: () => {
      canvas.renderAll()
    },
    easing: fabric.util.ease.easeInOutCubic,
    duration: getRandomInt(1000, 3000)
  })
  circle.animate('top', getRandomInt(0, 100), {
    onChange: () => {
      canvas.renderAll()
    },
    onComplete: () => nextMoving(circle),
    easing: fabric.util.ease.easeInOutCubic,
    duration: getRandomInt(1000, 3000)
  })
}

Day 9 - Fabricjs 动画


本日小结

今日利用 Fabricjs 裁切功能,做出了更多有趣的效果。

只能说 2.4.0 版本后新增的 clipPath 属性真的是相当强大又简单好用阿!

不论是在巢状裁切还是配合其他如事件和动画效果上都十分容易。
收藏00

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