Ash
Ash

Reputation: 62096

Extending kineticjs shapes

I'm new to kineticjs. I'm looking to build a stage that supports adjustable polygon line shapes that define valid areas for dropping things into.

I was told I'd need to extend (inherit from) built in shapes and add my required functionality. According to this page we use 'Kinetic.Util.extend' to do this.

However I've been reading the official docs and it appears Kinetic.Util.extend is undocumented! The page also uses Kinetic.Shape.call() but I cannot find anything about this either.

If we should not be using these methods, what is the recommended approach?

If they are still the recommended approach, why are they not documented?

I've already spent too long trying to locate any useful info on this, and it is beginning to reduce my confidence in kineticjs in general.

Upvotes: 0

Views: 294

Answers (1)

markE
markE

Reputation: 105015

You can indeed extend the KineticJS language to include your custom shapes.

You hook into KineticJS by using Kinetic.Util.extend plus some constructors that use .call to configure your custom shapes.

  • Kinetic.Util.extend just copies the "inherited" properties+methods from the base "class" to your new object.
  • Kinetic shapes are configured by sending in a plain-old-javascript-object containing the desired properties of the object (x,y coordinates, width/height, etc).
  • .call is used to initialize your custom shape and its "base class" with the configured properties.

But...

You very rarely need to formally extend the language itself to accomplish most tasks.

You don't give details about your project, but you can define an adjustable polygon and wire up mouse events to that polygon like this:

var poly=new Kinetic.Polygon({
    x:10,
    y:10,
    points:[180,150, 165,176, 135,176, 120,150, 135,124, 165,124],
    stroke:"green"
});
poly.on("mouseup",function(){
    console.log("You released the mouse in this polygon");
});
layer.add(poly);
layer.draw();

Here's a Demo:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Prototype</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.2.min.js"></script>
    <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.min.js"></script>
<style>
    body{padding:20px;}
    #container{
      border:solid 1px #ccc;
      margin-top: 10px;
      width:350px;
      height:350px;
    }
    #toolbar{
      width:350px;
      height:35px;
      border:solid 1px blue;
    }
</style>        
<script>
$(function(){

    // get a reference to the house icon in the toolbar
    // hide the icon until its image has loaded
    var $house=$("#house");
    $house.hide();

    // get the offset position of the kinetic container
    var $stageContainer=$("#container");
    var stageOffset=$stageContainer.offset();
    var offsetX=stageOffset.left;
    var offsetY=stageOffset.top;

    // create the Kinetic.Stage and layer
    var stage = new Kinetic.Stage({
        container: 'container',
        width: 350,
        height: 350
    });
    var layer = new Kinetic.Layer();
    stage.add(layer);

    // start loading the image used in the draggable toolbar element
    // this image will be used in a new Kinetic.Image
    var image1=new Image();
    image1.onload=function(){
        $house.show();
    }
    image1.src="house32x32.png";

    // make the toolbar image draggable
    $house.draggable({
        helper:'clone',
    });

    // set the data payload
    $house.data("myName","The House"); // key-value pair

    // make the Kinetic Container a dropzone
    $stageContainer.droppable({
        drop:dragDrop,
    });

    // handle a drop into the Kinetic container
    function dragDrop(e,ui){

        var element=ui.draggable;
        var draggable=element.data("myName");

        if(dropTarget){
            alert(draggable+" was dropped on the "+dropTarget.dropMessage);
        }else{
            alert("You didn't hit a drop polygon.");           
        }
    }

    var dropTarget=null;
    var pts;

    pts=[180,150, 165,176, 135,176, 120,150, 135,124, 165,124];
    var poly1=makeDropzone("green",pts,"green hexagon");

    pts=[200,250, 240,200, 280,250];
    var poly2=makeDropzone("red",pts,"red triangle");


    function makeDropzone(color,points,dropMessage){
        var poly=new Kinetic.Polygon({
            points:points,
            stroke:color
        });
        poly.dropMessage=dropMessage;
        poly.on("mouseenter",function(){
            dropTarget=this;;
        });
        poly.on("mouseleave",function(){
            dropTarget=null;
        });
        layer.add(poly);
        layer.draw();
        return(poly);
    }

}); // end $(function(){});
</script>       
</head>
<body>
    <h4>Drag from blue toolbar to polygon</h4>
    <div id="toolbar">
        <img id="house" width=32 height=32 src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house32x32transparent.png"><br>
    </div>
    <div id="container"></div>
</body>
</html>

Upvotes: 2

Related Questions