通过鼠标点击 然后放开鼠标 移动会生成正方形的轮廓 再次点击会生成正方形 求解
你好,我是有问必答小助手。为了技术专家团更好地为您解答问题,烦请您补充下(1)问题背景详情,(2)您想解决的具体问题,(3)问题相关代码图片或者报错信息。便于技术专家团更好地理解问题,并给出解决方案。
您可以点击问题下方的【编辑】,进行补充修改问题。
<script>
import { fabric} from 'fabric';
var pointArray=[];
export default {
name: "Fabric",
data() {
return {
width: 800,
height: 550,
rect: [],
canvas: {},
showMenu: false,
x: "",
y: "",
z:"",
t:"",
mouseFrom: {},
mouseTo: {},
drawType: null, //当前绘制图像的种类
canvasObjectIndex: 0,
textbox: null,
rectangleLabel: "warning",
drawWidth: 2, //笔触宽度
color: "#E34F51", //画笔颜色
drawingObject: null, //当前绘制对象
moveCount: 1, //绘制移动计数器
doDrawing: false, // 绘制状态
//polygon 相关参数
polygonMode: false,
pointArray: [],
lineArray: [],
activeShape: false,
activeLine: "",
line: {},
,
delectKlass: {},
imgFile: {},
imgSrc: "",
defaultProps: {
children: 'children',
label: 'label'
}
};
},
watch: {
drawType() {
this.canvas.selection = !this.drawType;
},
width() {
this.canvas.setWidth(this.width)
},
height() {
this.canvas.setHeight(this.height)
},
},
methods: {
// 保存当前画布为png图片
save() {
var canvas = document.getElementById('canvas')
this.downFile(canvas)
},
saveFile(data, filename) {
var save_link = document.createElement('a');
save_link.href = data;
save_link.download = filename;
var event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
save_link.dispatchEvent(event);
},
// 开始绘制时,指定绘画种类
drawTypeChange(e) {
this.drawType = e;
this.canvas.skipTargetFind = !!e
if (e == "pen") {
// isDrawingMode为true 才可以自由绘画
this.canvas.isDrawingMode = true;
} else {
this.canvas.isDrawingMode = false;
}
},
ondel(){
console.log('1111')
this.deleteObj();
this.canvas.remove
this.canvas.getObjects()[this.canvas.getObjects().length - 1]
},
// 鼠标按下时触发
mousedown(e) {
// 记录鼠标按下时的坐标
var xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);
this.mouseFrom.x = xy.x;
this.mouseFrom.y = xy.y;
this.doDrawing = true;
if (this.drawType == "text") {
this.drawing();
}
if (this.textbox) {
this.textbox.enterEditing();
this.textbox.hiddenTextarea.focus();
}
// 绘制多边形
if (this.drawType == "polygon") {
this.canvas.skipTargetFind = false;
try {
// 此段为判断是否闭合多边形,点击红点时闭合多边形
if (this.pointArray.length > 1) {
// e.target.id == this.pointArray[0].id 表示点击了初始红点
if (e.target && e.target.id == this.pointArray[0].id) {
this.generatePolygon();
}
}
//未点击红点则继续作画
if (this.polygonMode) {
this.addPoint(e);
}
} catch (error) {
console.log(error);
}
}
if(this.drawType == "pentagram"){
this.pentagram.top=xy.y
this.pentagram.left=xy.x
this.mouseups()
}
},
'selection:created': (e)=>{
if (e.target._objects) {
//多选删除
var etCount = e.target._objects.length;
for (var etindex = 0; etindex < etCount; etindex++) {
this.fabricObj.remove(e.target._objects[etindex]);
}
} else {
//单选删除
this.fabricObj.remove(e.target);
}
this.fabricObj.discardActiveObject(); //清楚选中框
this.updateModifications(true)
},
// 鼠标松开执行
mouseup(e) {
var xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);
this.mouseTo.x = xy.x;
this.mouseTo.y = xy.y;
pointArray.push({
x:xy.x,
y:xy.y,
})
this.drawingObject = null;
if (this.drawType != "polygon") {
this.doDrawing = false;
}
},
mouseups(e) {
var xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);
this.mouseTo.x = xy.x;
this.mouseTo.y = xy.y;
pointArrays.push({
x:xy.x,
y:xy.y,
})
this.drawingObject = null;
if (this.drawType != "pentagram") {
this.doDrawing = false;
}
this.canvas.renderAll();
},
//鼠标移动过程中已经完成了绘制
mousemove(e) {
if (this.moveCount % 2 && !this.doDrawing) {
//减少绘制频率
return;
}
this.moveCount++;
var xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);
this.mouseTo.x = xy.x;
this.mouseTo.y = xy.y;
// 多边形与文字框特殊处理
if (this.drawType != "text" || this.drawType != "polygon" ) {
this.drawing(e);
}
if (this.drawType == "polygon") {
if (this.activeLine && this.activeLine.class == "line") {
var pointer = this.canvas.getPointer(e.e);
this.activeLine.set({ x2: pointer.x, y2: pointer.y });
var points = this.activeShape.get("points");
points[this.pointArray.length] = {
x: pointer.x,
y: pointer.y,
zIndex: 1
};
this.activeShape.set({
points: points
});
this.canvas.renderAll();
}
this.canvas.renderAll();
}
},
deleteObj() {
this.canvas.getActiveObjects().map(item => {
this.canvas.remove(item);
});
},
transformMouse(mouseX, mouseY) {
return { x: mouseX / 1, y: mouseY / 1 };
},
// 绘制多边形开始,绘制多边形和其他图形不一样,需要单独处理
drawPolygon() {
this.drawType = "polygon";
this.polygonMode = true;
//这里画的多边形,由顶点与线组成
this.pointArray = new Array(); // 顶点集合
this.lineArray = new Array(); //线集合
this.canvas.isDrawingMode = false;
},
pentagram() {
this.drawType = "pentagram";
this.polygonMode = true;
//这里画的多边形,由顶点与线组成
this.pointer = new Array(); // 顶点集合
this.lineArray = new Array(); //线集合
this.canvas.isDrawingMode = false;
},
addPoint(e) {
var random = Math.floor(Math.random() * 10000);
var id = new Date().getTime() + random;
var circle = new fabric.Circle({
radius: 5,
fill: "#ffffff",
stroke: "#333333",
strokeWidth: 0.5,
left: (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
top: (e.pointer.y || e.e.layerY) / this.canvas.getZoom(),
selectable: false,
hasBorders: false,
hasControls: false,
originX: "center",
originY: "center",
id: id,
objectCaching: false
});
if (this.pointArray.length == 0) {
circle.set({
fill: "red"
});
}
var points = [
(e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
(e.pointer.y || e.e.layerY) / this.canvas.getZoom(),
(e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
(e.pointer.y || e.e.layerY) / this.canvas.getZoom()
];
this.line = new fabric.Line(points, {
strokeWidth: 2,
fill: "#999999",
stroke: "#999999",
class: "line",
originX: "center",
originY: "center",
selectable: false,
hasBorders: false,
hasControls: false,
evented: false,
objectCaching: false
});
if (this.activeShape) {
var pos = this.canvas.getPointer(e.e);
var points = this.activeShape.get("points");
points.push({
x: pos.x,
y: pos.y
});
var polygon = new fabric.Polygon(points, {
stroke: "#333333",
strokeWidth: 1,
fill: "#cccccc",
opacity: 0.3,
selectable: false,
hasBorders: false,
hasControls: false,
evented: false,
objectCaching: false
});
this.canvas.remove(this.activeShape);
this.canvas.add(polygon);
this.activeShape = polygon;
this.canvas.renderAll();
} else {
var polyPoint = [
{
x: (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),
y: (e.pointer.y || e.e.layerY) / this.canvas.getZoom()
}
];
var polygon = new fabric.Polygon(polyPoint, {
stroke: "#333333",
strokeWidth: 1,
fill: "#cccccc",
opacity: 0.5,
selectable: false,
hasBorders: false,
hasControls: false,
evented: false,
objectCaching: false
});
this.activeShape = polygon;
this.canvas.add(polygon);
}
this.activeLine = this.line;
this.pointArray.push(circle);
this.lineArray.push(this.line);
this.canvas.add(this.line);
this.canvas.add(circle);
},
generatePolygon() {
var points = new Array();
this.pointArray.map((point, index) => {
points.push({
x: point.left,
y: point.top
});
this.canvas.remove(point);
});
this.lineArray.map((line, index) => {
this.canvas.remove(line);
});
this.canvas.remove(this.activeShape).remove(this.activeLine);
var polygon = new fabric.Polygon(points, {
stroke: this.color,
strokeWidth: this.drawWidth,
fill: "rgba(255, 255, 255, 0)",
opacity: 1,
hasBorders: true,
hasControls: false
});
this.canvas.add(polygon);
this.activeLine = null;
this.activeShape = null;
this.polygonMode = false;
this.doDrawing = false;
this.drawType = null;
},
drawing(e) {
if (this.drawingObject) {
this.canvas.remove(this.drawingObject);
}
var canvasObject = null;
var left = this.mouseFrom.x,
top = this.mouseFrom.y,
mouseFrom = this.mouseFrom,
mouseTo = this.mouseTo;
switch (this.drawType) {
case "rectangle": //长方形
// 按shift时画正方型
if (e.e.shiftKey) {
mouseTo.x - left > mouseTo.y - top ? mouseTo.y = top + mouseTo.x - left : mouseTo.x = left + mouseTo.y - top
}
var path =
"M " +
mouseFrom.x +
" " +
mouseFrom.y +
" L " +
mouseTo.x +
" " +
mouseFrom.y +
" L " +
mouseTo.x +
" " +
mouseTo.y +
" L " +
mouseFrom.x +
" " +
mouseTo.y +
" L " +
mouseFrom.x +
" " +
mouseFrom.y +
" z";
canvasObject = new fabric.Path(path, {
left: left,
top: top,
stroke: this.color,
strokeWidth: this.drawWidth,
fill: "rgba(255, 255, 255, 0)",
hasControls: false
});
//也可以使用fabric.Rect
break;
case "text": //文本框
this.textbox = new fabric.Textbox("", {
left: mouseFrom.x,
top: mouseFrom.y - 10,
// width: 150,
fontSize: 16,
borderColor: this.color,
fill: this.color,
hasControls: false
});
this.canvas.add(this.textbox);
this.textbox.enterEditing();
this.textbox.hiddenTextarea.focus();
break;
default:
break;
case "del":
this.drawingObject.selection = true
this.drawingObject.skipTargetFind = false
this.drawingObject.selectable = true
break;
}
if (canvasObject) {
// canvasObject.index = getCanvasObjectIndex();\
this.canvas.add(canvasObject); //.setActiveObject(canvasObject)
this.drawingObject = canvasObject;
}
},
transferred(data) {
return data.replace(/<br>/g, "\r\n").replace(/>/g, ">");
},
downFile(){
let fileName = Date.now() + "point.json";
var columnDelimiter = ","; //列分割符
var lineDelimiter = "\r\n"; //行分割符
let result = "";// 最终结果的字符串
var ths=[
"label"
,"abc"
,"ab1c",
]
for (let i = 0, l = ths.length; i < l; i++) {
result +=
this.transferred('"' + ths[i] + '"') + columnDelimiter;//每一列用逗号分隔
}
result += lineDelimiter;// 每一行使用"\r\n"分隔
var trs = pointArray;
for (let i = 0, l = trs.length; i < l; i++) {
result +=
this.transferred('"' + trs[i].x + '"') + columnDelimiter
+ this.transferred('"' + trs[i].y + '"') + columnDelimiter
result += lineDelimiter;
}
var blob = new Blob(["\uFEFF" + result], { type: "text/json;" });//记得将编码格式设置一下,避免最终下载的文件出现乱码
var downloadLink = document.createElement("a");
if ("download" in downloadLink) {
var url = URL.createObjectURL(blob);
downloadLink.href = url;
downloadLink.download = fileName;
downloadLink.hidden = true;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
} else {
if (navigator.msSaveBlob) {
//IE10+
navigator.msSaveBlob(blob, fileName);
}
}
}
},
mounted() {
this.canvas = new fabric.Canvas("canvas", {
// skipTargetFind: false, //当为真时,跳过目标检测。目标检测将返回始终未定义。点击选择将无效
// selectable: false, //为false时,不能选择对象进行修改
// selection: false // 是否可以多个对象为一组
});
this.canvas.selectionColor = "rgba(0,0,0,0.05)";
this.canvas.on("mouse:down", this.mousedown);
this.canvas.on("mouse:move", this.mousemove);
this.canvas.on("mouse:up", this.mouseup);
document.onkeydown = e => {
// 键盘 delect删除所选元素
if (e.keyCode == 46) {
this.deleteObj();
}
// ctrl+z 删除最近添加的元素
if (e.keyCode == 90 && e.ctrlKey) {
this.canvas.remove(
this.canvas.getObjects()[this.canvas.getObjects().length - 1]
);
}
};
}
};