Fabric.js 簡介
Fabric.js
是一個功能強大且操作簡單的Javascript HTML5 canvas
工具庫。
如果你需要用 canvas
做特效,那我推薦你使用 Fabric.js
,因爲 Fabric.js
語法更加簡單易用,而且還提供了很多交互類的 api
。
Fabric.js
簡化了很多 Canvas
裏的概念,代碼看上去也更加語義化。
Fabric.js
能做什麼?
可以打開 『Fabric.js 官網首頁』 直接看例子,也可以看看 『Fabric.js Demos』 查看更炫酷的例子。
本文簡介
本文主要講解 Fabric
提供的基礎 畫布 操作,包含一下內容
- 安裝
Fabric.js
- 畫布基礎版(可交互)
- 不可交互的畫布
- 在
js
設置畫布參數 - 使用背景圖
- 旋轉背景圖
- 拉伸背景圖
- 重複背景圖
- 重疊影像
本文在案例在 Vue3
環境下使用,不懂 Vue3
也沒關係,因爲不會涉及多少 Vue
的知識。
相關鏈接
動手!
安裝 Fabric.js
CDN
<script src="https://unpkg.com/[email protected]/dist/fabric.min.js"></script>
npm
npm i fabric --save
基礎版(可交互)
基礎版就是“起步”章節所說的那個例子。
<template>
<canvas width="400" height="400" id="canvas" style="border: 1px solid #ccc;"></canvas>
</template>
<script setup>
import { onMounted } from 'vue'
import { fabric } from 'fabric' // 引入 fabric
function init() {
const canvas = new fabric.Canvas('canvas') // 這裏傳入的是canvas元素的id
// 創建一個長方形
const rect = new fabric.Rect({
top: 100, // 距離容器頂部 100px
left: 100, // 距離容器左側 100px
width: 30, // 矩形寬度 30px
height: 30, // 矩形高度 30px
fill: 'red' // 填充 紅色
})
canvas.add(rect) // 將矩形添加到 canvas 畫布裏
}
onMounted(() => {
init()
})
</script>
不可交互
<template>
<canvas width="400" height="400" id="canvas" style="border: 1px solid #ccc;"></canvas>
</template>
<script setup>
import { onMounted } from 'vue'
import { fabric } from 'fabric' // 引入 fabric
function init() {
// 使用 StaticCanvas 創建一個不可操作的畫布
const canvas = new fabric.StaticCanvas('canvas') // 這裏傳入的是canvas元素的id
// 創建一個長方形
const rect = new fabric.Rect({
top: 100, // 距離容器頂部 100px
left: 100, // 距離容器左側 100px
width: 30, // 矩形寬度 30px
height: 30, // 矩形高度 30px
fill: 'red' // 填充 紅色
})
canvas.add(rect) // 將矩形添加到 canvas 畫布裏
}
onMounted(() => {
init()
})
</script>
創建不可交互的畫布,其實只需把 new fabric.Canvas
改成 new fabric.StaticCanvas
即可。
在js設定畫布參數
<template>
<canvas id="canvas"></canvas>
</template>
<script setup>
import { onMounted } from 'vue'
import { fabric } from 'fabric' // 引入 fabric
function init() {
const canvas = new fabric.Canvas('canvas', {
width: 300, // 畫布寬度
height: 300, // 畫布高度
backgroundColor: '#eee' // 畫布背景色
})
// 圓形
const circle = new fabric.Circle({
radius: 30, // 圓的半徑
top: 20, // 距離容器頂部 20px
left: 20, // 距離容器左側 20px
fill: 'pink' // 填充 粉色
})
canvas.add(circle) // 將圓形添加到 canvas 畫布裏
}
onMounted(() => {
init()
})
</script>
new fabric.Canvas
的第二個參數是用來設置畫布基礎功能的。更多配置參數可以查看 『官方文檔』。
使用背景圖
<template>
<canvas width="400" height="400" id="canvas" style="border: 1px solid #ccc;"></canvas>
</template>
<script setup>
import { onMounted } from 'vue'
import { fabric } from 'fabric'
function init() {
const canvas = new fabric.Canvas('canvas')
// 設置背景圖
// 參數1:背景圖資源(可以引入本地,也可以使用網絡圖)
// 參數2:設置完背景圖執行以下重新渲染canvas的操作,這樣背景圖就會展示出來了
canvas.setBackgroundImage(
'https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/27d1b4e5f8824198b6d51a2b1c2d0d75~tplv-k3u1fbpfcp-zoom-crop-mark:400:400:400:400.awebp',
canvas.renderAll.bind(canvas)
)
}
onMounted(() => {
init()
})
</script>
setBackgroundImage
這個很好懂,設置背景圖片。
需要注意的是,在 Fabric.js
裏使用 gif
只會渲染第一幀。
旋轉背景圖
<template>
<canvas width="400" height="400" id="canvas" style="border: 1px solid #ccc;"></canvas>
</template>
<script setup>
import { onMounted } from 'vue'
import { fabric } from 'fabric'
function init() {
const canvas = new fabric.Canvas('canvas')
// 設置背景圖
// 參數1:背景圖資源(可以引入本地,也可以使用網絡圖)
// 參數2:設置完背景圖執行以下重新渲染canvas的操作,這樣背景圖就會展示出來了
canvas.setBackgroundImage(
'https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/27d1b4e5f8824198b6d51a2b1c2d0d75~tplv-k3u1fbpfcp-zoom-crop-mark:400:400:400:400.awebp',
canvas.renderAll.bind(canvas),
{
angle: 15 // 旋轉背景圖
}
)
}
onMounted(() => {
init()
})
</script>
setBackgroundImage
還有第三個參數,嘿嘿嘿沒想到吧
第三個參數除了旋轉,還可以設置 scaleX
、scaleY
之類的操作。
更多設置可以查看 『文檔』 。
但這個例子存在一個問題,如果圖片的尺寸沒 canvas
容器大,就填不滿,否則就溢出(只顯示圖片的局部)。
解決方案請看下一個案例。
拉伸背景圖
<template>
<canvas width="400" height="400" id="canvas" style="border: 1px solid #ccc;"></canvas>
</template>
<script setup>
import { onMounted } from 'vue'
import { fabric } from 'fabric'
function init() {
const canvas = new fabric.Canvas('canvas')
// fabric.Image.fromURL:加載圖片的api
// 第一個參數:圖片地址(可以是本地的,也可以是網絡圖)
// 第二個參數:圖片加載的回調函數
fabric.Image.fromURL(
'https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/27d1b4e5f8824198b6d51a2b1c2d0d75~tplv-k3u1fbpfcp-zoom-crop-mark:400:400:400:400.awebp',
(img) => {
// 設置背景圖
canvas.setBackgroundImage(
img,
canvas.renderAll.bind(canvas),
{
scaleX: canvas.width / img.width, // 計算出圖片要拉伸的寬度
scaleY: canvas.height / img.height // 計算出圖片要拉伸的高度
}
)
}
)
}
onMounted(() => {
init()
})
</script>
這個例子使用了 fabric.Image.fromURL
這個 api
來加載圖片,第一個參數是圖片地址,第二個參數是回調函數。
拿到圖片的參數和畫布的寬高進行計算,從而使圖片充滿全屏。
重複背景圖
<template>
<canvas width="400" height="400" id="canvas" style="border: 1px solid #ccc;"></canvas>
</template>
<script setup>
import { onMounted } from 'vue'
import { fabric } from 'fabric'
function init() {
const canvas = new fabric.Canvas('canvas')
canvas.setBackgroundColor({
source: 'https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/27d1b4e5f8824198b6d51a2b1c2d0d75~tplv-k3u1fbpfcp-zoom-crop-mark:40:40:40:40.awebp',
repeat: 'repeat'
}, canvas.renderAll.bind(canvas))
}
onMounted(() => {
init()
})
</script>
這個例子使用的圖片尺寸是比較小的,所以在 setBackgroundColor
的第3個參數中設置了 repeat: 'repeat'
,表示重複渲染圖片。
重疊影象
<template>
<canvas width="400" height="375" id="canvas" style="border: 1px solid #ccc;"></canvas>
</template>
<script setup>
import { onMounted } from 'vue'
import { fabric } from 'fabric'
import jailCellBars from '@/assets/images/jail_cell_bars.png' // 引入背景圖
function init() {
const canvas = new fabric.Canvas('canvas')
canvas.add(
new fabric.Circle({
radius: 30, // 圓形半徑
fill: '#f55',
top: 70,
left: 70
})
)
// 設置覆蓋圖像的畫布
canvas.setOverlayImage( // setOverlayImage(image, callback, optionsopt)
jailCellBars, // 圖片,script開頭import進來的
canvas.renderAll.bind(canvas)
)
}
onMounted(() => {
init()
})
</script>
值得注意的2點:
- 使用
canvas.setOverlayImage
代替原本的canvas.setBackgroundImage
。 - 所使用的圖片最好是帶透明層的
png
,這樣就能展示案例所示的效果,背景圖疊在圖案元素上面。