2013-03-20 97 views
1

使用下面的代码,我可以在画布上画出鼠标点。我需要检测绘制线何时完成一个形状并填充一些颜色。画布上的绘图形状

<script language="javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> 

<script type="text/javascript"> 
    $(document).ready(function() { 
     var worksheetCanvas = $('#worksheet-canvas'); 

     var context = worksheetCanvas.get(0).getContext("2d"); 
     var clicked = false; 
     // The array of stored lines 
     var storedLines = []; 

     // The object for the last stored line 
     var storedLine = {}; 
     var mouse = { 
      x: -1, 
      y: -1 
     } 

     var parentOffset = $('#canvas-holder').parent().offset(); 
     worksheetCanvas.click(function (e) { 
      clicked = true; 

      mouse.x = e.pageX - parentOffset.left; 
      mouse.y = e.pageY - parentOffset.top; 

      context.moveTo(mouse.x, mouse.y); 

      // Push last line to the stored lines 

      if (clicked) { 
       storedLines.push({ 
        startX: storedLine.startX, 
        startY: storedLine.startY, 
        endX: mouse.x, 
        endY: mouse.y 
       }); 

      } 

      // set last line coordinates 

      storedLine.startX = mouse.x; 
      storedLine.startY = mouse.y; 

      $(this).mousemove(function (k) { 
       // clear the canvas 

       context.clearRect(0, 0, 960, 500); 
       context.beginPath(); 
       context.strokeStyle = "rgb(180,800,95)"; 

       // draw the stored lines 

       for (var i = 0; i < storedLines.length; i++) { 
        var v = storedLines[i]; 
        context.moveTo(v.startX, v.startY); 
        context.lineTo(v.endX, v.endY); 
        context.stroke(); 
       } 
       context.moveTo(mouse.x, mouse.y); 
       context.lineTo(k.pageX - parentOffset.left, k.pageY - parentOffset.top); 
       context.stroke(); 


       context.closePath(); 


      }) 

     }) 

    }); 
</script> 
</head> 
<body> 
<div id="canvas-holder"> 

<canvas id="worksheet-canvas" width="960" height="500" style="background:black;"> 

        </canvas> 

       </div> 


</body> 
</html> 

回答

3

[澄清后,编辑由海报]

该代码将绘制/继续折线到永远的用户点击下一步。

如果用户在它们开始的绿色圆圈中单击,则会填充多段线。

这里是代码和一个小提琴:http://jsfiddle.net/m1erickson/qwd2a/

<!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> 
<!--[if lt IE 9]><script type="text/javascript" src="../excanvas.js"></script><![endif]--> 

<style> 
    body{ background-color: ivory; padding:10px; } 
    canvas{border:1px solid red;} 
</style> 

<script> 
$(function(){ 

    var canvas=document.getElementById("canvas"); 
    var ctx=canvas.getContext("2d"); 
    var canvasMouseX; 
    var canvasMouseY; 
    var canvasOffset=$("#canvas").offset(); 
    var offsetX=canvasOffset.left; 
    var offsetY=canvasOffset.top; 
    var storedLines=[]; 
    var startX=0; 
    var startY=0; 
    var radius=7; 

    ctx.strokeStyle="orange"; 
    ctx.font = '12px Arial'; 

    $("#canvas").mousedown(function(e){handleMouseDown(e);}); 

    function handleMouseDown(e){ 
     canvasMouseX=parseInt(e.clientX-offsetX); 
     canvasMouseY=parseInt(e.clientY-offsetY); 

     // Put your mousedown stuff here 
     if(hitStartCircle(canvasMouseX, canvasMouseY)){ 
      fillPolyline(); 
      return; 
     } 
     storedLines.push({x:canvasMouseX,y:canvasMouseY}); 
     if(storedLines.length==1){ 
      startX=canvasMouseX; 
      startY=canvasMouseY; 
      ctx.fillStyle="green"; 
      ctx.beginPath(); 
      ctx.arc(canvasMouseX, canvasMouseY, radius, 0 , 2 * Math.PI, false); 
      ctx.fill(); 
     }else{ 
      var c=storedLines.length-2; 
      ctx.strokeStyle="orange"; 
      ctx.lineWidth=3; 
      ctx.beginPath(); 
      ctx.moveTo(storedLines[c].x,storedLines[c].y); 
      ctx.lineTo(canvasMouseX, canvasMouseY); 
      ctx.stroke(); 
     } 
    } 

    function hitStartCircle(x,y){ 
     var dx=x-startX; 
     var dy=y-startY; 
     return(dx*dx+dy*dy<radius*radius) 
    } 
    function fillPolyline(){ 
     ctx.strokeStyle="red"; 
     ctx.fillStyle="blue"; 
     ctx.lineWidth=3; 
     ctx.clearRect(0,0,canvas.width,canvas.height); 
     ctx.beginPath(); 
     ctx.moveTo(storedLines[0].x,storedLines[0].y); 
     for(var i=0;i<storedLines.length;i++){ 
      ctx.lineTo(storedLines[i].x,storedLines[i].y); 
     } 
     ctx.closePath(); 
     ctx.fill(); 
     ctx.stroke(); 
     storedLines=[]; 
    } 

    $("#clear").click(function(){ 
     ctx.clearRect(0,0,canvas.width,canvas.height); 
     storedLines=[]; 
    }); 

}); // end $(function(){}); 
</script> 

