Skip to content Skip to sidebar Skip to footer

Kineticjs Canvas - Scale Group From Center Point

I want to scale my group (image and something). group.setScale(zoom, zoom); http://jsfiddle.net/K8nK3/ But when i scale my group, I think it's not scale from center of my group.

Solution 1:

[Edited to better fit questioner's needs]

Here’s how to scale a Kinetic group from the centerpoint

First we store the centerX and centerY of the original group so we can keep the group centered there:

group.cx=group.getX()+group.getWidth()/2;
      group.cy=group.getY()+group.getHeight()/2;

Then we write a custom scaling method that both scales the group and re-centers it:

group.scale=function(x,y){
          group.setScale(x,y);
          group.setPosition(
              group.cx-group.getWidth()/2*group.getScale().x,
              group.cy-group.getHeight()/2*group.getScale().y);
          group.draw();
      }

Here’s code and a Fiddle: http://jsfiddle.net/m1erickson/dVGGz/

<!DOCTYPE HTML><html><head></head><body><buttonid="larger">Larger</button><divid="container"></div><scriptsrc="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.4.0.min.js"></script><scripttype="text/javascript"src="http://code.jquery.com/jquery.min.js"></script><script>
    $(function(){
      var stage = newKinetic.Stage({
        container: 'container',
        width: 400,
        height: 400
      });
      var layer = newKinetic.Layer();

      // Be sure to set width and height// They are required for this method to workvar group = newKinetic.Group({
        x: 100,
        y: 100,
        width:100,
        height:100
      });
      // store the original group center// so we can center the group there
      group.cx=group.getX()+group.getWidth()/2;
      group.cy=group.getY()+group.getHeight()/2;
      // custom scale function to both// scale the group and center the results
      group.scale=function(x,y){
          group.setScale(x,y);
          group.setPosition(
              group.cx-group.getWidth()/2*group.getScale().x,
              group.cy-group.getHeight()/2*group.getScale().y);
          group.draw();
      }

      var box1 = newKinetic.Rect({
        x: 0,
        y: 0,
        width: 50,
        height: 50,
        fill: "blue",
        stroke: 'black',
        strokeWidth: 4
      });
      group.add(box1);

      var box2 = newKinetic.Rect({
        x: 50,
        y: 50,
        width: 50,
        height: 50,
        fill: "green",
        stroke: 'black',
        strokeWidth: 4
      });
      group.add(box2);

      layer.add(group);
      stage.add(layer);

      var scaleFactor=1;
      $("#larger").click(function(){
          scaleFactor+=0.10;
          group.scale(scaleFactor,scaleFactor);
          console.log(scaleFactor);
      });

});

    </script></body></html>

Solution 2:

Have you tried to use offset property? i.e. offset: [width/2, height/2]

Solution 3:

Problem #1: I need to scale a group from its center. Problem #2: Kinetic JS group.getWidth() and group.getHeight() don't work unless you explicitly set the width at creation. Problem #3: I don't know the width and height, I'm dynamically changing the shapes.

This means in order to try your code out, I'll have to write my own getWidth and getHeight functions. Then I can use the method you propose.

Solution below.

(There may be a better way, but this is my level of programming right now . . . if anyone can add recursion to this to look through groups that contain groups that contain groups etc, that would be great.)

varresults= getGroupMinsAndMaxes(myKineticGroup);
console.log('results: '+ results.groupMinX, results.groupMaxX, 
     results.groupMinY, results.groupMaxY);



function getGroupMinsAndMaxes( group ) {

   // note this does not handle children that are groups, // it expects children to be shapesvar item;
   vargroupMinX=99999;
   vargroupMaxX= -99999;
   vargroupMinY=99999;
   vargroupMaxY= -99999;
   varshapeFunctionDefinition='';
   varbounds= {};

   for (vari=0; i < group.children.length; i++ ) {

       item = group.children[ i ];
       if ( item.getType() !== 'Shape' ) {

            alert('The getGroupMinsAndMaxes function is not designed to handle groups that contain groups.');
            break;

       } else {

            shapeFunctionDefinition = item.attrs.drawFunc.toString();

            bounds = getShapeMinsAndMaxes( shapeFunctionDefinition );

            if ( bounds.shapeMinX < groupMinX ) { groupMinX = bounds.shapeMinX; }
            if ( bounds.shapeMaxX > groupMaxX ) { groupMaxX = bounds.shapeMaxX; }
            if ( bounds.shapeMinY < groupMinY ) { groupMinY = bounds.shapeMinY; }
            if ( bounds.shapeMaxY > groupMaxY ) { groupMaxY = bounds.shapeMaxY; }

        }
   }

    return {
            groupMinX: groupMinX,
            groupMaxX: groupMaxX,
            groupMinY: groupMinY,
            groupMaxY: groupMaxY
        };

}

function getShapeMinsAndMaxes( shape ) {

   // the shape definition is passed as a stringvarregex= /[+-]?\d+\.\d+/g;

    varfloats= shape.match(regex).map(function (v) {
        return parseFloat(v);
    });

   // preset some unrealistically large numbers which // we will never encountervarshapeMinX=99999;
    varshapeMaxX= -99999;
    varshapeMinY=99999;
    varshapeMaxY= -99999;


    for (vari=0; i < floats.length; i++) {

        if (isOdd(i)) {

            // Check Y valuesif (floats[i] < shapeMinY) {
                shapeMinY = floats[i];
            }
            if (floats[i] > shapeMaxY) {
                shapeMaxY = floats[i];
            }

        } else {

            // Check X valuesif (floats[i] < shapeMinX) {
                shapeMinX = floats[i];
            }
            if (floats[i] > shapeMaxX) {
                shapeMaxX = floats[i];
            }

        }
    }

    return {
            shapeMinX: shapeMinX,
            shapeMaxX: shapeMaxX,
            shapeMinY: shapeMinY,
            shapeMaxY: shapeMaxY
        };

}


function isOdd(num) {
    return num % 2;
}

Solution 4:

the easiest way would be to reposition / center the offset. all scaling and moving will be based on your new offset position.

group.offset( { x: group.width() * .5, y: group.height() * .5 } );

http://kineticjs.com/docs/Kinetic.Group.html

Post a Comment for "Kineticjs Canvas - Scale Group From Center Point"