使用鼠标事件在HTML5画布上绘制圆/椭圆

dex*_*007 2 javascript canvas

我想在画布上画椭圆选项,以便在画布上绘画.我已经部分实现了这一点.问题是我无法获得圆的半径,目前我已将其硬编码为15.此外,我想绘制椭圆(与油漆相同)不是精确的圆.这是我使用鼠标事件在画布上绘制圆圈的代码.请帮助我使用代码来实现我上面提到的要求.

 function tool_circle() {
        var tool = this;
        this.started = false;

        this.mousedown = function (ev) {
            tool.started = true;
            tool.x0 = ev._x;
            tool.y0 = ev._y;
        };

        this.mousemove = function (ev) {
            if (!tool.started) {
                return;
            }

            context.fillStyle = 'red';

            var distance = Math.sqrt(Math.pow(tool.x0 - ev._x, 2) + Math.pow(tool.y0 - ev._y));
            context.beginPath();

            context.arc(tool.x0, tool.y0,15, 0, Math.PI * 2, false);
            context.stroke();
            context.fill();
        };

        this.mouseup = function (ev) {
            if (tool.started) {
                tool.mousemove(ev);
                tool.started = false;
                img_update();
            }
        };
    }
Run Code Online (Sandbox Code Playgroud)

小智 6

我会像markE的回答一样,但是使用Bezier曲线会绘制椭圆,但它不会给你你可能需要的确切半径.

为此,需要绘制手动椭圆的功能,而且相当简单 -

此功能需要一个拐角起点和和终点,并绘制一个椭圆究竟该边界之内:

现场演示

来自演示的快照

function drawEllipse(x1, y1, x2, y2) {

    var radiusX = (x2 - x1) * 0.5,   /// radius for x based on input
        radiusY = (y2 - y1) * 0.5,   /// radius for y based on input
        centerX = x1 + radiusX,      /// calc center
        centerY = y1 + radiusY,
        step = 0.01,                 /// resolution of ellipse
        a = step,                    /// counter
        pi2 = Math.PI * 2 - step;    /// end angle

    /// start a new path
    ctx.beginPath();

    /// set start point at angle 0
    ctx.moveTo(centerX + radiusX * Math.cos(0),
               centerY + radiusY * Math.sin(0));

    /// create the ellipse    
    for(; a < pi2; a += step) {
        ctx.lineTo(centerX + radiusX * Math.cos(a),
                   centerY + radiusY * Math.sin(a));
    }

    /// close it and stroke it for demo
    ctx.closePath();
    ctx.strokeStyle = '#000';
    ctx.stroke();
}
Run Code Online (Sandbox Code Playgroud)

该演示也标记了矩形区域,以显示椭圆正好位于其中.

要处理可以绘制椭圆的鼠标操作,您可以执行以下操作:

var canvas = document.getElementById('myCanvas'),
    ctx = canvas.getContext('2d'),
    w = canvas.width,
    h = canvas.height,
    x1,                 /// start points
    y1,
    isDown = false;     /// if mouse button is down

/// handle mouse down    
canvas.onmousedown = function(e) {

    /// get corrected mouse position and store as first point
    var rect = canvas.getBoundingClientRect();
    x1 = e.clientX - rect.left;
    y1 = e.clientY - rect.top;
    isDown = true;
}

/// clear isDown flag to stop drawing
canvas.onmouseup = function() {
    isDown = false;
}

/// draw ellipse from start point
canvas.onmousemove = function(e) {

    if (!isDown) return;

    var rect = canvas.getBoundingClientRect(),
        x2 = e.clientX - rect.left,
        y2 = e.clientY - rect.top;

    /// clear canvas
    ctx.clearRect(0, 0, w, h);

    /// draw ellipse
    drawEllipse(x1, y1, x2, y2);
}
Run Code Online (Sandbox Code Playgroud)

提示可以在主画布顶部创建顶部画布,并在那里进行绘制.释放鼠标按钮后,将绘图传输到主画布.这样,在绘制新形状时,您无需重绘所有内容.

希望这可以帮助!

  • @user130004 当然,只需在顶部添加一个用于拖动和绘制的画布。当 mouseup 将该画布绘制回已经存在的画布之上的主画布时。如果要重绘所有内容,可以将圆数据存储在数组(中心 x、t 和半径)中并从中重绘。 (2认同)
  • @user130004 这里是对上述代码的修改:http://jsfiddle.net/37vge/21/ (2认同)