Skip to content

自定义图形

自定义绘制图形,有2种方式,一种是滑动绘制,一种是点击绘制的

怎么自定义

ts
import CanvasMarkBoard from "canvas-mark-board";
const { MoveMarkObject, MarkBoardUtils } = CanvasMarkBoard;
class XXXXXObject extends MoveMarkObject {}
new CanvasMarkBoard().register('xxxx',XXXXXObject)

具体可以参考查看react在线演示源码

下面是2种模式具体api和demo

点击绘制

tsx
import CanvasMarkBoard from "canvas-mark-board";
const { ClickMarkObject, MarkBoardUtils } = CanvasMarkBoard;
class XXXObject extends ClickMarkObject {
  constructor(box) {
    super(box);
    // 图形名称
    this.type = "sides_arrow"
    // 是否闭合
    this.isClosed = true
    // 最大点数
    this.maxPointCount = 3
    // 最小点数
    this.minPointCount = 2
  }
  /** 绘制的图形path */
  get pathData() {}
  /** 获取结果点 */
  get resultPoints() {}
  /** 获取index点 */
  get indexPoint() {}
  /** 渲染 */
  render(){}
  /** 判断点是否在图形内部 */
  isPointInside(point) {}
  /** 鼠标和其他操作,一般不用写,内部已经判断好 */
  boxMousemove(point){}
  boxMouseup(point){}
  boxMousedown(point){}
  destory() {}
  removeAll() {}
  async complete() {}
  static import(){}
}
tsx
/** 自定义多线段箭头 */
class MarkPolylineArrowObject extends ClickMarkObject {
  constructor(box: any) {
    super(box);
    this.type = "polyline_arrow" as any;
  }
  /** 获取path  */
  get pathData() {
    let path = ``;
    if (this.pointList.length) {
      this.pointList.forEach((point, index) => {
        if (index === 0) {
          path += `M${point.x},${point.y}`;
        } else {
          path += `L${point.x},${point.y}`;
        }
      });
      if (this.pointList.length >= 2) {
        for (let i = 0; i < this.pointList.length - 1; i++) {
          const [arrow1, arrow2] = MarkBoardUtils.getArrow(
            this.pointList[i],
            this.pointList[i + 1],
            20 / this.box.t.a
          );
          path += `M${arrow1.x},${arrow1.y}`;
          path += `L${this.pointList[i + 1].x},${this.pointList[i + 1].y}`;
          path += `M${this.pointList[i + 1].x},${this.pointList[i + 1].y}`;
          path += `L${arrow2.x},${arrow2.y}`;
          path += `M${this.pointList[i + 1].x},${this.pointList[i + 1].y}`;
        }
      }
    }
    return path;
  }
}

滑动绘制

