Search code examples
kineticjsshapesintersectionsubtraction

KineticJS subtract one shape from another


I have a KineticJs stage where a user can draw objects - rectangles and polygons.

I would like the user to be able to select any two objects and have the first-selected shape be subtracted from the second-selected shape.

Ideally, the user would choose options from a context menu ("subtract this shape", "from this shape"), and the cutting shape would not be affected, only the cut shape would change.

What I'm stuck on is how to subtract shape A from shape B.

Here's a link to a drawing that shows what I mean:

https://docs.google.com/drawings/d/1X8ccw2YqDwMF8JwUYy_TeUnMX-4q6PcPsH8SjViyO3E/edit?usp=sharing (the "context menu" items are the floating rectangles).

Is this possible?


Solution

  • Altering one shape using another shape is called compositing.

    In your case subtracting the new circle from the existing rectangle would be a compositing operation called "destination-out".

    KineticJS does not offer composite operations on its objects.

    enter image description here

    This how to composite your rectangle minus circle using non-Kinetic html canvas:

    // draw the rectangle
    
    ctx.fillStyle="lightblue";
    ctx.fillRect(20,20,80,160);
    
    // save the context state
    
    ctx.save();
    
    // set compositing to destination-out
    // all new drawings will "cut-out" existing
    // drawings where they both overlap
    
    ctx.globalCompositeOperation="destination-out";
    
    // draw the circle
    
    ctx.beginPath();
    ctx.arc(100,90,30,0,Math.PI*2);
    ctx.closePath();
    ctx.fill();
    
    // restore the context state
    // This also turns off compositing 
    
    ctx.restore();
    

    What you can do to achieve your effect in KineticJS

    A Demo: http://jsfiddle.net/m1erickson/m34tn/

    • Create an off-screen canvas
    • Draw your rectangle-minus-circle on that canvas
    • Use that canvas as the source for a Kinetic.Image

    The result is that you will have a Kinetic image object with the shape you desire.