圖片上傳
使用了element-plus提供的圖片上傳el-upload
組件
<el-upload :show-file-list="false" :auto-upload="false" :on-change="(e) => uploadImage(e, 'background')" >
<button class="right-canvas-resize-btn">上傳圖片</button>
</el-upload>?
圖片上傳支持兩種元素,普通圖片元素和背景圖片元素,所以定義屬性type進(jìn)行區(qū)分
type為Image
為普通圖片, background
為背景
背景也是一張圖片,使用fabric.Image創(chuàng)建圖片元素
因?yàn)闆]有圖片服務(wù)器所以把上傳的文件轉(zhuǎn)換了base64圖片,作為fabric圖片的鏈接
需要區(qū)分上傳類型type
, 不同類型的圖片走不同邏輯
fileUpload = async (file: File, name: string, type: string) => {
const src = await this.handler.utils.fileToBase64(file);
if (src) {
const image = new Image();
image.src = src;
const options: any = {
name,
type,
src,
};
await new Promise((resolve) => {
image.onload = () => {
options.width = image.width;
options.height = image.height;
resolve(true);
};
});
let marterialObject;
if (type == "background") {
marterialObject = this.handler.workareaHandler.setBgImage(options);
} else {
marterialObject = this.handler.add(options);
}
return marterialObject;
}
}
背景設(shè)置原理
背景圖片和普通圖片的區(qū)別
- 不能選中,不能移動,不能修改,沒有操作控件
給背景元素添加以下屬性
hasControls: false,
hasBorders: false,
selectable: false,
lockMovementX: true,
lockMovementY: true,
lockScalingX: true,
lockScalingY: true
- 背景需要自適應(yīng)畫布
計(jì)算規(guī)則如下
- 獲取寬高比例最大值作為元素縮放值,目的是圖片元素保持寬高比例不變的情況下覆蓋畫布
- 根據(jù)縮放值計(jì)算圖片最新寬高,需要基于畫布居中展示
- 水平居中規(guī)則如下,垂直居中同理
_getBgPosition(bgObject: FabricImage | any) {
const { width, height } = this.workspace as any;
let scale = 1;
if (width > bgObject.width || height > bgObject.height) {
if (width / bgObject.width > height / bgObject.height) {
scale = width / bgObject.width;
} else {
scale = height / bgObject.height;
}
}
// 居中
const bgHeight = bgObject.height * scale;
const bgWidth = bgObject.width * scale;
const bgLeft = width / 2 - bgWidth / 2;
const bgTop = height / 2 - bgHeight / 2;
return {
left: bgLeft,
top: bgTop,
scaleX: scale,
scaleY: scale,
}
- 背景圖片支持修改,所以上傳時(shí)需要把畫布中的背景元素給移除
// 獲取背景元素
getBgObject() {
return this.handler.canvas.getObjects().find((item: any) => {
if (item.type == "background") {
return item;
}
});
}
// 去重, 防止出現(xiàn)多個背景元素
const bgObject = this.getBgObject();
if (bgObject && bgObject.src !== src) {
this.handler.canvas.remove(bgObject);
}
- 背景元素永遠(yuǎn)置底,但比畫布高一層,所以先置底再上移一層
this.canvas.sendToBack(this.bgObject);
this.canvas.bringForward(this.bgObject);
- 畫布中有元素層級的邏輯,所以當(dāng)我們選中某個元素的時(shí)候需要保持原有層級,但是fabric.js默認(rèn)是對象在選中時(shí)不保持在當(dāng)前堆棧位置
所以我們需要在初始化畫布時(shí)指定保留層級
preserveObjectStacking: true
完整代碼如下
async setBgImage(options: WorkareaOption) {
const { src } = options || {};
const editable = false;
const option = {
editable,
hasControls: editable,
hasBorders: editable,
selectable: editable,
lockMovementX: !editable,
lockMovementY: !editable,
lockScalingX: !editable,
lockScalingY: !editable,
hoverCursor: "default",
name: "背景圖片",
type: "background",
src,
};
// 去重, 防止出現(xiàn)多個背景元素
const bgObject = this.getBgObject();
if (bgObject && bgObject.src !== src) {
this.handler.canvas.remove(bgObject);
}
const poiOptions = this._getBgPosition(options);
const newOptions = Object.assign({}, option, poiOptions);
this.bgObject = await this.handler.add(newOptions, false);
if (this.bgObject) {
this.canvas.add(this.bgObject);
this.canvas.sendToBack(this.bgObject);
this.canvas.bringForward(this.bgObject);
}
this.canvas.requestRenderAll();
return this.bgObject;
}
背景的翻轉(zhuǎn)、分離、刪除
支持背景圖片的翻轉(zhuǎn)、分離、刪除
翻轉(zhuǎn)
修改背景元素的scaleX屬性,默認(rèn)為水平翻轉(zhuǎn){ scaleX: -1 }
分離
修改背景元素為圖片元素
-
type
修改為Image
- 支持選中,移動,修改,有操作控件, 把上文的
hasControls
等字段取反即可
刪除
基于fabric提供的刪除方法 this.canvas.remove(target);
簡介
vue-design-editor
是仿搞定設(shè)計(jì)的一款開源圖片編輯器, 支持多種格式的導(dǎo)入,包括png、jpg、gif、mp4, 也可以一鍵psd轉(zhuǎn)模板(后續(xù)開發(fā))
github地址 預(yù)覽文章來源地址http://www.zghlxwxcb.cn/news/detail-783279.html
上個開源庫是 vue-form-design
基于Vue3的可視化表單設(shè)計(jì)器,拖拽式操作讓你快速構(gòu)建一個表單, 讓表單開發(fā)簡單而高效。文章來源:http://www.zghlxwxcb.cn/news/detail-783279.html
github地址 預(yù)覽
到了這里,關(guān)于基于fabric.js的圖片編輯器, 畫布背景實(shí)現(xiàn)原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!