Search code examples
html5-canvaspaperjs

Change mouse cursor while hover over specific canvas paths with Paper.js


Actually (using w3.org doc's example http://www.w3.org/html/wg/drafts/2dcontext/html5_canvas/#dom-context-2d-ispointinpath) I did figured out how it could be done in raw HTML5Canvas/JavaScript: http://jsfiddle.net/QTu9E/4/

Above I used isPointInPath(x, y) syntax, but according to mentioned docs there is also isPointInPath(path, x, y[, w ]) in which certain path can be given to check.

This one could be problem solver, but I can't get it work just passing paperjs's Path object into it!

I'll continue searching for solution, because as anyone else I have my deadlines, but any help would be appreciated!


Solution

  • Ok, here is the answer!

    http://jsfiddle.net/fqaJM/

    <canvas id="myCanvas" width="256" height="128"></canvas>
    <div id="xycoordinates"></div>
    

     

    #myCanvas {
        border: 1px solid #c3c3c3;
    }
    #xycoordinates {
        font: 9pt sans-serif;
    }
    

     

    var canvas = document.getElementById("myCanvas"); // Get canvas
    
    // Some initialisation stuff to make things work out of PaperScript context
    // Have to have things to be done this way because jsfiddle don't allow to save source with script type="text/paperscript"
    paper.install(window); 
    paper.setup(canvas);   
    
    var myPath = new paper.Path.Circle([64, 64], 32); // Red one, with 'pointer' cursor on it
    myPath.style = {
        fillColor: '#FF0000'
    };
    var scndPath = new paper.Path.Circle([192, 64], 32); // Green one, without cursor accent
    scndPath.style = {
        fillColor: '#00FF00'
    };
    paper.view.draw(); // Have to call manually when working from JavaScript directly
    
    var hitOptions = { // Trigger hit only on 'fill' part of the path with 0 tolerance
        segments: false,
        stroke: false,
        fill: true,
        tolerance: 0
    };
    
    var tool = new paper.Tool(); // Again manually. Life is much easier with script type="text/paperscript"
    tool.onMouseMove = function (event) { // Installig paperjs event 
        var x = event.point.x;
        var y = event.point.y;
    
        document.getElementById("xycoordinates").innerHTML = "Coordinates: (" + x + "," + y + ")";
    
        var hitResult = myPath.hitTest(event.point, hitOptions); // isPointInPath
    
        if (hitResult) {
            document.body.style.cursor = "pointer";
        } else {
            document.body.style.cursor = "default";
        }
    };
    

    The point is I missed paperjs has its own onMouseMove and hitTest(), which is isPointInPath() wrapper.

    Don't know how did it happen, because I'm already using it in project! Perhabs need to have some rest %)

    And any way, there are still some problems: it looks like hitTest() fires up some strange false positives, sontimes it doesn't trigger where it should. Check out point with (46,96) and (77,64) coordinates!

    UPD: Just tested the same code in one HTML file localy to get same artifacts: http://pastebin.com/HiYgKnw0