I have a canvas and I want to change the users cursor (like style cursor pointer crosshair move etc).
Is it possible to change the users cursor while its over a certain area of my canvas without introducing "hit boxes" with style of cursor on these hit boxes?
To change cursors when hovering over individual shapes you must do mouse hit-testing versus each shape (versus each path). You can hit-test a shape (a path) using the isPointInPath method. Oh this is brilliant!! That test in point thing with mousemove makes cursor changing so absolutely accurate!
Customize Your Mouse on Windows 10Search for and click on “Mouse settings” on your computer via the Start button or the Search bar in your taskbar. In the Window that follows click on “Adjust mouse & cursor size” in the right-side column. The next window will offer options for changing the pointer size and color.
If it has no keyboard shortcut, or you can't be bothered to remember it, you can toggle it by pressing Command/Ctrl + Shift + A , type "overwrite" in the popup, which should bring up the "Toggle Insert/Overwrite" option, and hit enter.
Shapes drawn on the canvas do not individually receive mouse events, so individual shapes cannot receive hover events.
A shape drawn on the canvas can be represented as a set of path commands
A Shape == A set of path commands. // Example: A set of path commands drawing a triangle context.beginPath(); context.moveTo(50,50); context.lineTo(75,100); context.lineTo(25,100); context.closePath();
To change cursors when hovering over individual shapes you must do mouse hit-testing versus each shape (versus each path).
You can hit-test a shape (a path) using the isPointInPath
method.
To use isPointInPath
you must re-issue the path command for a shape (but no need to stroke or fill) and then call isPointInPath
with the current mouse coordinates:
// first re-issue the path commands for the shape being tested // and then test if the mouse is inside the shape using isPointInPath if( context.isPointInPath(mouseX,mouseY) ){ alert('The mouse is inside this shape'); }
Here's example code and a Demo:
var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var cw=canvas.width; var ch=canvas.height; function reOffset(){ var BB=canvas.getBoundingClientRect(); offsetX=BB.left; offsetY=BB.top; } var offsetX,offsetY; reOffset(); window.onscroll=function(e){ reOffset(); } window.onresize=function(e){ reOffset(); } var isDown=false; var startX,startY; var cursors=['default','w-resize','n-resize']; var currentCursor=0; var shapes=[]; shapes.push({ points:[{x:20,y:50},{x:100,y:10},{x:180,y:50},{x:100,y:90}], cursor:1, }); shapes.push({ points:[{x:200,y:50},{x:250,y:150},{x:200,y:250},{x:150,y:150}], cursor:2, }); for(var i=0;i<shapes.length;i++){ var s=shapes[i]; definePath(s.points); ctx.stroke(); } $("#canvas").mousemove(function(e){handleMouseMove(e);}); function definePath(p){ ctx.beginPath(); ctx.moveTo(p[0].x,p[0].y); for(var i=1;i<p.length;i++){ ctx.lineTo(p[i].x,p[i].y); } ctx.closePath(); } function handleMouseMove(e){ // tell the browser we're handling this event e.preventDefault(); e.stopPropagation(); mouseX=parseInt(e.clientX-offsetX); mouseY=parseInt(e.clientY-offsetY); // Put your mousemove stuff here var newCursor; for(var i=0;i<shapes.length;i++){ var s=shapes[i]; definePath(s.points); if(ctx.isPointInPath(mouseX,mouseY)){ newCursor=s.cursor; break; } } if(!newCursor){ if(currentCursor>0){ currentCursor=0; canvas.style.cursor=cursors[currentCursor]; } }else if(!newCursor==currentCursor){ currentCursor=newCursor; canvas.style.cursor=cursors[currentCursor]; } }
body{ background-color: ivory; } #canvas{border:1px solid red; margin:0 auto; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <h4>Move the mouse over the shapes and the cursor will change.</h4> <canvas id="canvas" width=300 height=300></canvas>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With