一、非流畅实现

1.canvas.component.html

<button (click)="switchMark(1)">画笔</button>
<button (click)="switchMark(2)">矩形</button>
<button (click)="switchMark(3)">圆形</button>
<button (click)="switchMark(4)">文字</button>
<button (click)="switchMark(0)">撤销</button>
<input type="text" [(ngModel)]="text">
<canvas class="vp-canvas" #canvas1 width="470" height="300" style="border: 1px solid #ccc;">您的浏览器不支持画布!</canvas>
View Code

2.canvas.component.ts

  // canvas
  @ViewChild('canvas1')
  public canvasRef: ElementRef;
  // canvas1
  public canvas1;
  // contex1
  public context1;
  // 操作次数
  public canvasIndex = -1;
  // canvas图片
  public canvasData = [];
  // 轨迹结束判断
  public isSameMove = false;
  // 起点对象
  public startXY = { x1: 0, y1: 0, x2: 0, y2: 0 };
  // 开关
  public switchType = null;
  // 文字
  public Text = null;
  // 初始化canvas
  public initCanvas() {
    this.canvas1 = null;
    this.context1 = null;
    this.canvasIndex = -1;
    this.canvasData = [];
    this.isSameMove = false;
    this.startXY = { x1: 0, y1: 0, x2: 0, y2: 0 };
    this.switchType = null;
    this.Text = null;
  }
  // 生成canvas内容及事件
  public createCanvas(base64PImg) {
    this.initCanvas();
    this.canvas1 = this.canvasRef.nativeElement;
    const context1 = this.canvasRef.nativeElement.getContext('2d');
    var img = new Image();
    img.onload = function () {
      context1.drawImage(img, 0, 0, 470, 300);
    }
    img.src = base64PImg;
    this.context1 = context1;
    // 添加默认图片到历史记录
    this.canvasIndex++;
    this.canvasData.push(base64PImg);
    // 绑定canvas参数
    this.canvas1.canvas1 = this.canvasRef.nativeElement;
    this.canvas1.context1 = this.canvasRef.nativeElement.getContext('2d');
    this.canvas1.canvasIndex = this.canvasIndex;
    this.canvas1.canvasData = this.canvasData;
    this.canvas1.startXY = this.startXY;
    this.canvas1.switchType = this.switchType;
    this.canvas1.Text = this.Text;
    // 绑定canvas方法
    this.canvas1.windowToCanvas = this.windowToCanvas;
    // 绑定canvas事件
    this.canvas1.onmousedown = this.canvasMouseDown;
    this.canvas1.onmouseup = this.canvasMouseUp;
    this.canvas1.onmousemove = this.canvasMouseMove;
  }
  // 增加文字内容
  public updateText(ev) {
    this.canvas1.Text = ev;
  }
  // 切换绘制
  public switchMark(type) {
    if (type === 0) {
      this.undo();
    }
    if (type === 0) {
      this.switchType = null;
      this.canvas1.switchType = this.switchType;
      return;
    }
    this.switchType = type;
    this.canvas1.switchType = this.switchType;
  }
  // 撤销
  public undo() {
    if (this.canvas1.canvasIndex > 0) {
      this.canvasData.pop();
      this.canvas1.canvasIndex--;
      this.context1.clearRect(0, 0, 470, 300);
      var context1 = this.canvasRef.nativeElement.getContext('2d');
      var img = new Image();
      img.onload = function () {
        context1.drawImage(img, 0, 0, 470, 300);
      }
      img.src = this.canvasData[this.canvas1.canvasIndex];
    } else {
      console.log('不能再继续撤销了');
    }
  }
  // 求鼠标坐标函数
  public windowToCanvas(canvas, x, y) {
    var rect = canvas.getBoundingClientRect();
    return {
      x: x - rect.left * (canvas.width / rect.width),
      y: y - rect.top * (canvas.height / rect.height)
    };
  }
  // 鼠标按下开始绘制图形函数
  public canvasMouseDown(e) {
    if (this.switchType === null) {
      return;
    }
    this.context1.strokeStyle = 'red';
    this.context1.fillStyle = 'red';
    // 绘制曲线
    if (this.switchType === 1) {
      this.isSameMove = true;
      var ele = this.windowToCanvas(this.canvas1, e.clientX, e.clientY);
      this.context1.beginPath();
      this.context1.moveTo(ele.x, ele.y);
    }
    // 绘制矩形
    if (this.switchType === 2) {
      var ele = this.windowToCanvas(this.canvas1, e.clientX, e.clientY);
      this.startXY.x1 = ele.x;
      this.startXY.y1 = ele.y;
    }
    // 绘制圆形
    if (this.switchType === 3) {
      var ele = this.windowToCanvas(this.canvas1, e.clientX, e.clientY);
      this.startXY.x1 = ele.x;
      this.startXY.y1 = ele.y;
    }
    // 绘制文字
    if (this.switchType === 4) {
      var str = this.Text;
      var ele = this.windowToCanvas(this.canvas1, e.clientX, e.clientY);
      this.startXY.x1 = ele.x;
      this.startXY.y1 = ele.y;
      this.context1.font = "24px Arial";
      this.context1.fillText(str, ele.x, ele.y);
    }
  }
  // 鼠标弹起
  public canvasMouseUp(e) {
    if (this.switchType === null) {
      return;
    }
    // 曲线
    if (this.switchType === 1) {
      this.isSameMove = false;
    }
    // 矩形
    if (this.switchType === 2) {
      var ele = this.windowToCanvas(this.canvas1, e.clientX, e.clientY);
      this.startXY.x2 = ele.x;
      this.startXY.y2 = ele.y;
      this.context1.strokeRect(this.startXY.x1, this.startXY.y1, this.startXY.x2 - this.startXY.x1, this.startXY.y2 - this.startXY.y1);
    }
    // 圆形
    if (this.switchType === 3) {
      var ele = this.windowToCanvas(this.canvas1, e.clientX, e.clientY);
      this.startXY.x2 = ele.x;
      this.startXY.y2 = ele.y;
      this.context1.beginPath();
      var cx = (this.startXY.x1 + this.startXY.x2) / 2;
      var cy = (this.startXY.y1 + this.startXY.y2) / 2;
      var rx = Math.abs((this.startXY.x1 - this.startXY.x2) / 2);
      var ry = Math.abs((this.startXY.y1 - this.startXY.y2) / 2);
      this.context1.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2);
      this.context1.stroke();
    }
    this.canvas1.canvasIndex++;
    this.canvasData.push(this.canvas1.toDataURL());
  }
  // 鼠标移动
  public canvasMouseMove(e) {
    if (this.switchType === 1) {
      if (this.isSameMove) {
        var ele = this.windowToCanvas(this.canvas1, e.clientX, e.clientY);
        this.context1.lineTo(ele.x, ele.y);
        this.context1.stroke();
        this.context1.save();
      }
    }
  }
View Code
12-27 18:16
查看更多