Search code examples
javascriptimagecanvaskineticjsshapes

Kinetic.js get shape hit region with color change


First of all, I have images with different shapes and i have to recolour them, and set the hit region (for onclick event) only when the mouse is on the shape. So after investigate the problem separately, i have found both solutions, but i dont know how to use both together.

-to use only shape hit region, i use .cache(), to store the image on cache and redraw it without transparent pixels.

-to change the color, i iterate on imageData pixels, to change them one by one inside a for loop.

For testing, i'm using original blue image (.png format) and i want red image with hit regions set properly, also i'm using kinetic-v5.0.2.

this is my code.

    function makeKineticImage(imageObj){


    var dImage = new Kinetic.Shape({
        sceneFunc: function (context) {
            context.beginPath();
            console.log("sceneFunc");
            var x = 100;
            var y = 100;
            context.drawImage(imageObj, x, y, imageObj.width, imageObj.height);
            var imageData = context.getImageData(x, y, imageObj.width, imageObj.height);
            var data = imageData.data;

                            //Here i'm changing the color
            for (var i = 0; i < data.length; i += 4) {
                //var brightness = 0.9 * data[i] + 0 * data[i + 1] + 0 * data[i + 2];
                data[i] = 255;
                data[i + 1] = 25;
                data[i + 2] = 25;
            }
            context.putImageData(imageData, x, y);
            context.rect(x, y, imageObj.width, imageObj.height);
            context.closePath();
            context.fillStrokeShape(this);
        }
    });

    dImage.on("click", function() {
      console.log("Click dImage");
    }); 

    layer.add(dImage);

    /*dImage.cache({
        width: 79,
        height: 73,
        x: 100,
        y: 100
    });

    dImage.drawHitFromCache();*/

    layer.draw();
    layer.drawHit();
}

Now I get my shape filled in other color (red) but hit region dont fit the shape (get all image square), but If I uncomment .cache() and .drawHitFromCache() i get my original image (blue) with hit region only on the shape.

Could you help me? Thank you very much.


Solution

  • try this!!!

    The relavant part of code is:

    dataURL = context.getCanvas().toDataURL("image/png");

    var imageObj = new Image(); imageObj.src = dataURL;

    function makeKineticImage(imageObj){
            var dataURL;
            var dImage = new Kinetic.Shape({
                sceneFunc: function (context) {
                    context.beginPath();
                    console.log("sceneFunc");
                    var x = 100;
                    var y = 100;
                    context.drawImage(imageObj, x, y, imageObj.width, imageObj.height);
                    var imageData = context.getImageData(x, y, imageObj.width, imageObj.height);
                    var data = imageData.data;
                    for (var i = 0; i < data.length; i += 4) {
                        //var brightness = 0.9 * data[i] + 0 * data[i + 1] + 0 * data[i + 2];
                        data[i] = 255;
                        data[i + 1] = 25;
                        data[i + 2] = 25;
                    }
                    context.putImageData(imageData, x, y);
                    context.rect(x, y, imageObj.width, imageObj.height);
                    context.closePath();
                    context.fillStrokeShape(this);
                    dataURL = context.getCanvas().toDataURL("image/png");
                    console.log(dataURL);
    
                },
                hitFunc: function(context) {
                    console.log("hitFunc");
                    context.beginPath();
                    var x = 100;
                    var y = 100;
                    context.drawImage(imageObj, x, y, imageObj.width, imageObj.height);
                    var imageData = context.getImageData(x, y, imageObj.width, imageObj.height);
                    var data = imageData.data;
                    for (var i = 0; i < data.length; i += 4) {
                        //var brightness = 0.9 * data[i] + 0 * data[i + 1] + 0 * data[i + 2];
                        data[i] = 255;
                        data[i + 1] = 25;
                        data[i + 2] = 25;
                    }
                    context.putImageData(imageData, x, y);
                    context.rect(x, y, imageObj.width, imageObj.height);
                    context.closePath();
                    context.fillStrokeShape(this);
                }
            });
    
            layer.add(dImage);
            layer.draw();
            layer.removeChildren();
            var imageObj = new Image();
            imageObj.src = dataURL;
            var kImage = new Kinetic.Image({
                image: imageObj,
                //x: 100,
                //y: 100,
            });
    
            kImage.on("click", function() {
                console.log("Click dImage");
            });
    
            layer.add(kImage);
            kImage.cache();
            kImage.drawHitFromCache();
            layer.draw();
            layer.drawHit();
        }