2014-02-06 177 views
2

我想要繪製在畫布上的繪畫中的橢圓選項。我已經部分實現了這一點。問題是我不能得到圓的半徑,目前我已經硬編碼到15。我也想繪製橢圓(與油漆相同)不是確切的圓。 這是我使用鼠標事件在畫布上繪製圓的代碼。請幫我用代碼實現我上面提到的要求。使用鼠標事件在HTML5畫布上繪製圓/橢圓

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

回答

2

下面是如何拖動繪製橢圓的示例。

演示:http://jsfiddle.net/m1erickson/3SFJy/

enter image description here

使用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> 
+0

@markE你好,我想做同樣的事情了移動應用程序(Phonegap包裹)觸摸事件。我試過你的代碼,只是通過替換mouseup,mousemove與touchstart,touchmove事件。這些事件正在觸發,因爲我可以看到日誌,但不會繪製橢圓/圓。我需要爲觸摸事件做些什麼特別的事情?在此先感謝(我第一次使用畫布:)) – hashcoder

5

我會與坊間的答案類似然而,使用貝塞爾曲線將繪製橢圓,但它不會給你你可能需要的確切半徑。

對於繪製手動橢圓函數是必要的,而且是相當簡單 -

此功能需要一個拐角起點和和終點,並繪製一個橢圓正是該邊界內:

Live demo

Snapshot from demo

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

小費可以創建你的主畫布上方的頂部帆布做繪圖在那裏。當鼠標按鈕被釋放後,將繪圖轉移到您的主畫布。這樣,您在繪製新形狀時不必重繪所有內容。

希望這會有所幫助!

+0

我看到演示,它很好。但是,它只允許我們畫一個圓圈。我可以在畫布上繪製儘可能多的圈子嗎? – Pawan

+1

@ user130004當然,只需在頂部添加一個用於拖動和繪製的畫布。當mouseup將該畫布拖回到已存在的主畫布上時。如果你想重繪一切,你可以將圓形數據存儲在一個數組(中心x,t和半徑)中,並從中重繪。 – K3N

+1

@ user130004這裏是對上述代碼的修改:http://jsfiddle.net/37vge/21/ – K3N

0

下面是我用鼠標拖動畫一個橢圓到畫布上的方法。

它採用了1半徑,而是動態調整,以獲得橢圓效果:)

https://jsfiddle.net/richardcwc/wdf9cocz/

//Canvas 
 
var canvas = document.getElementById('canvas'); 
 
var ctx = canvas.getContext('2d'); 
 
//Variables 
 
var scribble_canvasx = $(canvas).offset().left; 
 
var scribble_canvasy = $(canvas).offset().top; 
 
var scribble_last_mousex = scribble_last_mousey = 0; 
 
var scribble_mousex = scribble_mousey = 0; 
 
var scribble_mousedown = false; 
 

 
//Mousedown 
 
$(canvas).on('mousedown', function(e) { 
 
    scribble_last_mousex = parseInt(e.clientX-scribble_canvasx); 
 
\t scribble_last_mousey = parseInt(e.clientY-scribble_canvasy); 
 
    scribble_mousedown = true; 
 
}); 
 

 
//Mouseup 
 
$(canvas).on('mouseup', function(e) { 
 
    scribble_mousedown = false; 
 
}); 
 

 
//Mousemove 
 
$(canvas).on('mousemove', function(e) { 
 
    scribble_mousex = parseInt(e.clientX-scribble_canvasx); 
 
\t scribble_mousey = parseInt(e.clientY-scribble_canvasy); 
 
    if(scribble_mousedown) { 
 
     ctx.clearRect(0,0,canvas.width,canvas.height); //clear canvas 
 
     //Save 
 
     ctx.save(); 
 
     ctx.beginPath(); 
 
     //Dynamic scaling 
 
     var scalex = 1*((scribble_mousex-scribble_last_mousex)/2); 
 
     var scaley = 1*((scribble_mousey-scribble_last_mousey)/2); 
 
     ctx.scale(scalex,scaley); 
 
     //Create ellipse 
 
     var centerx = (scribble_last_mousex/scalex)+1; 
 
     var centery = (scribble_last_mousey/scaley)+1; 
 
     ctx.arc(centerx, centery, 1, 0, 2*Math.PI); 
 
     //Restore and draw 
 
     ctx.restore(); 
 
     ctx.strokeStyle = 'black'; 
 
     ctx.lineWidth = 5; 
 
     ctx.stroke(); 
 
    } 
 
    //Output 
 
    $('#output').html('current: '+scribble_mousex+', '+scribble_mousey+'<br/>last: '+scribble_last_mousex+', '+scribble_last_mousey+'<br/>mousedown: '+scribble_mousedown); 
 
});
canvas { 
 
    cursor: crosshair; 
 
    border: 1px solid #000000; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<canvas id="canvas" width="800" height="500"></canvas> 
 
<div id="output"></div>