美文网首页
互动白板项目文档(二)

互动白板项目文档(二)

作者: 风中凌乱的男子 | 来源:发表于2022-09-08 16:18 被阅读0次
第二部分,接下来要实现直线、箭头、矩形和文字

直线: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!!!

相关文章

网友评论

      本文标题:互动白板项目文档(二)

      本文链接:https://www.haomeiwen.com/subject/spzgnrtx.html