ts
import CanvasMarkBoard from "canvas-mark-board";
const { MoveMarkObject, MarkBoardUtils } = CanvasMarkBoard;
class XXXXXObject extends MoveMarkObject {
  constructor(box: any) {
    super(box);
    // 类型
    this.type = "triangle" as any;
    // 低于多少尺寸不绘制
    this.completeOffset = 30 
  }
  /** move到操作点时设置鼠标样式 */
  setCursor(){}
  /** 编辑move时设置形状操作 */
  setMoveEdit(_offset?: any) {}
  /** 获取绘制的path */
  get pathData(){}
  /** 获取坐标点 */
  get vertexList(){}
  /** 获取导出结果点 */
  get resultPoints(){}
  /** 获取index点 */
  get indexPoint(){}
  /** 渲染 */
  render(){}
  /** 判断点是否在多边形内部 */
  isPointInside(){}
   /** 鼠标和其他操作,一般不用写,内部已经判断好 */
  boxMousemove(point){}
  boxMouseup(point){}
  boxMousedown(point){}
  destory() {}
  removeAll() {}
  async complete() {}
  static import(){}

}
ts
/** 自定义三角形 */
class MarkTriangleObject extends MoveMarkObject {
  constructor(box: any) {
    super(box);
    this.type = "triangle" as any;
  }
  setMoveEdit(offset: any): void {
    if (this.acctivePointIndex == 0) {
      this.pointList[0] = {
        x: this.pointList[0].x + offset.x,
        y: this.pointList[0].y + offset.y,
      };
    } else if (this.acctivePointIndex === 1) {
      this.pointList[1] = {
        x: this.pointList[1].x + offset.x,
        y: this.pointList[1].y + offset.y,
      };
    } else if (this.acctivePointIndex === 2) {
      this.pointList[0] = {
        x: this.pointList[0].x + offset.x,
        y: this.pointList[0].y,
      };
      this.pointList[1] = {
        x: this.pointList[1].x,
        y: this.pointList[1].y + offset.y,
      };
    }
  }
  /** 获取path  */
  get pathData() {
    let path = ``;
    if (this.vertexList.length) {
      this.vertexList.forEach((point, index) => {
        // 绘制线段
        if (index === 0) {
          path += `M${point.x},${point.y}`;
        } else {
          path += `L${point.x},${point.y}`;
        }
      });
      path += `Z `;
    }
    return path;
  }
  /** 获取三角形顶点 */
  get vertexList() {
    if (this.pointList.length === 2) {
      return [
        {
          x: (this.pointList[0].x + this.pointList[1].x) / 2,
          y: this.pointList[0].y,
        },
        this.pointList[1],
        { x: this.pointList[0].x, y: this.pointList[1].y },
      ];
    } else {
      return [];
    }
  }
  get indexPoint() {
    return this.vertexList[0];
  }
  /** 获取三角形结果点 */
  get resultPoints() {
    return this.vertexList;
  }
}
ts
/** 自定义带方向的线 */
class MarkSidesArrowObject extends MoveMarkObject {
  constructor(box: any) {
    super(box);
    this.type = "sides_arrow" as any;
  }
  setMoveEdit(): void {
    this.pointList[this.acctivePointIndex] = {
      x: this.lastMousePoint!.x,
      y: this.lastMousePoint!.y,
    };
  }
  isPointInside(point: { x: number; y: number }): boolean {
    let expand = this.expent / this.box.t.a;
    let offset = MarkBoardUtils.isPointInPolygon(point, this.pointList);
    return offset < expand;
  }
  get pathData() {
    let path = ``;
    if (
      this.pointList.length === 2 &&
      this.pointList[0].x != this.pointList[1].x &&
      this.pointList[0].y != this.pointList[1].y
    ) {
      path += `M${this.pointList[0].x},${this.pointList[1].y}`;
      path += `L${this.pointList[0].x},${this.pointList[1].y}`;
      const [side1, side2] = MarkBoardUtils.getSides(
        this.pointList[0],
        this.pointList[1]
      );
      const [arrow1, arrow2] = MarkBoardUtils.getArrow(
        side2,
        side1,
        20 / this.box.t.a
      );
      path += `Z`;
      path += `M${side2.x},${side2.y}`;
      path += `L${side1.x},${side1.y}`;
      // 绘制三角形
      path += `Z`;
      path += `M${arrow1.x},${arrow1.y}`;
      path += `L${side1.x},${side1.y}`;
      path += `M${side1.x},${side1.y}`;
      path += `L${arrow2.x},${arrow2.y}`;
      path += `Z`;
      // 连接到原来位置
      path += `M${this.pointList[0].x},${this.pointList[0].y}`;
      path += `L${this.pointList[1].x},${this.pointList[1].y}`;

      path += `L${this.pointList[0].x},${this.pointList[0].y} `;
      path += `L${this.pointList[this.pointList.length - 1].x},${
        this.pointList[this.pointList.length - 1].y
      } `;
      path += `Z `;
    }

    return path;
  }
}