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

Javascript 使用鼠标事件在HTML5画布上绘制圆/椭圆,javascript,canvas,Javascript,Canvas,我想在我的画布上绘制类似椭圆的东西。我已经部分实现了这一点。问题是我不能得到圆的半径;目前我已经硬编码为15。我还想画一个椭圆(就像在绘画中)而不是精确的圆 这是我使用鼠标事件在画布上绘制圆圈的代码。请帮助我的代码,以实现我的上述要求 功能工具_circle(){ var工具=这个; this.start=false; this.mousedown=函数(ev){ tool.started=true; 工具x0=ev.\u x; 工具y0=ev.\u y; }; this.mousemove=函

我想在我的画布上绘制类似椭圆的东西。我已经部分实现了这一点。问题是我不能得到圆的半径;目前我已经硬编码为15。我还想画一个椭圆(就像在绘画中)而不是精确的圆

这是我使用鼠标事件在画布上绘制圆圈的代码。请帮助我的代码,以实现我的上述要求

功能工具_circle(){
var工具=这个;
this.start=false;
this.mousedown=函数(ev){
tool.started=true;
工具x0=ev.\u x;
工具y0=ev.\u y;
};
this.mousemove=函数(ev){
如果(!tool.started){
返回;
}
context.fillStyle='red';
var距离=数学sqrt(数学功率(tool.x0-ev.x,2)+数学功率(tool.y0-ev.y));
context.beginPath();
弧(tool.x0,tool.y0,15,0,Math.PI*2,false);
stroke();
context.fill();
};
this.mouseup=函数(ev){
如果(工具启动){
工具。鼠标移动(ev);
tool.start=false;
img_update();
}
};
}

下面是一个如何拖动绘制椭圆形的示例

演示:

使用2条贝塞尔曲线拖动绘制椭圆的示例代码:

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
body{ background-color: ivory; padding:0px;}
#canvas{ border:1px solid blue; }
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;
    var startX;
    var startY;
    var isDown=false;

    function drawOval(x,y){
        ctx.clearRect(0,0,canvas.width,canvas.height);
        ctx.beginPath();
        ctx.moveTo(startX, startY + (y-startY)/2);
        ctx.bezierCurveTo(startX, startY, x, startY, x, startY + (y-startY)/2);
        ctx.bezierCurveTo(x, y, startX, y, startX, startY + (y-startY)/2);
        ctx.closePath();
        ctx.stroke();
    }

    function handleMouseDown(e){
      e.preventDefault();
      e.stopPropagation();
      startX=parseInt(e.clientX-offsetX);
      startY=parseInt(e.clientY-offsetY);
      isDown=true;
    }

    function handleMouseUp(e){
      if(!isDown){ return; }
      e.preventDefault();
      e.stopPropagation();
      isDown=false;
    }

    function handleMouseOut(e){
      if(!isDown){ return; }
      e.preventDefault();
      e.stopPropagation();
      isDown=false;
    }

    function handleMouseMove(e){
      if(!isDown){ return; }
      e.preventDefault();
      e.stopPropagation();
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      drawOval(mouseX,mouseY);
    }

    $("#canvas").mousedown(function(e){handleMouseDown(e);});
    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    $("#canvas").mouseup(function(e){handleMouseUp(e);});
    $("#canvas").mouseout(function(e){handleMouseOut(e);});

}); // end $(function(){});
</script>
</head>
<body>
    <h4>Drag to create a circle or oval</h4>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

