Angular : How to make undo on canvas drawing?

Angular : How to make undo on canvas drawing?

Problem Description:

I’m creating some drawing tool which is required in my current project, as per my requirement the drawing works fine, but I’m trying to create the UNDO option, and it’s not working properly.

Once the undo button clicks I need to remove the last drawn line only.

Refer the code here

<div style="position : relative">
  <canvas class="roiCanvas" id="canvas" #roiCanvas></canvas>

  <button (click)="clear()">Clear</button>
  <button (click)="undo()">Undo</button>
</div>

Angular Code for undo:

 drawPaths() {
    // delete everything
    this.cx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
    // draw all the paths in the paths array
    this.lineTo.forEach((path: any) => {
      this.cx.beginPath();
      var last = this.lineTo[this.lineTo.length - 1];
      this.cx.moveTo(last.x, last.y);
      for (let i = 1; i < path.length; i++) {
        this.drawChart(path[i].x, path[i].y);
        this.cx.lineTo(path[i].x, path[i].y);
      }
      this.cx.strokeStyle = '#0652DD';
      this.cx.stroke();
    });
  }
  undo() {
    this.lineTo.splice(-1, 1);
    console.log(this.lineTo);
    this.drawPaths();
  }

enter image description here
Please check the below stackblitz codebase.
https://stackblitz.com/edit/angular-ivy-kdc7dp?file=src/app/app.component.ts

Solution – 1

Well your drawPaths() function is using the last position, which does not work when this is removed:

var last = this.lineTo[this.lineTo.length - 1];

So i re-wrote the undo function to just draw the lines from start to finish, and this now works.

See: https://stackblitz.com/edit/angular-ivy-kdc7dp?file=src/app/app.component.ts

undo() {
  this.lineTo.splice(-1, 1);
  
  this.cx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);

  this.lineTo.forEach((path: any, i: any) => {

    this.cx.beginPath();

    this.drawChart(path.x, path.y);

    if(this.lineTo.length > i+1) {
      this.cx.lineTo(this.lineTo[i+1].x, this.lineTo[i+1].y);
    }

    this.cx.strokeStyle = '#0652DD';
    this.cx.stroke();
  });
}

I’ll leave it to you to dedupe the code and make it nice 😉

Rate this post
We use cookies in order to give you the best possible experience on our website. By continuing to use this site, you agree to our use of cookies.
Accept
Reject