简体   繁体   中英

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

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 perfect circle?

Would this be possible, and if so what are the best ways to check its accuracy compared to a perfect circle and how?

Also thinking of this like if the user has drawn a circle but the start and end points don't exactly meet, maybe draw a line to connect them, etc?

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. :-)

在此处输入图片说明

 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> 

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM