0

I am trying to implement the logic for drawing a rectangle on the canvas image. So basically first I am drawing image on the canvas. I want to provide the functionality of drawing a rectangle on that canvas image using a mouse.

  mdEvent(e) {
    //console.log("mouse down");
    var target = e.target || e.srcElement || e.currentTarget;
    var idAttr = target.attributes.id;
    var value = idAttr.nodeValue;
    this.canvasPage = value;
    
    let cElement: any = document.getElementById(this.canvasPage);
    let context: any = cElement.getContext("2d");
    let l = cElement.getBoundingClientRect().left;
    let t = cElement.getBoundingClientRect().top;
    let r = cElement.getBoundingClientRect().right;
    let b = cElement.getBoundingClientRect().bottom;
    //console.log("points ", this.startX - l, this.startY - t);
    this.startX = ((e.clientX - l) / (r - l)) * cElement.width;
    this.startY = ((e.clientY - t) / (b - t)) * cElement.height;

    this.drag = true;
  }

In the above code - I am taking starting positions of the mouse on canvas image for drawing

mmEvent(e) {
    //console.log("mouse move");
    var target = e.target || e.srcElement || e.currentTarget;
    var idAttr = target.attributes.id;
    var value = idAttr.nodeValue;
    this.canvasPage = value;
    if (this.drag) {
      let cElement: any = document.getElementById(this.canvasPage);
      let context: any = cElement.getContext("2d");
   

      let l = cElement.getBoundingClientRect().left;
      let t = cElement.getBoundingClientRect().top;
      let r = cElement.getBoundingClientRect().right;
      let b = cElement.getBoundingClientRect().bottom;
      //console.log("points ", this.startX - l, this.startY - t);
      let mousex = ((e.clientX - l) / (r - l)) * cElement.width;
      let mousey = ((e.clientY - t) / (b - t)) * cElement.height;

      context.beginPath();
      let width = mousex - this.startX;
      let height = mousey - this.startY;
      context.strokeStyle = "yellow";
      context.lineWidth = 2;
      context.strokeRect(this.startX, this.startY, width, height);
    }
  }

In the above code- mouse move event in which I am drawing rectangle by getting width and height by subtracting starting points from current points.

 muEvent(e) {
    this.drag = false;
  }

In the above code - Drawing is finished by making drag false.

Output when I draw:

enter image description here

I have already tried clearing rectangle but it is clearing the image that I have drawn on the canvas.

HTML snippet

 <canvas class="canImg" #canvasDoc [attr.id]="'docCanvas'+index" [style.width]="zoomWidth + 'px'" 
                (mousedown)="mdEvent($event)" 
                  (mousemove)="mmEvent($event)" 
                  (mouseup)="muEvent($event)">
              </canvas>
              <img class="imgTag" #docImg src="{{image.page_obj}}" [style.width]="zoomWidth + 'px'" [attr.id]="'docImg'+index"
                (load)="onLoad(image.page_obj,index)" style='display: none;'>

Above code description:- Above code is in *ngFor . It iterates over number of images that we get from server. I am calling onLoad function on every image on image tag. Inside on load function we are just drawing image using onload .

  • You have to clear entire canvas then draw everything again (image + rect) – Helder Sepulveda Jul 13 '20 at 15:22
  • I tried it. But it was creating flickering whenever we draw image and rect again. – Chetan Dhanraj Patil Jul 14 '20 at 04:32
  • In that case you have optimization issues ... looking at that code the `cElement` and the `context` should be global – Helder Sepulveda Jul 14 '20 at 12:54
  • cElement and context are local because we don't know number of images in advance and I wanted to know on which canvas user is trying to draw for further logic implementation.So I added events on every canvas image in html. – Chetan Dhanraj Patil Jul 15 '20 at 07:50
  • How many canvases do you have? I'm assuming it's a known number and you can put that in global array ... would be easier to help you if you had a code snippet with a minimal but reproducible example – Helder Sepulveda Jul 15 '20 at 14:56
  • Thanks for helping me .Number of canvas are known at runtime. Code is very huge to add but I have added html snippet above. That snippet is inside for loop which is iterating over the number image inside an array. I wanted to add mouse event on every canvas image. – Chetan Dhanraj Patil Jul 16 '20 at 04:56
  • I think I have found the answer. I focused on optimization as Helder said . Instead of using onLoad everytime on mouse move I stored Image object in one while while initial loading and then used that array in mouse move . Now it working fine. I will test it and then upload answer. – Chetan Dhanraj Patil Jul 16 '20 at 07:45
  • @ChetanDhanrajPatil Can you please share the updated solution? I also have the same requirements. – Sathishkumar Sep 21 '22 at 07:07

0 Answers0