angular11+fabric-with-erasing实现涂抹和擦除,重做,恢复,撤销,保存涂抹痕迹

安装

npm i fabric-with-erasing

html

<canvas #canvas style="position: absolute; top:0;left:0;z-index: 10;" id="main"></canvas>
<div class="right">
<button (click)="undo()">撤销</button>
<button (click)="redo()">恢复</button>
<button (click)="paint()">涂抹</button>
    <button (click)="erase()">擦除</button>
    <button (click)="save()">保存</button>
</div>

ts

import { Component, ElementRef, OnInit, Renderer2, ViewChild } from '@angular/core';
import 'fabric-with-erasing';
declare var fabric: any;

@Component({
  selector: 'app-image-mark',
  templateUrl: './image-mark.component.html',
  styleUrls: ['./image-mark.component.less']
})
export class ImageMarkComponent implements OnInit {
  canvas: any;
  banner = ''
  lastMousePosition: any;
  ifErase = false
  undoStack: any[] = [];
  redoStack: any[] = [];

  history: fabric.Object[] = [];
  currentIndex: number = -1;
  ctx: any;

  constructor(private renderer: Renderer2) {

  }

  ngOnInit(): void {

    this.createCanvas()
  }

  createCanvas() {
    this.canvas = new fabric.Canvas('main', {
      hoverCursor: 'pointer'
    });
    this.ctx = this.canvas.getContext('2d');
    console.log(this.canvas)

    // 设置画布显示比例
    this.setPageStyle()
    this.canvas.hoverCursor = 'none'
    // 初始化画笔
    const pencil = new fabric.PencilBrush(this.canvas);

    // 设置画笔的样式
    pencil.color = 'rgba(68,255,205,0.4)'; // 画笔颜色
    pencil.width = 50; // 画笔宽度
    // 将画笔绑定到 Canvas
    this.canvas.freeDrawingBrush = pencil;
    this.canvas.isDrawingMode = true; // 启用涂抹功能
    this.saveHistory();

    // 创建自定义鼠标样式对象
    const customCursor = document.createElement('div');
    customCursor.style.width = '50px';
    customCursor.style.height = '50px';
    customCursor.style.border = '3px solid #ffffff';
    customCursor.style.background = 'rgba(255,255,255,0.6)'
    customCursor.style.borderRadius = '50%';
    customCursor.style.position = 'absolute';
    customCursor.style.pointerEvents = 'none';
    customCursor.style.display = 'none';

    // 设置自定义鼠标样式
    this.canvas.upperCanvasEl.style.cursor = 'none';
    this.canvas.wrapperEl.appendChild(customCursor);


    // 监听鼠标按下时事件,用于判断当前选中的元素,利用setInfo服务给全局发送当前编辑的对象。
    this.canvas.on('mouse:up', (event: any) => {
      console.log('鼠标抬起事件')
      const snapshot = this.canvas.toJSON();
      this.history.push(snapshot);

      this.saveHistory();
    })
    this.canvas.on('mouse:down', (event: any) => {
      console.log(event, 'down')
      let pointer = this.canvas.getPointer(event.e);

    });

    this.canvas.on('mouse:move', (event: any) => {
      this.canvas.upperCanvasEl.style.cursor = 'none';
      const pointer = this.canvas.getPointer(event.e);
      customCursor.style.left = pointer.x - 25 + 'px';
      customCursor.style.top = pointer.y - 25 + 'px';
    })

    this.canvas.on('mouse:out', () => {
      customCursor.style.display = 'none';
    });

    this.canvas.on('mouse:over', () => {
      customCursor.style.display = 'block';
    });



  }


  setPageStyle() {
    this.canvas.setWidth(200)
    this.canvas.setHeight(200);
    this.canvas.backgroundColor = 'rgba(255, 255, 255, 0)';
    this.canvas.renderAll();

  }

  //重做
  clearCanvas() {
    this.canvas.clear()
  }
 //保存
  save() {
    this.canvas.backgroundColor = 'white';
    const base64Image = this.canvas.toDataURL('image/png', 1.0);
    console.log(base64Image)
    this.canvas.backgroundColor = 'rgba(255,255,255,0.1)'
    // 创建一个下载链接
    const link = document.createElement('a');
    link.href = base64Image;
    link.download = 'canvas_image.jpg';

    // 触发下载
    link.click();

  }

 //涂抹
  paint() {
    this.ifErase = false
    const pencil = new fabric.PencilBrush(this.canvas);
    // 设置画笔的样式
    pencil.color = 'rgba(68,255,205,0.4)'; // 画笔颜色
    pencil.width = 50; // 画笔宽度
    // 将画笔绑定到 Canvas
    this.canvas.freeDrawingBrush = pencil;
    this.canvas.isDrawingMode = true;
  }

  //擦除
  erase() {
    // 启用橡皮擦功能
    this.canvas.freeDrawingBrush = new fabric.EraserBrush(this.canvas);

    // 自定义橡皮擦的宽度和颜色
    this.canvas.freeDrawingBrush.width = 50; // 设置橡皮擦宽度
    this.canvas.freeDrawingBrush.color = 'rgba(255, 255, 255, 1)'; // 设置橡皮擦颜色
  }

  saveHistory() {
    const snapshot = this.canvas.toJSON();
    this.history = this.history.slice(0, this.currentIndex + 1); // 截断未来的历史记录
    this.history.push(snapshot);
    this.currentIndex++;
  }

  undo() {
    if (this.currentIndex > 0) {
      this.currentIndex--;
      this.loadHistory();
    }
  }

  redo() {
    if (this.currentIndex < this.history.length - 1) {
      this.currentIndex++;
      this.loadHistory();
    }
  }

  loadHistory() {
    const snapshot = this.history[this.currentIndex];
    this.canvas.loadFromJSON(snapshot, () => {
      this.canvas.renderAll();
    });
  }

}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值