第二部分,接下来要实现直线、箭头、矩形和文字
直线:fabric绘制直线提供了一个方法
new fabric.Line([mouseFrom.x, mouseFrom.y, mouseTo.x, mouseTo.y])
想要实现直线,首先要获取到canvas内的xy轴坐标,要获取到四个点,就是开始绘制的xy坐标点和结束绘制的xy坐标点
而想要获取到这四个坐标点,首先要监听鼠标按下和鼠标抬起的行为事件
// initEvent
initEvent() {
this.canvas.on("mouse:down", (options) => {
this.mouseFrom.x = options.e.offsetX; //记录开始的坐标x点
this.mouseFrom.y = options.e.offsetY; //记录开始的坐标y点
});
this.canvas.on("mouse:up", (options) => {
this.mouseTo.x = options.e.offsetX;
this.mouseTo.y = options.e.offsetY;
})
},
记住该方法要在初始化的时候就要调用!!!!
既然得到了4个坐标点,那么绘制的时候一定是在鼠标移动的时候
不停的改变mouseTo的xy坐标
this.canvas.on("mouse:move", (options) => {
this.mouseTo.x = options.e.offsetX;
this.mouseTo.y = options.e.offsetY;
this.drawing(); //在这里执行绘制方法
});
//我们要判断下当前是什么模式,是自由绘制模式,还是直线?等等,所以在切换的时候要赋值一个变量 `dragType`,
//在`setBrushModel`方法内
// 自由绘制
case 0:
this.dragType = "pen";
this.canvas.isDrawingMode = true;
break;
// 直线
case 2:
this.dragType = "line";
break;
------------------------------------------------------
drawing(){
this.canvas.remove(this.drawingObject);
let canvasObject = null;
switch (this.dragType) {
case "line":
canvasObject = new fabric.Line(
[
this.mouseFrom.x,
this.mouseFrom.y,
this.mouseTo.x,
this.mouseTo.y,
],
//参数:没有参数就没有颜色和痕迹
{
stroke: this.color,
strokeWidth: this.width,
}
);
break;
default:
break;
}
if (canvasObject) {
this.canvas.add(canvasObject);
this.drawingObject = canvasObject;
}
}
下面实现矩形:同样实现了方法
new fabric.Rect({
left: left,
top: top,
width: width,
height: height,
stroke: this.color,
fill: "rgba(255, 255, 255, 0)",
strokeWidth: this.width,
});
image.png
完整代码如下
let left = this.mouseFrom.x;
let top = this.mouseFrom.y;
let width = this.mouseTo.x - this.mouseFrom.x;
let height = this.mouseTo.y - this.mouseFrom.y;
canvasObject = new fabric.Rect({
left: left,
top: top,
width: width,
height: height,
stroke: this.color,
fill: "rgba(255, 255, 255, 0)",
strokeWidth: this.width,
});
下面实现 文本 ,同样api如下
new fabric.Textbox(" ", {
left: this.mouseFrom.x,
top: this.mouseFrom.y,
width: 150,
fontSize: 18,
borderColor: "#2c2c2c",
fill: this.color,
hasControls: false,
selectable: false,//不可被选中
})
case 4:
this.dragType = "text";
break;
this.canvas.on("mouse:down", (options) => {
this.mouseFrom.x = options.e.offsetX; //记录开始的坐标x点
this.mouseFrom.y = options.e.offsetY; //记录开始的坐标y点
if (this.dragType == "text") {
this.textBox = new fabric.Textbox(" ", {
left: this.mouseFrom.x,
top: this.mouseFrom.y,
width: 400,
fontSize: 18,
padding: 7, // 设置输入框内边距
fill: this.color,
});
this.canvas.add(this.textBox).setActiveObject(this.textBox);//将输入框添加到画布中
this.textBox.enterEditing(); //激活输入框
this.textBox.hiddenTextarea.focus();
}
});
最后是 实现 箭头 ,箭头插件没有提供 api。只能自己封装
// 绘制箭头的方法
drawArrow(fromX, fromY, toX, toY, theta, headlen) {
theta = typeof theta != "undefined" ? theta : 30;
headlen = typeof theta != "undefined" ? headlen : 10;
// 计算各角度和对应的P2,P3坐标
var angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI,
angle1 = ((angle + theta) * Math.PI) / 180,
angle2 = ((angle - theta) * Math.PI) / 180,
topX = headlen * Math.cos(angle1),
topY = headlen * Math.sin(angle1),
botX = headlen * Math.cos(angle2),
botY = headlen * Math.sin(angle2);
var arrowX = fromX - topX,
arrowY = fromY - topY;
var path = " M " + fromX + " " + fromY;
path += " L " + toX + " " + toY;
arrowX = toX + topX;
arrowY = toY + topY;
path += " M " + arrowX + " " + arrowY;
path += " L " + toX + " " + toY;
arrowX = toX + botX;
arrowY = toY + botY;
path += " L " + arrowX + " " + arrowY;
return path;
},
//通过path路径来绘制
case "arrow":
canvasObject = new fabric.Path(
this.drawArrow(
this.mouseFrom.x,
this.mouseFrom.y,
this.mouseTo.x,
this.mouseTo.y,
30,
20
),
{
stroke: this.color,
fill: "rgba(255,255,255,0)",
strokeWidth: this.width,
}
);
break;
END!!!
网友评论