<template>
|
<div>
|
<el-divider content-position="left">基础要素</el-divider>
|
<div class="tool-box">
|
<span @click="() => addText()" :draggable="true" @dragend="addText">
|
<textIcon width="26" height="26"></textIcon>
|
</span>
|
<span @click="() => addTextBox()" :draggable="true" @dragend="addTextBox">
|
<textBoxIcon width="26" height="26"></textBoxIcon>
|
</span>
|
<span @click="() => addRect()" :draggable="true" @dragend="addRect">
|
<rectIcon width="26" height="26"></rectIcon>
|
</span>
|
<span @click="() => addCircle()" :draggable="true" @dragend="addCircle">
|
<circleIcon width="26" height="26"></circleIcon>
|
</span>
|
<span @click="() => addTriangle()" :draggable="true" @dragend="addTriangle">
|
<triangleIcon width="26" height="26"></triangleIcon>
|
</span>
|
|
<span @click="() => addPolygon()" :draggable="true" @dragend="addPolygon">
|
<polygonIcon width="26" height="26"></polygonIcon>
|
</span>
|
</div>
|
</div>
|
</template>
|
|
<script setup name="Tools">
|
import { getPolygonVertices } from '@/fabric-editor/utils/math';
|
import useSelect from '@/fabric-editor/hooks/select';
|
import circleIcon from '@/fabric-editor/assets/icon/tools/circle.svg?component';
|
// import draw1Icon from '@/assets/icon/tools/draw1.svg';
|
// import draw2Icon from '@/assets/icon/tools/draw2.svg';
|
// import draw3Icon from '@/assets/icon/tools/draw3.svg';
|
// import draw4Icon from '@/assets/icon/tools/draw4.svg';
|
|
import polygonIcon from '@/fabric-editor/assets/icon/tools/polygon.svg?component';
|
import rectIcon from '@/fabric-editor/assets/icon/tools/rect.svg?component';
|
import textIcon from '@/fabric-editor/assets/icon/tools/text.svg?component';
|
import textBoxIcon from '@/fabric-editor/assets/icon/tools/textBox.svg?component';
|
import triangleIcon from '@/fabric-editor/assets/icon/tools/triangle.svg?component';
|
|
// import qrCodeIcon from '@/assets/icon/tools/qrCode.svg';
|
// import barCodeIcon from '@/assets/icon/tools/barCode.svg';
|
|
// import useCalculate from '@/hooks/useCalculate';
|
// const { getCanvasBound, isOutsideCanvas } = useCalculate();
|
|
const LINE_TYPE = {
|
polygon: 'polygon',
|
freeDraw: 'freeDraw',
|
pathText: 'pathText',
|
};
|
// 默认属性
|
const defaultPosition = { shadow: '', fontFamily: 'arial' };
|
|
const { fabric, canvasEditor } = useSelect();
|
const state = reactive({
|
isDrawingLineMode: false,
|
lineType: false,
|
});
|
|
const addText = (event) => {
|
cancelDraw();
|
const text = new fabric.IText('万事大吉', {
|
...defaultPosition,
|
fontSize: 40,
|
fill: '#000000FF',
|
});
|
|
console.log('canvasEditor: ', canvasEditor);
|
canvasEditor.addBaseType(text, { center: true, event });
|
};
|
|
const addTextBox = (event) => {
|
cancelDraw();
|
const text = new fabric.Textbox('诸事顺遂', {
|
...defaultPosition,
|
splitByGrapheme: true,
|
width: 400,
|
fontSize: 80,
|
fill: '#000000FF',
|
});
|
|
canvasEditor.addBaseType(text, { center: true, event });
|
};
|
|
const addTriangle = (event) => {
|
cancelDraw();
|
const triangle = new fabric.Triangle({
|
...defaultPosition,
|
width: 400,
|
height: 400,
|
fill: '#92706BFF',
|
name: '三角形',
|
});
|
canvasEditor.addBaseType(triangle, { center: true, event });
|
};
|
|
const addPolygon = (event) => {
|
cancelDraw();
|
const polygon = new fabric.Polygon(getPolygonVertices(5, 200), {
|
...defaultPosition,
|
fill: '#CCCCCCFF',
|
name: '多边形',
|
});
|
polygon.set({
|
// 创建完设置宽高,不然宽高会变成自动的值
|
width: 400,
|
height: 400,
|
// 关闭偏移
|
pathOffset: {
|
x: 0,
|
y: 0,
|
},
|
});
|
canvasEditor.addBaseType(polygon, { center: true, event });
|
};
|
|
const addCircle = (event) => {
|
cancelDraw();
|
const circle = new fabric.Circle({
|
...defaultPosition,
|
radius: 150,
|
fill: '#57606BFF',
|
// id: uuid(),
|
name: '圆形',
|
});
|
canvasEditor.addBaseType(circle, { center: true, event });
|
};
|
|
const addRect = (event) => {
|
cancelDraw();
|
const rect = new fabric.Rect({
|
...defaultPosition,
|
fill: '#F57274FF',
|
width: 400,
|
height: 400,
|
name: '矩形',
|
});
|
|
canvasEditor.addBaseType(rect, { center: true, event });
|
};
|
const drawPolygon = () => {
|
const onEnd = () => {
|
state.lineType = false;
|
state.isDrawingLineMode = false;
|
ensureObjectSelEvStatus(!state.isDrawingLineMode, !state.isDrawingLineMode);
|
};
|
if (state.lineType !== LINE_TYPE.polygon) {
|
endConflictTools();
|
endDrawingLineMode();
|
state.lineType = LINE_TYPE.polygon;
|
state.isDrawingLineMode = true;
|
canvasEditor.beginDrawPolygon(onEnd);
|
canvasEditor.endDraw();
|
ensureObjectSelEvStatus(!state.isDrawingLineMode, !state.isDrawingLineMode);
|
} else {
|
canvasEditor.discardPolygon();
|
}
|
};
|
|
const drawPathText = () => {
|
if (state.lineType === LINE_TYPE.pathText) {
|
state.lineType = false;
|
state.isDrawingLineMode = false;
|
canvasEditor.endTextPathDraw();
|
} else {
|
endConflictTools();
|
endDrawingLineMode();
|
state.lineType = LINE_TYPE.pathText;
|
state.isDrawingLineMode = true;
|
canvasEditor.startTextPathDraw();
|
}
|
};
|
|
const freeDraw = () => {
|
if (state.lineType === LINE_TYPE.freeDraw) {
|
canvasEditor.endDraw();
|
state.lineType = false;
|
state.isDrawingLineMode = false;
|
} else {
|
endConflictTools();
|
endDrawingLineMode();
|
state.lineType = LINE_TYPE.freeDraw;
|
state.isDrawingLineMode = true;
|
canvasEditor.startDraw({ width: 20 });
|
}
|
};
|
|
const endConflictTools = () => {
|
canvasEditor.discardPolygon();
|
canvasEditor.endDraw();
|
canvasEditor.endTextPathDraw();
|
};
|
const endDrawingLineMode = () => {
|
state.isDrawingLineMode = false;
|
state.lineType = '';
|
canvasEditor.setMode(state.isDrawingLineMode);
|
canvasEditor.setLineType(state.lineType);
|
};
|
const drawingLineModeSwitch = (type) => {
|
if ([LINE_TYPE.polygon, LINE_TYPE.freeDraw, LINE_TYPE.pathText].includes(state.lineType)) {
|
endConflictTools();
|
}
|
if (state.lineType === type) {
|
state.isDrawingLineMode = false;
|
state.lineType = '';
|
} else {
|
state.isDrawingLineMode = true;
|
state.lineType = type;
|
}
|
canvasEditor.setMode(state.isDrawingLineMode);
|
canvasEditor.setLineType(type);
|
// this.canvasEditor.setMode(this.isDrawingLineMode);
|
// this.canvasEditor.setArrow(isArrow);
|
ensureObjectSelEvStatus(!state.isDrawingLineMode, !state.isDrawingLineMode);
|
};
|
|
const ensureObjectSelEvStatus = (evented, selectable) => {
|
canvasEditor.canvas.forEachObject((obj) => {
|
if (obj.id !== 'workspace') {
|
obj.selectable = selectable;
|
obj.evented = evented;
|
}
|
});
|
};
|
|
// 退出绘制状态
|
const cancelDraw = () => {
|
if (!state.isDrawingLineMode) return;
|
state.isDrawingLineMode = false;
|
state.lineType = '';
|
canvasEditor.setMode(false);
|
endConflictTools();
|
ensureObjectSelEvStatus(true, true);
|
};
|
|
onDeactivated(() => {
|
cancelDraw();
|
});
|
</script>
|
|
<style scoped lang="scss">
|
@use '@/style/common.scss' as *;
|
|
.tool-box {
|
display: flex;
|
justify-content: space-around;
|
|
span {
|
margin-left: 2px;
|
padding: 5px 0;
|
text-align: center;
|
background: #f6f6f6;
|
flex: 1;
|
cursor: pointer;
|
|
&:hover {
|
background: #edf9ff;
|
|
svg {
|
fill: getCssVar('color', 'primary');
|
}
|
}
|
}
|
|
.bg {
|
background: #d8d8d8;
|
|
&:hover {
|
svg {
|
fill: getCssVar('color', 'primary');
|
}
|
}
|
}
|
}
|
|
.img {
|
width: 20px;
|
}
|
</style>
|