Question

I'm new to kineticjs and am having issues doing what seems to be a trivial operation: making the canvas update when changes are made to the objects drawn to it.

I have a loop that creates some circles with numbers in them, both contained in a group. When I click on the groups I want them to scale and move around. (In my current version the movement is the same one from the kinetic tutorial.) I also have two text boxes that will display the x,y coordinate of the group when the group is clicked and update the shape coordinate when the text box values are changed. The text boxes get the values of the clicked groups, but if you change the value the shape doesn't move to the proper location. I'm sure I'm just missing something obvious, but I can't for the life of me figure out what it is.

HTML

<html>  
<head>  
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">

<title>TEST</title> 

<script src="js/jquery-1.10.2.js"></script>
<script src="Libraries/kinetic-v5.1.0.min.js" type='text/javascript'></script>

<script  src="KineticTest.js" type='text/javascript'></script>

<script type='text/javascript'>
window.onload = function(){
    Startup();
}

</script>

 </head>  
 <body>  
<br/>
<h1>TEST</h1>
<input id="x" type="text" value="3" onkeyup='UpdateCircle();'/>
<input id="y" type="text" value="3" onkeyup='UpdateCircle();'/>

<div id="holder" style="height:1000px; width:1000px;"></div>
</body> 

</html>

KineticTest.js

function Startup(){

    // Create a collector to store the created groups
    var ObjGroup = [];

    // Create a stage
    var stage = new Kinetic.Stage({
        container: 'holder',
        width: 1200,
        height: 1200
      });

    // Create a layer to draw stuff to
    var layer = new Kinetic.Layer();

    var ctr = 0;

    // Create a square array of circles with text in them
    for (var i=0; i<5; i++){
        for (var j=0; j<5; j++){
            var r = 15;
            var x = 3*r * i + 2*r;
            var y = 3*r * j + 2*r;

            var group = new Kinetic.Group({
                id: ctr
            });

            // Create a circle
            var circle = new Kinetic.Circle({
                x: 0,
                y: 0,
                radius: r,
                fill: 'lightblue',
                stroke: 'black',
                strokeWidth: 1
              });

            // Create a label
            var label = new Kinetic.Label({
                x: 0,
                y: 0+10,
                rotation:270
            });

            // Create a text element
            var text = new Kinetic.Text({
                  x: 0,
                  y: 0,
                  text: ctr,
                  fontSize: 10,
                  fontFamily: 'Calibri',
                  fill: 'black',
                  align: 'center'
              });

            // add the text element to the label  
            label.add(text);

            // ad the circle and label to the group
            group.add(circle);
            group.add(label);

            // set the x,y location of the group
            group.setX(x);
            group.setY(y);

            // Create a transformation tween to move the group
            group.tween = new Kinetic.Tween({
                node: group, 
                duration: 1,
                x: 400,
                y: 30,
                rotation: 360,
                opacity: 1,
                strokeWidth: 6,
                scaleX: 1.5
              });


            // Create the event handler for clicking on the groups
            group.on('click', function(){
                // Get the selected object
                window.SelectedObjId = this.attrs.id; 

                // Set the text box values
                $('#x').val(this.attrs.x);
                $('#y').val(this.attrs.y);

                // Run the animation
            this.tween.play();
            });

            // Add the group to the layer
            layer.add(group);

            // Add the group to an array so I can find it later
            ObjGroup.push(group);

            ctr++;
        }

    }
      this.ObjGroup = ObjGroup;

   // add the layer to the stage
      stage.add(layer);




}


function UpdateCircle(){
    // This function is called when the user changes the values in the text boxes
    var x = $('#x').val();
    var y = $('#y').val();

    for (var i=0; i<ObjGroup.length; i++){
        var group = ObjGroup[i];
        if (group.attrs.id == window.SelectedObjId){
            group.setX(x);
            group.setY(y);
        }
    }

}
Était-ce utile?

La solution

The tween wasn't working correctly using your code. I fixed that by putting the tween binding, inside the click event. Note that this is not really a good solution, now a new tween gets added on every click. At least it got it quickly working for me...

Actually to answer your question, the changed value of the shape does not get visually updated. You have to call the draw function itself on shape, layer, stage (any container) of itself and it's children which you want redrawn.

I think changing your if statement in the updateCircle function to the following should do it:

    if (group.attrs.id == window.SelectedObjId){
        group.setX(x);
        group.setY(y);
        layer.draw();
    }

Furthermore, assigning properties to the global window object is a bad practise (the selected group in your case). In the outer scope, I create a variable selectedGroup, which get assigned also during the click event. This variable is then used in the keyup event to check what group needs to be changed from position.

See also the fiddle for a working example: http://jsfiddle.net/BsK7Q/

Mind you, there still seem to be a few checks you need to, such as checking if it is a real number.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top