仿写设计编辑器第三天
今天主要完成了头部区域的导入文件,和对画布中的元素的排列方式操作
导入JSON文件
使用Element-ui 的upload上传,在文件上传成功前使用before-upload 拿到上传的文件 使用HTML5的文件解析FileReder(),使用reader.readAsText(file),对文件进行解析,在文件读取成功的钩子onload()后拿到文件读取的结果,拿到读取后的json文件后,下载所需要的font-family 最后使用fabric.js的loadFromJSON()将JSON文件渲染到画布
methods: {
// 上传前拿到文件进行处理
handleUpload(file) {
const reader = new FileReader();
reader.readAsText(file);
reader.onload = () => {
this.jsonFile = reader.result;
};
},
// 插入文件
insertJSON() {
downFontByJSON(this.jsonFile).then(() => {
this.canvas.c.loadFromJSON(
this.jsonFile,
this.canvas.c.renderAll.bind(this.canvas.c)
);
});
},
导入SVG图片
拿到文件的操作与前面相同,读取文件使用的是readAsDataURL()解析文件,然后使用fabric.js的loadSVGFromURL(){其中使用fabric.util.groupSVGElements()组合svg}渲染到画布
methods: {
// 在上传文件前处理文件
handleUpload(file) {
getImgStr(file).then((res) => {
this.svgFile = res;
});
},
// 插入svg文件
insertSVG() {
this.fabric.loadSVGFromURL(this.svgFile, (objects, options) => {
const item = this.fabric.util.groupSVGElements(objects, {
...options,
name: "svg",
id: uuid(),
});
item.scale(0.1);
this.canvas.c.add(item).centerObject(item).renderAll();
});
},
},
导入图片
methods: {
handleUpload(file) {
getImgStr(file).then((res) => {
this.imgFile = res;
});
},
//插入图片
insertImg() {
const imgEle = document.createElement("img");
imgEle.src = this.imgFile;
document.body.appendChild(imgEle);
imgEle.onload = () => {
// 创建图片对象
const imgInstance = new this.fabric.Image(imgEle, {
id: uuid(),
name: "图片1",
left: 100,
top: 100,
});
imgInstance.scale(0.2);
// 添加canvas
this.canvas.c.add(imgInstance);
// 设置图片可缩放
this.canvas.c.setActiveObject(imgInstance);
this.canvas.c.renderAll();
// 删除创建的图片元素
imgEle.remove();
};
},
},
画布里面图片的排列
首先要确定选中的元素是单个还是多个,在util中使用EventEmiter给元素绑定选中和取消选中事件,每次触发事件就调用定义在select.js中的选择事件
//uitil
import EventEmitter from 'events'
class EventHandle extends EventEmitter {
// 初始化绑定事件
init(handler) {
this.handler = handler
this.handler.on("selection:created", (e) => this._selected(e))
this.handler.on("selection:updated", (e) => this._selected(e))
this.handler.on("selection:cleared", (e) => this._selected(e))
}
// 暴露多选事件
_selected(e) {
// getActiveObjects()拿到选中的元素
const actives = this.handler.getActiveObjects()
if (actives && actives.length === 1) {
// 触发选中事件
this.emit('selectOne', actives)
} else if (actives && actives.length > 1) {
this.mSelectMode = 'multiple'
this.emit('selectMultiple', actives)
} else {
this.emit('selectCancel')
}
}
}
export default EventHandle
// 混入 canvas fabric event
export default {
inject: ['canvas', 'fabric', 'event'],
data() {
return {
mSelectMode: '', // one | multiple
mSelectOneType: '', // i-text | group ...
mSelectId: '', // 选择id
mSelectIds: [], // 选择id
}
},
created() {
// 给event实例改在选择事件
this.event.on('selectOne', (e) => {
this.mSelectMode = 'one'
this.mSelectId = e[0].id
this.mSelectOneType = e[0].type
this.mSelectIds = e.map(item => item.id)
})
this.event.on('selectMultiple', (e) => {
this.mSelectMode = 'multiple'
this.mSelectId = ''
this.mSelectIds = e.map(item => item.id)
})
this.event.on('selectCancel', () => {
this.mSelectId = ''
this.mSelectIds = []
this.mSelectMode = ''
this.mSelectOneType = ''
})
},
}
在选中后根据选中的图片是一个还是多个来判断是否显示按钮 点击按钮后先用canvas.getActiveObject()拿到选中的元素,之后再对每个元素的left和top元素进行操作
// 左对齐
alignLeft() {
// 获取选中的元素
const activeObject = this.canvas.c.getActiveObject();
if (activeObject && activeObject.type === "activeSelection") {
const activeSelection = activeObject;
const activeObjectLeft = -(activeObject.width / 2);
activeSelection.forEachObject((item) => {
item.set({
left: activeObjectLeft,
});
// 调用setCoords()才能重新计算控制位置
item.setCoords();
this.canvas.c.renderAll();
});
}
},
// 右对齐
alignRight() {
const activeObject = this.canvas.c.getActiveObject();
if (activeObject && activeObject.type === "activeSelection") {
const activeSelection = activeObject;
const activeObjectLeft = activeObject.width / 2;
activeSelection.forEachObject((item) => {
item.set({
left: activeObjectLeft - item.width * item.scaleX,
});
item.setCoords();
this.canvas.c.renderAll();
});
}
},
// 水平居中对齐
centerHorizontally() {
const activeObject = this.canvas.c.getActiveObject();
if (activeObject && activeObject.type === "activeSelection") {
activeObject.forEachObject((item) => {
item.set({
left: 0 - (item.width * item.scaleX) / 2,
});
item.setCoords();
this.canvas.c.renderAll();
});
}
},
// 垂直居中对齐
verticalCenter() {
const activeObject = this.canvas.c.getActiveObject();
if (activeObject && activeObject.type === "activeSelection") {
activeObject.forEachObject((item) => {
item.set({
top: 0 - (item.width * item.scaleY) / 2,
});
item.setCoords();
this.canvas.c.renderAll();
});
}
},
// 顶部对齐
alignTop() {
const activeObject = this.canvas.c.getActiveObject();
if (activeObject && activeObject.type === "activeSelection") {
const activeObjectTop = -(activeObject.height / 2);
activeObject.forEachObject((item) => {
item.set({
top: activeObjectTop,
});
item.setCoords();
this.canvas.c.renderAll();
});
}
},
// 底部对齐
alingBottom() {
const activeObject = this.canvas.c.getActiveObject();
if (activeObject && activeObject.type === "activeSelection") {
const activeObjectTop = activeObject.height / 2;
activeObject.forEachObject((item) => {
item.set({
top: activeObjectTop - item.height * item.scaleY,
});
item.setCoords();
this.canvas.c.renderAll();
});
}
},
选中元素的旋转
拿到选中的元ji使用cnavas.set(scaleX,-1)进行绕X轴旋转,canvas.set(scaleY,-1),绕Y轴旋转,旋转后要使用cnavas.scale()把元素设置为原来的尺寸
flip(type) {
const activeObject = this.canvas.c.getActiveObject();
console.log(activeObject.type)
activeObject.set("scale" + type, -1).setCoords();
activeObject.scale(0.1);
this.canvas.c.renderAll();
},
合拼或者打散选中的元素
拿到选中的元素,选中类型为mutiple时,使用toGroup()将元素组合在一起,选中类型为one时,使用toActiveSelection()将元素拆解
// 打散组合
unGroup() {
// 先获取对象然后打散
const activeObject = this.canvas.c.getActiveObject().toActiveSelection();
//取消选中
this.canvas.c.discardActiveObject().renderAll();
},
// 组合SVG图片
toGroup() {
const activeObject = this.canvas.c.getActiveObject();
const activeGrounp = activeObject.toGroup();
},
改变选中元素的尺寸
拿到选中的元素后,对canvas.scaleX和canvas.scalexY的值进行加减
// 放大选中的图片
toLarger() {
const activeObject = this.canvas.c.getActiveObject();
activeObject.scaleX += 0.03;
activeObject.scaleY += 0.03;
this.canvas.c.renderAll();
},
// 缩小选中的图片
toSmall(e) {
const activeObject = this.canvas.c.getActiveObject();
activeObject.scaleX -= 0.03;
activeObject.scaleY -= 0.03;
this.canvas.c.renderAll();
},
// 还原选中的图片
toDefault() {
const activeObject = this.canvas.c.getActiveObject();
activeObject.scale(0.1);
this.canvas.c.renderAll();
},