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>
4

2 に答える 2

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[] を使用して線を描画し、色で塗りつぶします。
  • ( 「線の描画が完了したことを検出する必要がある...」と言うので、ユーザーがクリックしたときにすぐに線を描画したくないと思います。)ユーザーがクリックしたときにすぐに描画したい場合は、私にコメントしてください。その代替案についてもお手伝いできます;)

あなたのコードでいくつかのクリーンアップを提案する場合:

これは、キャンバス上のマウスの位置を取得する良い方法です:

    // before you begin listening for mouseclicks, 
    // get the canvas’  screen position into offsetX/offsetY
    var canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

    // then when a mousedown event occurs
    // use e.clientX/Y (not e.pageX/Y) to get the mouse position on the canvas
    canvasMouseX=parseInt(e.clientX-offsetX);
    canvasMouseY=parseInt(e.clientY-offsetY);

コンテキストと storedLines を使用して実際にパスを描画している場合:

  • パスを閉じるには、context.stroke() と context.fill() の前に context.closePath() を置きます。
  • fillStyle と strokeStyle を設定します。
  • context.fill() と context.stroke() を実行します。fill() を実行しないと、塗りつぶしが得られません。

    // 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>
于 2013-03-20T15:37:26.450 に答える
1

storedLines 配列がその中のすべての値の正確なコピーで構成されている場合、図形を描画したことになります。それ以外の場合はまだ描画していません...

例:

3本の線を引くことで三角形を描く

  1. Line1 - (0,0) から (10,0)

  2. Line2 - (10,0) から (5,10)

  3. Line3 - (5,10) から (0,0)

そのため、すべてのポイントにそのコピーがあります。

于 2013-03-20T07:37:43.923 に答える