How to draw in javascript canvas and compare it to a shape?

后端 未结 2 411
小蘑菇
小蘑菇 2021-01-28 02:36

so to keep it short I\'m wondering how would I be able to track a user drawing from the moment they click to when they let go and compare it to check its accuracy with say, a pe

相关标签:
2条回答
  • 2021-01-28 02:59

    Here's how i would do to compare a figure : I would let globalComposite operation 'xor' mode do the 'substraction' of the right figure, then, with getImageData, count the non-null pixels to estimate the error.

    Steps :
    • Let the user draw and store the points coordinates.
    • When figure is complete, compute the figure bounding box (min/max on x/y basically).
    • Draw again the figure (as a filled polygon) on a temporary canvas having the size of the bbox.
    • Set globalComposite to 'xor', and draw what would be the perfect figure on this canvas.
    • Grab the imageData of the canvas and count non-null pixels.
    • Compute the 'score' out of non-null pixels count vs canvas size. I suppose that less than 5% error is perfect, less than 25% is very good... Only trying can tell.

    0 讨论(0)
  • 2021-01-28 03:09

    I did this "stay inside the text" game a while back. All you try to do is trace the number. The more you stay inside the lines while tracing, the higher your score is.

    You're welcome to start with this and modify it as needed. :-)

    enter image description here

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var $canvas=$("#canvas");
    var canvasOffset=$canvas.offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;
    var scrollX=$canvas.scrollLeft();
    var scrollY=$canvas.scrollTop();
    
    
    ctx.font="216px arial";
    ctx.fillStyle="white";
    ctx.fillText("2",100,200);
    ctx.strokeText("2",100,200);
    
    var cw=canvas.width;
    var ch=canvas.height;
    var imgData=ctx.getImageData(0,0,cw,ch);
    var data=imgData.data;
    
    var isDown=false;
    var wasInside=true;
    var score=0;
    
    function draw(mouseX,mouseY){
    
      var alpha = data[((cw*mouseY)+mouseX)*4+3];
    
      score+=(alpha>19?1:-1);
    
      if(alpha<20 && wasInside){
        wasInside=false;
        ctx.fillStyle="white";
        ctx.fillRect(0,0,cw,ch);
        ctx.fillStyle="white";
        ctx.fillText("2",100,200);
        ctx.strokeText("2",100,200);
      }else if(alpha>19 && !wasInside){
        wasInside=true;
        ctx.fillStyle="white";
        ctx.fillRect(0,0,cw,ch);
        ctx.fillStyle="green";
        ctx.fillText("2",100,200);
        ctx.strokeText("2",100,200);
      }
    
    }
    
    function handleMouseDown(e){
      e.preventDefault();
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      var alpha = data[((cw*mouseY)+mouseX)*4+3];
      wasInside=(alpha<20);
      score=0;
      isDown=true;
      draw(mouseX,mouseY);
    }
    
    function handleMouseUp(e){
      e.preventDefault();
      isDown=false;
      $("#score").text("Score: "+score);
    }
    
    function handleMouseOut(e){
      e.preventDefault();
      isDown=false;
    }
    
    function handleMouseMove(e){
      if(!isDown){return;}
      e.preventDefault();
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      draw(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);});
    
    $(window).scroll(function(){
        var BB=canvas.getBoundingClientRect();
        offsetX=BB.left;
        offsetY=BB.top;
    });
    body{ background-color: white; }
    #canvas{border:1px solid red;}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <h4>Drag inside the number<br>Number stays green while you're inside.</h4>
    <h3 id="score">Score:</h3>
    <canvas id="canvas" width=300 height=300></canvas>

    0 讨论(0)
提交回复
热议问题