zoukankan      html  css  js  c++  java
  • (四)Angular2 Canvas简单实现

    一、非流畅实现

    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

     二、流畅实现

    1.canvas.component.html

    <canvas class="vp-canvas1" #canvas1 [width]="canvasWidth" [height]="canvasHeight">您的浏览器不支持画布!</canvas>
    <canvas class="vp-canvas2" #canvas2 [width]="canvasWidth" [height]="canvasHeight">您的浏览器不支持画布!</canvas>
    View Code

    2.canvas.component.ts

      /** canvas1 */
      @ViewChild('canvas1')
      public canvas1Ref: ElementRef;
      /** canvas2 */
      @ViewChild('canvas2')
      public canvas2Ref: ElementRef;
      /** 绘制类型 */
      public readonly markCfg = [
        { value: 2, label: '矩形', class: 'mark-rectangle' },
        { value: 3, label: '圆形', class: 'mark-ellipse' },
        { value: 1, label: '曲线', class: 'mark-curves' },
        { value: 4, label: '文字', class: 'mark-text' },
        { value: 0, label: '撤销', class: 'rotation-anticw-d2' },
      ];
      /** 当前绘制类型 */
      public switchMarkType: number;
      /** 鼠标按下状态 */
      public isMouseDown: boolean;
      /** 文字绘制 */
      public MarkTexts: string;
      /** 文字绘制弹窗 */
      public nzmdMarkText: boolean;
      /** 绘制颜色 */
      public readonly markColorCfg = ['#ef4343', '#ef7c43'];
      /** 默认绘制颜色 */
      public defaultMarkColor: string;
      /** canvas1 */
      public canvas1;
      /** canvas1的contex1 */
      public context1;
      /** canvas2 */
      public canvas2;
      /** canvas2的contex2 */
      public context2;
      /** canvas宽度 */
      public canvasWidth: number = 952;
      /** canvas高度 */
      public canvasHeight: number = 477;
      /** canvas操作次数 */
      public canvasIndex: number;
      /** canvas图像源 */
      public canvasData;
      /** 鼠标坐标 */
      public mouseXY = { x1: 0, y1: 0, x2: 0, y2: 0 };
      /** 初始化canvas */
      public initCanvas() {
        this.switchMarkType = null;
        this.isMouseDown = false;
        this.MarkTexts = null;
        this.nzmdMarkText = false;
        this.defaultMarkColor = '#ef4343';
        this.canvasIndex = -1;
        this.canvasData = [];
        this.mouseXY = { x1: 0, y1: 0, x2: 0, y2: 0 };
      }
      /** 生成canvas图像及绑定参数和事件 */
      public createCanvas(base64PImg) {
        this.initCanvas();
        this.canvas1 = this.canvas1Ref.nativeElement;
        this.context1 = this.canvas1Ref.nativeElement.getContext('2d');
        this.canvas2 = this.canvas2Ref.nativeElement;
        this.context2 = this.canvas2Ref.nativeElement.getContext('2d');
        // 绑定canvas变量
        this.canvas1.canvasIndex = this.canvasIndex;
        this.canvas1.canvasData = this.canvasData;
        // 绑定canvas事件
        this.canvas1.onmousedown = this.canvasMouseDown;
        this.canvas1.onmouseup = this.canvasMouseUp;
        this.canvas1.onmousemove = this.canvasMouseMove;
        // 添加默认图片到历史记录
        this.setCanvasImage(this.context2, this.canvas2, base64PImg, this.canvasWidth, this.canvasHeight, (url) => {
          this.canvas1.canvasIndex++;
          this.canvasData.push(url);
        });
      }
      /** 切换绘制 */
      public switchMark(markType: number) {
        if (markType === 0) {
          this.undo();
        }
        if (markType !== 4) {
          this.nzmdMarkText = false;
        }
        if (this.switchMarkType === markType || markType === 0) {
          this.switchMarkType = null;
          return;
        }
        this.switchMarkType = markType;
      }
      /** 提交文字绘制 */
      public MarkText() {
        this.context1.font = "24px Arial";
        if(isNull(this.MarkTexts)) return console.log('文字内容不能为空');
        this.context1.fillText(this.MarkTexts, this.mouseXY.x1, this.mouseXY.y1);
        this.setCanvasImage(this.context2, this.canvas2, this.canvas1.toDataURL(), this.canvasWidth, this.canvasHeight, (url) => {
          this.context1.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
          this.canvas1.canvasIndex++;
          this.canvasData.push(url);
        })
        this.MarkTextCancel();
      }
      /** 取消文字绘制 */
      public MarkTextCancel() {
        this.MarkTexts = null;
        this.nzmdMarkText = false;
      }
      /** 撤销 */
      public undo() {
        if (this.canvas1.canvasIndex > 0) {
          this.canvasData.pop();
          this.canvas1.canvasIndex--;
          this.setCanvasImage(this.context2, this.canvas2, this.canvasData[this.canvas1.canvasIndex], this.canvasWidth, this.canvasHeight, (url) => {
            return;
          });
        } else {
          this.nzmsgSrv.warning('不能再继续撤销了');
        }
      }
      /** 设置绘制颜色 */
      public colorChange(color: string) {
        this.defaultMarkColor = color;
      }
      /** 鼠标按下 */
      public canvasMouseDown = (e) => {
        if (this.switchMarkType === null) {
          return;
        }
        this.isMouseDown = true;
        // 设置线条样式
        this.context1.lineWidth = '2';
        this.context1.strokeStyle = this.defaultMarkColor;
        this.context1.fillStyle = this.defaultMarkColor;
        // 设置起点坐标
        this.setMouseXY(true, e);
        // 绘制曲线
        if (this.switchMarkType === 1) {
          this.context1.beginPath();
          this.context1.moveTo(this.mouseXY.x1, this.mouseXY.y1);
        }
        // 设置文字坐标
        if (this.switchMarkType === 4) {
          this.nzmdMarkText = true;
        }
      }
      /** 鼠标弹起 */
      public canvasMouseUp = (e) => {
        this.isMouseDown = false;
        if (this.switchMarkType === null || this.switchMarkType === 4) {
          return;
        }
        this.setCanvasImage(this.context2, this.canvas2, this.canvas1.toDataURL(), this.canvasWidth, this.canvasHeight, (url) => {
          this.context1.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
          this.canvas1.canvasIndex++;
          this.canvasData.push(url);
        })
      }
      /** 鼠标移动 */
      public canvasMouseMove = (e) => {
        if (this.isMouseDown) {
          // 清除canvas1上的图像
          this.context1.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
          // 绘制线
          if (this.switchMarkType === 1) {
            // 记录起点坐标
            this.setMouseXY(true, e);
            this.context1.lineTo(this.mouseXY.x1, this.mouseXY.y1);
            this.context1.stroke();
            this.context1.save();
          }
          // 记录终点坐标
          this.setMouseXY(false, e);
          // 绘制矩形
          if (this.switchMarkType === 2) {
            this.context1.strokeRect(this.mouseXY.x1, this.mouseXY.y1, this.mouseXY.x2 - this.mouseXY.x1, this.mouseXY.y2 - this.mouseXY.y1);
          }
          // 绘制圆形
          if (this.switchMarkType === 3) {
            this.context1.beginPath();
            var cx = (this.mouseXY.x1 + this.mouseXY.x2) / 2;
            var cy = (this.mouseXY.y1 + this.mouseXY.y2) / 2;
            var rx = Math.abs((this.mouseXY.x1 - this.mouseXY.x2) / 2);
            var ry = Math.abs((this.mouseXY.y1 - this.mouseXY.y2) / 2);
            this.context1.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2);
            this.context1.stroke();
          }
          // 在canvas1上绘制图像
          this.context1.drawImage(this.canvas1, 0, 0, this.canvasWidth, this.canvasHeight);
        }
      }
    
      /** 根据宽高生成canvas图像 */
      public setCanvasImage(context, canvas, base64PImg, canvasWidth: number, canvasHeight: number, callback) {
        let img = new Image();
        img.onload = function () {
          context.drawImage(img, 0, 0, canvasWidth, canvasHeight);
          callback(canvas.toDataURL());
        }
        img.src = base64PImg;
      }
      /** 求鼠标坐标函数 */
      public windowToCanvas(canvas, x, y) {
        const rect = canvas.getBoundingClientRect();
        return {
          x: x - rect.left * (canvas.width / rect.width),
          y: y - rect.top * (canvas.height / rect.height)
        };
      }
      /** 记录坐标 */
      public setMouseXY(start: boolean, e) {
        const ele = this.windowToCanvas(this.canvas1, e.clientX, e.clientY);
        if (start) {
          this.mouseXY.x1 = ele.x;
          this.mouseXY.y1 = ele.y;
        } else {
          this.mouseXY.x2 = ele.x;
          this.mouseXY.y2 = ele.y;
        }
      }
    View Code
  • 相关阅读:
    s:set标签
    Oracle创建表语句(Create table)语法详解及示例
    jsp:useBean
    四则运算练习
    Navicat Premium无法连上ORACLE数据库的几种问题解决方法
    Ubuntu开机等待5分钟的取消方法
    Ubuntu内网、外网网络IP地址配置
    eclipse中常用的快捷键汇总
    oracle死锁进程及杀死死锁进程
    oracle导入导出表数据
  • 原文地址:https://www.cnblogs.com/chendongbky/p/12027481.html
Copyright © 2011-2022 走看看