Kineticjs Canvas - Scale Group From Center Point
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 } );
Post a Comment for "Kineticjs Canvas - Scale Group From Center Point"