【问题标题】:Angular, drawing multiples rectangles with canvas on mouse eventAngular,在鼠标事件上用画布绘制多个矩形
【发布时间】:2019-12-11 23:35:48
【问题描述】:

我正在尝试创建一个有角度的绘图工具。我创建了一个工具,您可以在画布元素上绘制一个矩形,该工具工作正常,但我一次只能绘制一个矩形,我只是不知道如何“不清除”前一个矩形并保留我的画布上的多幅图画。我无法清除许多画布,因为我将有更多的图纸,而不仅仅是矩形。

rectangleDrawing() {

    // first coordinates when clicked
    let startX = 0;
    let startY = 0;

    const rect = this.canvasEl.getBoundingClientRect();

    fromEvent(this.canvasEl, "mousedown")
        .pipe(
            switchMap((e:MouseEvent) => {

                startX = e.clientX - rect.left;
                startY = e.clientY - rect.top;

                return fromEvent(this.canvasEl, 'mousemove').pipe(

                    takeUntil(fromEvent(this.canvasEl, 'mouseup')),
                    takeUntil(fromEvent(this.canvasEl, 'mouseleave'))
                )

            })
        ).subscribe((event:MouseEvent) => {

            let x = event.clientX - rect.left;
            let y = event.clientY - rect.top;

            let width = x - startX;
            let height = y - startY;


            this.setCanvasProperties(10, 'square', 'rgba(255,158,43,0.6)');

            this.cx.beginPath();

            // if I comment this line, the rectangles will stay, but they 
            // won't be clear, making multiples rectangles inside the 
            // main rectangle
            this.cx.clearRect(0,0, this.canvasEl.width, this.canvasEl.height);

            this.cx.rect(startX, startY, width, height);

            this.cx.stroke();

        });

}

setCanvasProperties(lineWidth, lineCap, strokeStyle) {
    this.cx = this.canvasEl.getContext('2d');
    this.cx.lineWidth = lineWidth;
    this.cx.lineCap = lineCap;
    this.cx.strokeStyle = strokeStyle;
}

这个链接就是一个很好的例子:https://jsfiddle.net/richardcwc/ukqhf54k/,如果你评论清楚的行,你可以看到主要问题。许多示例似乎一次只允许一个矩形。

【问题讨论】:

  • 我和你一样面临同样的问题!!我看到了您的代码,是的,如果我们评论了我们无法绘制多个矩形的清晰线条。如果您找到任何解决方案,请告诉我,因为我被卡住了。 (Garcia 给出的以下解决方案不在 Angular 中)
  • 但是,当您第一次尝试创建矩形时,它将无法工作,但在第二次尝试之后,矩形被绘制。总是在第一次尝试时它不起作用。

标签: angular html5-canvas mouseevent rectangles


【解决方案1】:

鼠标向上时,您可以将绘制的矩形存储在一个数组中,然后绘制该数组和当前的矩形。

首先,让我们设置数组并将宽度和高度保持为全局变量:

var width;
var height;
var drawItems = [];

那么,mouseup 函数将是这样的:

$(canvas).on('mouseup', function(e) {
  mousedown = false;

  drawItems.push({
    x0: last_mousex,
    x1: width,
    y0: last_mousey,
    y1: height
  });
});

这是mousemove函数:

$(canvas).on('mousemove', function(e) {
    mousex = parseInt(e.clientX-canvasx);
    mousey = parseInt(e.clientY-canvasy);
    if(mousedown) {
        ctx.clearRect(0,0,canvas.width,canvas.height); //clear canvas

        ctx.strokeStyle = 'black';
        ctx.lineWidth = 10;

        for(var i=0; i<drawItems.length; i++) {
            ctx.beginPath();
            ctx.rect(drawItems[i].x0, drawItems[i].y0, drawItems[i].x1, drawItems[i].y1);
            ctx.stroke();
        }

        width = mousex-last_mousex;
        height = mousey-last_mousey;
        ctx.beginPath();
        ctx.rect(last_mousex,last_mousey,width,height);
        ctx.stroke();
    }
    //Output
    $('#output').html('current: '+mousex+', '+mousey+'<br/>last: '+last_mousex+', '+last_mousey+'<br/>mousedown: '+mousedown);
});

Here 是更新的小提琴

希望对你有帮助

【讨论】:

  • 我也面临同样的问题,比如@heliosk。我的代码在 Angular 中,但我已经应用了您建议的逻辑。感谢您的建议,它解决了我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
  • 2016-06-07
  • 1970-01-01
  • 2017-01-19
  • 1970-01-01
  • 1970-01-01
  • 2011-04-18
相关资源
最近更新 更多