0

I have an image (the blue box) and ad red rectangle. The image's offset is set to the center of the image to make rotation around the center of the image. The code is similar to the following:

var image = new Kinetic.Image({
x: 200,
y: 100
});
image.offsetX(100);
image.offsetY(50);

var rect = new Kinetic.Rect();

var group = new Kinetic.Group();

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

The stage than looks something like this:

enter image description here

After I rescale the image with

image.scaleX(0.5);
image.scaleY(0.5);

I get the following:

enter image description here

The red rectangle is not attached to the image anymore.

I could do

rect.scaleX(0.5);
rect.scaleY(0.5);

but this would change the size of the rect.

How do I rescale the image and keep the rectangle attached to the same position as before?

Edit:

The following image shows what it should look like after the image scaling. Event after the scaling the red rectangle should be attached to the image.

enter image description here

Michael
  • 32,527
  • 49
  • 210
  • 370
  • Could you describe what you want to happen? If you want to scale both image and rect while maintaining relative positions you could scale the group that they are both inside. – markE Mar 17 '14 at 00:29
  • @markE I want to scale only the image (blue box). While scaling the image the red box should be attached to the blue box as before. – Michael Mar 17 '14 at 00:46
  • Ok, thanks for the clarification -- I understand now...please see my answer for a solution. Cheers! – markE Mar 17 '14 at 06:11
  • @markE I commented your answer! – Michael Mar 17 '14 at 12:47

2 Answers2

1

If you want the red rect to be centered in the top-left of the blue image after scaling the image, you will need to listen for changes in the images scaleX and scaleY properties.

You can listen for scaleX / scaleY property changes like this:

image.on("scaleXChange scaleYChange",function(){
    // either scaleX or scaleY has changed on this image
});

Then you can reposition the rect to be centered on the images top-left corner like this:

image.on("scaleXChange scaleYChange",function(){
    var imgX=this.x()-this.offsetX()*this.scaleX();
    var imgY=this.y()-this.offsetY()*this.scaleY();
    rect.position({x:imgX-rect.width()/2,y:imgY-rect.height()/2});
})

Here's a Demo: http://jsfiddle.net/m1erickson/6H9aK/

enter image description hereenter image description here

markE
  • 102,905
  • 11
  • 164
  • 176
  • That work but what if the red rectangle is a group that contains other shapes. Do I have to adjust each shapes position separately? The problem is that group.width() is zero. – Michael Mar 17 '14 at 12:42
  • If you want to scale both image and rect while maintaining relative positions you could put both red and blue inside a group and scale that group. – markE Mar 18 '14 at 17:15
  • I don't want to scale the red rectangle. It should only keep the position on the blue rect. The red rect is in a group which contains only the red rectangle. How can you do your solution with the group of the red rectangle instead of the red rect itself? – Michael Mar 18 '14 at 17:22
  • 1
    OK, if you want the red group to reposition relative to the scaled blue, then you must set a width and height to the red group--no other option. Then you can use the same code in my answer--just replace rect with red-group. Cheers! – markE Mar 18 '14 at 17:45
  • thank you. May be you have an idea on this issue too http://stackoverflow.com/questions/22481870/kineticjs-how-to-import-iphone-retina-images-taken-by-camera – Michael Mar 18 '14 at 18:47
  • You're welcome! I may be the only person in the world who doesn't have an iPhone, but I do know the retina display is 2x the normal. You might check out this set of previous SO answers: http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios – markE Mar 18 '14 at 19:07
  • I did not see how I can combine this with KineticJs – Michael Mar 18 '14 at 20:06
  • Keep in mind that an offscreen html5 canvas can be the source for a Kinetic.Image. That's how to link the post with KineticJS. Anyway, like I said, my iPhone knowledge is limited. Good luck with your project! – markE Mar 18 '14 at 20:10
  • Ok thank you! How to I generate a Kinetic Image from a Canvas? – Michael Mar 18 '14 at 23:09
  • 1
    (1) Get a reference to any canvas element: var canvas=document.getElementById("anyHtmlCanvas"); (2) set the image property on a Kinetic.Image to that reference: var img=new Kinetic.Image({ image: canvas ... – markE Mar 18 '14 at 23:12
  • Your solution in the link also worked. If you post it to my other question I can give you credit for that too. – Michael Mar 19 '14 at 00:01
  • Thanks, I'll post on your linked question also...Cheers! – markE Mar 19 '14 at 00:03
0

Do this instead to apply the scaling to both x and y axes at the same time, rather than scaling one first, then the other:

rect.scale({x:0.5,y:0.5});

thinkbigthinksmall
  • 894
  • 5
  • 10
  • 19