在經過了兩天的裁切介紹,今天要來介紹另外一種方式來做圖片的裁切!
透過實作圖片裁切功能,來了解 image.crop
這個屬性的使用。
來實現能夠讓使用者自訂想要裁切的範圍。
一起來看看該怎麼做吧
這邊先新增一張圖片後,將 canvas
的大小動態變成圖片的原始大小。
並且新增一個和圖片一樣大的半透明遮罩讓使用者選取。
可使用 naturalWidth
、 naturalHeight
來取得讀取圖片的原始大小。
img = new fabric.Image(imgEl, {
top: 0,
left: 0,
selectable: false
})
canvas.setWidth(imgEl.naturalWidth)
canvas.setHeight(imgEl.naturalHeight)
userClipPath = new fabric.Rect({
width: imgEl.naturalWidth, // 圖片原始大小
height: imgEl.naturalHeight,
fill: 'rgb(178, 178, 178, 0.4)',
})
canvas.add(img)
canvas.add(userClipPath)
得到和圖片一樣大的 canvas
圖片
crop
屬性crop
屬性為 fabric.Image
專屬的屬性,可以透過設定 cropX
、sropY
來設定裁切的起始位置,並且使用 width
、height
決定大小。
讓我們看看下面的圖解。
程式就會是這樣寫的。
img.set({
cropX: 100,
cropY: 100,
width: 100,
height: 100
})
出來的結果會是這樣
crop
屬性這邊我想要讓使用者自己訂出想要裁切的範圍,所以我們可以讓使用者調整半透明矩形,調整完當使用者點選 "裁切" 按鈕後。
再去抓取目前半透明矩形的位置和形狀,並且更改圖片的 cropX
、cropY
、width
、height
屬性,並且動態改變 canvas 的大小。
因為使用者可能不只裁切一次,所以我們需要紀錄目前裁切位置在哪邊來做累加,所以使用 nowClip
物件紀錄目前的裁切起始位置。
let nowClip = {
x: 0,
y: 0
}
function clipImage () {
console.log('clip!')
const newImgCrop = userClipPath.getBoundingRect()
console.log(newImgCrop)
canvas.setWidth(newImgCrop.width)
canvas.setHeight(newImgCrop.height)
img.set({
cropX: newImgCrop.left + nowClip.x,
cropY: newImgCrop.top + nowClip.y,
width: newImgCrop.width,
height: newImgCrop.height
})
// 校正位置
nowClip.x += newImgCrop.left
nowClip.y += newImgCrop.top
userClipPath.set({
left: 0,
top: 0
})
userClipPath.setCoords()
canvas.renderAll()
}
最後再加入一些常用的功能,和修改一些細節
須注意匯出時因為還有矩形遮罩,我這邊不讓矩形遮罩一起被匯出成圖檔的方法是將透明度先調成 0,匯出後在加入回來。
function output () {
// 用來讓使用者看的遮罩不想入鏡
userClipPath.opacity = 0
const dataURL = canvas.toDataURL({
format: `image/jpeg`,
top: 0,
left: 0,
width: canvas.width,
height: canvas.height,
multiplier: 1
})
const a = document.createElement('a')
a.href = dataURL
a.download = `output.jpeg`
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
userClipPath.opacity = 1
canvas.renderAll()
}
canvas
清除後,再次做原本剛進入時,新增圖片和矩形遮罩的動作。function reset () {
canvas.clear()
initCanvas()
}
今日練習使用 Image.cropX
、Image.cropY
達到圖片裁切的效果。
並且做出讓使用者能夠自訂裁切區塊的功能。