</head> 

<body> 
    <p>Click to draw lines</p> 
    <p>Click back in the green circle to close+fill</p><br/> 
    <canvas id="canvas" width=300 height=300></canvas><br/> 
    <button id="clear">Clear Canvas</button> 
</body> 
</html> 

[上一页答案基于信息较少]

它看起来像你想:

  • 让用户点击画布上的点。
  • 在storedLines []中收集这些点。
  • 稍后,使用storedLines []画线+填充颜色。
  • (我假设你不想立即画线,因为你说“我需要检测绘图线何时完成......”。)如果你要立即提请当用户点击,给我留下了评论,我可以帮你,替代过多;)

如果让我来推荐几个清理在你的代码:

这是让你的画布上鼠标位置的好方法:

​​

当你实际绘制的路径与上下文和storedLines:

  • 要关闭路径,请在context.stroke()和context.fill()之前放置context.closePath()。
  • 设置fillStyle和strokeStyle。
  • 做context.fill()和context.stroke() - 如果你不填充(),你将不会得到颜色填充。

    // close a path 
    context.closePath(); 
    context.fillStyle=”blue”; 
    context.strokeStyle=”rgb(180,80,95)”; 
    context.fill(); 
    context.stroke(); 
    

这里是代码和一个小提琴:http://jsfiddle.net/m1erickson/zYsQh/

<!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> 
<!--[if lt IE 9]><script type="text/javascript" src="../excanvas.js"></script><![endif]--> 

<style> 
    body{ background-color: ivory; padding:10px; } 
    canvas{border:1px solid red;} 
</style> 

<script> 
$(function(){ 

    var canvas=document.getElementById("canvas"); 
    var ctx=canvas.getContext("2d"); 
    var canvasMouseX; 
    var canvasMouseY; 
    var canvasOffset=$("#canvas").offset(); 
    var offsetX=canvasOffset.left; 
    var offsetY=canvasOffset.top; 
    var storedLines=[]; 

    ctx.strokeStyle="orange"; 
    ctx.font = '12px Arial'; 

    $("#canvas").mousedown(function(e){handleMouseDown(e);}); 

    function handleMouseDown(e){ 
     canvasMouseX=parseInt(e.clientX-offsetX); 
     canvasMouseY=parseInt(e.clientY-offsetY); 

     // Put your mousedown stuff here 
     storedLines.push({x:canvasMouseX,y:canvasMouseY}); 
     var count=storedLines.length; 
     var X=canvasMouseX-(count<10?4:7); 
     ctx.strokeStyle="orange"; 
     ctx.fillStyle="black"; 
     ctx.lineWidth=1; 
     ctx.beginPath(); 
     ctx.arc(canvasMouseX, canvasMouseY, 8, 0 , 2 * Math.PI, false); 
     ctx.fillText(storedLines.length, X, canvasMouseY+4); 
     ctx.stroke(); 
    } 

    $("#draw").click(function(){ 
     ctx.strokeStyle="red"; 
     ctx.fillStyle="blue"; 
     ctx.lineWidth=3; 
     ctx.clearRect(0,0,canvas.width,canvas.height); 
     ctx.beginPath(); 
     ctx.moveTo(storedLines[0].x,storedLines[0].y); 
     for(var i=0;i<storedLines.length;i++){ 
      ctx.lineTo(storedLines[i].x,storedLines[i].y); 
     } 
     ctx.closePath(); 
     ctx.fill(); 
     ctx.stroke(); 
     storedLines=[]; 
    }); 

    $("#clear").click(function(){ 
     ctx.clearRect(0,0,canvas.width,canvas.height); 
     storedLines=[]; 
    }); 

}); // end $(function(){}); 
</script> 

</head> 

<body> 
    <p>Click to create storedLines[]</p> 
    <p>Then press the Draw button to fill the path</p><br/> 
    <canvas id="canvas" width=300 height=300></canvas><br/> 
    <button id="clear">Clear Canvas</button> 
    <button id="draw">Draw</button> 
</body> 
</html> 
+0

喜!谢谢您的帮助。我实际上需要在用户单击并用颜色填充颜色时填写线条 – chamara 2013-03-21 01:59:01

+0

没问题...当用户单击并填充完成时,我已根据绘制线修改了我的答案 - 干杯:) – markE 2013-03-21 02:52:28

+0

您好!需要帮助。我需要在绘图时用光标悬挂绘图线。我试图用mousemove事件,但没有得到它的工作。 – chamara 2013-03-21 10:51:37

1

如果您storedLines阵列包含在它的所有值的精确副本,那么你已经绘制的形状,否则你有没有......

例子:

你画三条线画一个三角形

  1. 线路1 - (0,0)到(10,0)

  2. 线路2 - (10,0)到(5,10)

  3. 行3 - (5,10)到(0,0)

因此,所有点都有它的副本。