本文簡介 我列舉了3種在 Fabric.js 中 更換圖片 的方法。 其中還包括 更換組內圖片 的操作。 環境和版本 Chrome瀏覽器版本:96.0.4664.45 Fabric.js版本:4.6.0 我是在原生環境下開發的,同時也提供了一份 Vue3 環境下開發的代碼(文末有鏈接)。 動手操作 ...
本文簡介
我列舉了3種在 Fabric.js
中 更換圖片 的方法。
其中還包括 更換組內圖片 的操作。
環境和版本
Chrome瀏覽器版本:96.0.4664.45
Fabric.js版本:4.6.0
我是在原生環境下開發的,同時也提供了一份 Vue3
環境下開發的代碼(文末有鏈接)。
動手操作
接下來有3個案例,使用了2張圖片 Agumon.png
和 Bhikkhu.png
,圖片是在 iconfont 網站上找到的。
如果需要使用本案例的圖片,可以在文末提供的倉庫中獲取。
情景1:更換圖片元素的src
如果在畫布上添加的是 Image
對象,那麼可以使用 Image.setSrc
設置新的圖片,然後再使用 Canvas.renderAll
刷新一下畫布即可。
<style>
canvas {
border: 1px solid #ccc;
}
</style>
<button onclick="change()">修改圖片</button>
<canvas width="300" height="300" id="canvas"></canvas>
<script src="https://cdn.bootcdn.net/ajax/libs/fabric.js/460/fabric.min.js"></script>
<script>
// 實例化canvas
canvas = new fabric.Canvas('canvas')
// 創建圖片對象
fabric.Image.fromURL('../../images/Agumon.png', oImg => {
// 將圖片對象添加到 canvas 中
canvas.add(oImg)
})
// 更換圖片事件
function change() {
// 獲取圖片對象。因為在本例中,畫布里只有一個元素,用 getObjects() 獲取到的數組第一個元素就是圖片咯
const img = canvas.getObjects()[0]
// 使用 setSrc 方法更改圖片,第二個參數是回調函數,在回調函數里刷新一下 canvas 即可
img.setSrc('../../images/Bhikkhu.png', () => {
canvas.renderAll()
})
}
</script>
上面這種情景是最簡單的。
如果畫布上有多個圖形和圖片,你可能需要在創建圖片的時候加一些自定義屬性進去判斷。
使用 fabric.getObjects().find()
去搜索就行了。
find()
就是數組的原始方法。
情景2:修改組內的圖片(無緩存)
創建組預設是有緩存的,有緩存的話使用 Canvas.renderAll()
方法重新渲染也不會更新圖片。
所以在創建組的時候要聲明 不緩存: Group.objectCaching
。
<style>
canvas {
border: 1px solid #ccc;
}
</style>
<button onclick="change()">修改圖片</button>
<canvas width="300" height="300" id="canvas"></canvas>
<script src="https://cdn.bootcdn.net/ajax/libs/fabric.js/460/fabric.min.js"></script>
<script>
// 實例化canvas
canvas = new fabric.Canvas('canvas')
// 創建圖片對象
fabric.Image.fromURL('../../images/Agumon.png', oImg => {
// 文本
const text = new fabric.Text('沒緩存的組', {
fontSize: 14,
top: 50
})
// 創建組
const group = new fabric.Group([oImg, text], {
objectCaching: false // 不緩存!!!
})
// 將分組添加到canvas里
canvas.add(group)
})
// 更換圖片事件
function change() {
// 獲取組
const group = canvas.getObjects()[0]
// 獲取圖片
const img = group.getObjects().find(item => {
// 通過 isType 判斷圖片元素,因為組內有2個元素(一個圖片,一個文本)
return item.isType('image')
})
// 找到圖片,然後更換
img.setSrc('../../images/Bhikkhu.png', () => {
// 更換完圖片,刷新一下 canvas
canvas.renderAll()
})
}
</script>
這種情景,重點在創建組時,要聲明 objectCaching: false
。
情景3:修改組內的圖片(有緩存)
如果 組(Group) 設置了緩存,又需要更換 組(Group) 內的圖片。
我的做法是:
- 查找圖片對象,並保存到一個變數上;
- 刪除分組內的圖片對象(使用
Group.removeWithUpdate
); - 更新圖片對象的
src
指向(使用Image.setSrc
); - 將圖片放到分組裡(使用
Group.addWithUpdate
); - 重新渲染畫布(使用
Canvas.renderAll
);
<style>
canvas {
border: 1px solid #ccc;
}
</style>
<button onclick="change()">修改圖片</button>
<canvas width="300" height="300" id="canvas"></canvas>
<script src="https://cdn.bootcdn.net/ajax/libs/fabric.js/460/fabric.min.js"></script>
<script>
// 實例化canvas
canvas = new fabric.Canvas('canvas')
// 創建圖片對象
fabric.Image.fromURL('../../images/Agumon.png', oImg => {
// 文本
const text = new fabric.Text('沒緩存的組', {
fontSize: 14,
top: 50
})
// 創建組
const group = new fabric.Group([oImg, text])
// 將分組添加到canvas里
canvas.add(group)
})
// 更換圖片事件
function change() {
// 獲取組
const group = canvas.getObjects()[0]
// 【1】查找圖片對象,並保存到一個變數上
const img = group.getObjects().find(item => {
// 通過 isType 判斷圖片元素,因為組內有2個元素(一個圖片,一個文本)
return item.isType('image')
})
// 【2】刪除分組內的圖片對象
group.removeWithUpdate(img)
// 【3】更新圖片對象的 `src` 指向
img.setSrc('../../images/Bhikkhu.png', () => {
// 【4】將圖片放到分組裡
group.addWithUpdate(img)
// 【5】重新渲染畫布
canvas.renderAll()
})
}
</script>
按這個例子的方式是可以達到目的的,但總覺得不太舒服。
如果你有更好的思路可以分享一下,一起討論學習。
如果你的項目中也需要更改圖片,但又不在以上3種情景中,可以留言,我會嘗試解決。
代碼倉庫
更多推薦
《Fabric.js實現漸變(Gradient)效果,包括徑向漸變radial》
點贊 + 關註 + 收藏 = 學會了