title: Angular2 Draw Rectangle on Canvas with Mouse
body: <p>I am new to angular2 and canvases and I am trying to create a component that first draws an image onto a canvas and then the user can draw rectangles on that image with their mouse (in a click and drag fashion).  This is what I have so far which almost works as intended.</p>
  
  <pre><code>@Component({
      selector:'app-annotation',
      template:`                    
          &lt;canvas #myCanvas width="400" height="400" style="background:lightgray;" (mousedown)="mdEvent($event)" (mouseup)="muEvent($event)" (mousemove)="mmEvent($event)"&gt;&lt;/canvas&gt;
      `
  })
  export class ObjectDetectionComponent implements OnInit{
  
      startX:number=null;
      startY:number=null;
      drag=false;
  
      @ViewChild("myCanvas") myCanvas:ElementRef;
  
      mdEvent(e){
          //persist starting position
          this.startX=e.clientX;
          this.startY=e.clientY;
          this.drag=true;
      }
  
      mmEvent(e){
  
          if(this.drag){
  
              //redraw image on canvas
              let base_image = new Image();
              base_image.src = 'https://ak3.picdn.net/shutterstock/videos/10826363/thumb/1.jpg';
              let context: CanvasRenderingContext2D = this.myCanvas.nativeElement.getContext("2d");
              base_image.onload = function(){
                  context.canvas.height=base_image.height;
                  context.canvas.width=base_image.width;
                  context.drawImage(base_image, 0, 0);
              };
  
              //draw rectangle on canvas
              let x = this.startX - this.myCanvas.nativeElement.getBoundingClientRect().left;
              let y= this.startY- this.myCanvas.nativeElement.getBoundingClientRect().top;
              let w = e.clientX -this.myCanvas.nativeElement.getBoundingClientRect().left - x;
              let h = e.clientY -this.myCanvas.nativeElement.getBoundingClientRect().top - y;
              context.setLineDash([6]);
              context.strokeRect(x, y, w, h);
          }
      }
  
      muEvent(e){
          //draw final rectangle on canvas
          let x = this.startX - this.myCanvas.nativeElement.getBoundingClientRect().left;
          let y= this.startY- this.myCanvas.nativeElement.getBoundingClientRect().top;
          let w = e.clientX -this.myCanvas.nativeElement.getBoundingClientRect().left - x;
          let h = e.clientY -this.myCanvas.nativeElement.getBoundingClientRect().top - y;
          this.myCanvas.nativeElement.getContext("2d").setLineDash([6]);
          this.myCanvas.nativeElement.getContext("2d").strokeRect(x, y, w, h);
  
          this.drag=false;
      }
  
      ngOnInit(){
  
          //draw image on canvas
          let base_image = new Image();
          base_image.src = 'https://ak3.picdn.net/shutterstock/videos/10826363/thumb/1.jpg';
          let context: CanvasRenderingContext2D = this.myCanvas.nativeElement.getContext("2d");
          base_image.onload = function(){
              context.canvas.height=base_image.height;
              context.canvas.width=base_image.width;
              context.drawImage(base_image, 0, 0);
          }
      }
  
  }
  </code></pre>
  
  <p>The problem here is that when the mouse is clicked and held down, the rectangle only shows if there is mouse movement - but I want the current rectangle to be still be shown as long as the mouse is still clicked.  This is sort of unexpected since in <code>mmEvent()</code> the rectangle is drawn after the image is redrawn so I would expect the rectangle to be the last thing drawn after any mouse move event - however maybe the <code>base_image.onload()</code> callback is messing with the timing of that.  Any suggestions on fixing this issue?</p>
  
  <p>UPDATE:</p>
  
  <p>drawing the rectangle inside the callback seems to fix it</p>
  
  <pre><code>mmEvent(e) {
  
          if (this.drag) {
  
              //redraw image on canvas
              let base_image = new Image();
              base_image.src = 'https://ak3.picdn.net/shutterstock/videos/10826363/thumb/1.jpg';
              let context: CanvasRenderingContext2D = this.myCanvas.nativeElement.getContext("2d");
              let sx = this.startX;
              let sy = this.startY;
  
              let canvasTop = this.myCanvas.nativeElement.getBoundingClientRect().top;
              let canvasLeft = this.myCanvas.nativeElement.getBoundingClientRect().left;
  
              base_image.onload = function () {
                  context.canvas.height = base_image.height;
                  context.canvas.width = base_image.width;
                  context.drawImage(base_image, 0, 0);
  
                  //draw rectangle on canvas
                  let x = sx - canvasLeft;
                  let y = sy - canvasTop;
                  let w = e.clientX - canvasLeft - x;
                  let h = e.clientY - canvasTop - y;
                  context.setLineDash([6]);
                  context.strokeRect(x, y, w, h);
              };
  
  
          }
      }
  </code></pre>