正文{背景色:象牙色;填充:0px;}
#画布{边框:1px纯蓝色;}
$(函数(){
var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
var canvasOffset=$(“#画布”).offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var-startX;
var startY;
var isDown=假;
函数(x,y){
clearRect(0,0,canvas.width,canvas.height);
ctx.beginPath();
ctx.moveTo(startX,startY+(y-startY)/2);
ctx.bezierCurveTo(startX,startY,x,startY,x,startY+(y-startY)/2);
ctx.bezierCurveTo(x,y,startX,y,startX,startY+(y-startY)/2);
ctx.closePath();
ctx.stroke();
}
功能手柄向下(e){
e、 预防默认值();
e、 停止传播();
startX=parseInt(e.clientX-offsetX);
startY=parseInt(e.clientY-offsetY);
isDown=真;
}
功能handleMouseUp(e){
如果(!isDown){return;}
e、 预防默认值();
e、 停止传播();
isDown=假;
}
函数handleMouseOut(e){
如果(!isDown){return;}
e、 预防默认值();
e、 停止传播();
isDown=假;
}
功能手柄移动(e){
如果(!isDown){return;}
e、 预防默认值();
e、 停止传播();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(例如clientY-offsetY);
drawOval(mouseX,mouseY);
}
$(“#canvas”).mousedown(函数(e){handleMouseDown(e);});
$(“#canvas”).mousemove(函数(e){handleMouseMove(e);});
$(“#canvas”).mouseup(函数(e){handleMouseUp(e);});
$(“#canvas”).mouseout(函数(e){handleMouseOut(e);});
}); // end$(函数(){});
拖动以创建圆形或椭圆形

我希望与markE的答案类似,但是,使用Bezier曲线将绘制椭圆,但它不会给出您可能需要的确切半径

为此,需要一个手动绘制椭圆的函数,而且它相当简单-

此函数将获取一个角点起点和终点,并在该边界内准确地绘制一个椭圆:

提示可以是在主画布的顶部创建一个顶部画布,并在那里自己绘制。释放鼠标按钮后,将图形转移到主画布。这样,在绘制新形状时,您不必重新绘制所有内容


希望这有帮助

这是我用鼠标拖动在画布上绘制椭圆的方法

它使用半径1,但动态缩放以获得椭圆效果:)

//画布
var canvas=document.getElementById('canvas');
var ctx=canvas.getContext('2d');
//变数
var scribble_canvasx=$(canvas).offset().左;
var scribble_canvasy=$(canvas).offset().top;
var scribble_last_mousex=scribble_last_mousey=0;
var scribble_mousex=scribble_mousey=0;
var scribble_mousedown=false;
//穆斯敦
$(画布).on('mousedown',函数(e){
scribble_last_mousex=parseInt(e.clientX-scribble_canvasx);
scribble_last_mousey=parseInt(e.clientY-scribble_canvasy);
scribble_mousedown=真;
});
//鼠标
$(画布).on('mouseup',函数(e){
scribble_mousedown=假;
});
//鼠标移动
$(画布).on('mousemove',函数(e){
scribble_mousex=parseInt(e.clientX-scribble_canvasx);
scribble_mousey=parseInt(例如clientY-scribble_canvasy);
如果(涂鸦鼠标向下){
ctx.clearRect(0,0,canvas.width,canvas.height);//清除画布
//拯救
ctx.save();
ctx.beginPath();
//动态缩放
var scalex=1*((scribble\u mousex-scribble\u last\u mousex)/2);
var scaley=1*((scribble\u mousey-scribble\u last\u mousey)/2);
ctx.scale(scalex,scaley);
//创建椭圆
var centerx=(scribble\u last\u mousex/scalex)+1;
变量centery=(scribble\u last\u mousey/scaley)+1;
ctx.arc(centerx,centery,1,0,2*Math.PI);
//还原并绘制
ctx.restore();
ctx.strokeStyle=‘黑色’;
ctx.lineWidth=5;
ctx.stroke();
}
//输出
$('#output').html('current:'+scrible_mousex+','+scrible_mousey+'
last:'+scrible_last_mousex+','+scrible_last_mousey+'
mousedown:'+scrible_mousedown]; });
画布{
光标:十字线;
边框:1px实心#000000;
}


我看了演示,很不错。但是,它只允许我们画一个圆。我可以在画布上画任意多的圆圈吗?@user130004当然可以,只要在上面添加一块画布,你就可以用它来拖动和绘制。当鼠标将画布拉回到主画布时
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();
}
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);
}