Fabric.js初识及简单使用,使用fabric创建分享海报,保存海报
Fabric.js是一个强大而简单的JavaScript HTML5 Canvas库。Fabric在画布元素之上提供交互式对象模型。Fabric还具有SVG到画布(和画布到SVG)的解析器
环境:
- vite
- vue3
- node v16.19.0
Fabric.js 目前的版本是5.0(2023-06-28),最新的是6.0,本文介绍使用的是6.0版本 "fabric": "6.0.0-beta10"
官网:fabricjs
新版的不同在于引入方式,
import * as fabric from 'fabric'; // v6
import { fabric } from 'fabric'; // v5
本文介绍只会用到Fabric.js中的 Canvas Image Text 类,使用这些即可满足创建海报.基本大步骤如下
1.创建画布
const canvas = new fabric.Canvas(canvasEl.value);
2.加载图片
使用fabric.Image.fromURL
加载图片
canvas.add(img)
将图片添加到画布中
await fabric.Image.fromURL(bg2).then(img => {
const imgWidth = 300;
const imgHeight = 290;
const scaleX = (imgWidth / img.width);
img.set({
scaleX,
scaleY: (imgHeight / img.height),
objectCaching: false,
left: (canvas.width - img.width * scaleX) / 2,
top: 50,
selectable : false,
});
canvas.add(img);
// 下移
canvas.sendObjectBackwards(img) ;
})
3.加载文字
const text = new fabric.Text('英雄联盟直播2023LOL', {
left: canvas.width / 2,
top: 100,
fill: '#333',
stroke: '#333',
fontSize: 14,
textAlign: 'center', // 设置文本居中对齐
originX: 'center', // 设置originX为'center'以使文本以水平中心点为基准
selectable : false,
});
4.保存海报
const saveImg = () => {
const dataUrl = fabric.util.toDataURL(canvasIns.value, 'jpeg', 1);
FileSaver.saveAs(dataUrl, 'qrcode.jpeg');
};
完整代码
<script setup>
import * as fabric from 'fabric'; // v6
import { onMounted, ref, shallowRef } from 'vue';
import QRCode from 'qrcode';
import FileSaver from 'file-saver';
import bg from './assets/share-bg-pc.56c5fc1b.png';
import bg2 from './assets/share-bg1.875eea06.png';
import bg3 from './assets/qr.80ad385f.png';
const canvasEl = ref(null);
const canvasIns = shallowRef();
onMounted(async () => {
const canvas = new fabric.Canvas(canvasEl.value);
canvasIns.value = canvas;
await fabric.Image.fromURL(bg).then(pic => {
pic.set({
// 通过scale来设置图片大小,这里设置和画布一样大
scaleX: canvas.width / pic.width,
scaleY: canvas.height / pic.height,
});
canvas.backgroundImage = pic;
});
await fabric.Image.fromURL(bg2).then(img => {
const imgWidth = 300;
const imgHeight = 290;
const scaleX = (imgWidth / img.width);
img.set({
scaleX,
scaleY: (imgHeight / img.height),
objectCaching: false,
left: (canvas.width - img.width * scaleX) / 2,
top: 50,
selectable : false,
});
canvas.add(img);
// 下移
canvas.sendObjectBackwards(img) ;
})
await fabric.Image.fromURL(bg3).then(img => {
const imgWidth = 126;
const imgHeight = 126;
const scaleX = (imgWidth / img.width);
img.set({
scaleX,
scaleY: (imgHeight / img.height),
objectCaching: false,
// left: (canvas.width - img.width * scaleX) / 2,
left: (canvas.width) / 2,
top: 170,
originX: 'center',
selectable : false,
});
canvas.add(img);
});
const text = new fabric.Text('英雄联盟直播2023LOL', {
left: canvas.width / 2,
top: 100,
fill: '#333',
stroke: '#333',
fontSize: 14,
textAlign: 'center', // 设置文本居中对齐
originX: 'center', // 设置originX为'center'以使文本以水平中心点为基准
selectable : false,
});
canvas.add(text);
canvas.bringObjectForward(text)
QRCode.toDataURL('I am a pony!', function(err, url) {
const i = new Image();
i.src = url;
i.width = 120;
i.height = 120;
const qrImg = new fabric.Image(i);
const imgWidth = 120;
const imgHeight = 120;
const scaleX = (imgWidth / qrImg.width);
qrImg.set({
scaleX,
scaleY: (imgHeight / qrImg.height),
objectCaching: false,
left: (canvas.width - qrImg.width * scaleX) / 2,
top: 174,
selectable : false,
});
canvas.add(qrImg);
// 上移
canvas.bringObjectForward(qrImg)
});
});
const saveImg = () => {
const dataUrl = fabric.util.toDataURL(canvasIns.value, 'jpeg', 1);
FileSaver.saveAs(dataUrl, 'qrcode.jpeg');
};
</script>
<template>
<div class="min-h-screen flex flex-col justify-center items-center">
<canvas width="400" height="420" class="" ref="canvasEl" />
<button @click="saveImg" class="mt-6 px-4 py-2 bg-blue-300/70 border-2 border-blue-400 rounded-lg">save</button>
</div>
</template>
<style scoped>
</style>