接續昨天 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()
})
結果
畫布的裁切也能夠配合動畫效果來做,可以做出有趣的效果。
一樣先做出裁切遮罩物件,在幫裁切物件加上動畫就可以了。
// 畫布裁切
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)
})
}
今日利用 Fabricjs 裁切功能,做出了更多有趣的效果。
只能說 2.4.0
版本後新增的 clipPath
屬性真的是相當強大又簡單好用阿!
不論是在巢狀裁切還是配合其他如事件和動畫效果上都十分容易。