我是angular2和画布的新手,我正在尝试创建一个首先将图像绘制到画布上的组件,然后用户可以使用鼠标在该图像上绘制矩形(以点击和拖动方式) . 这是我到目前为止几乎按预期工作的 .

@Component({
    selector:'app-annotation',
    template:`                    
        <canvas #myCanvas width="400" height="400" style="background:lightgray;" (mousedown)="mdEvent($event)" (mouseup)="muEvent($event)" (mousemove)="mmEvent($event)"></canvas>
    `
})
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);
        }
    }

}

这里的问题是,当单击并按住鼠标时,矩形仅显示是否有鼠标移动 - 但我希望只要仍然单击鼠标,仍然会显示当前矩形 . 这有点出乎意料,因为在 mmEvent() 中,在重绘图像后绘制矩形,所以我希望矩形是在任何鼠标移动事件之后绘制的最后一个东西 - 但是 base_image.onload() 回调可能会弄乱它的时间 . 有关解决此问题的任何建议吗?

更新:

在回调中绘制矩形似乎可以修复它

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);
            };


        }
    }