3
votes

I am currently trying to create an algorithm that will center the viewport on the content present on the Stage.

Lets say the stage is initiated and it looks like this

I can get it to this point where the stage is centred over all shapes on the stage

Now I need a way to figure out how far to zoom the stage so that none of the shapes are cut off by the "viewport"

Getting the origin/most central point in regards to every shape on the map is straight forward and I can get that far. I am having trouble figuring out a proper calculation to scale the stage such that each Shape on the stage is visible (plus some extra padding)

I am having a real tough time visualizing an answer mathematically in my head. The only solution I have came up was to create rectangles from the view and the objects on the stage and brute forcing an answer so that the edges of the view does not intersect any shapes on the stage.

Any guidance would greatly be appreciated

1

1 Answers

5
votes

You can try to use something like this:

// do we need padding?
const padding = 10;

// get bounding rectangle
const box = layer.getClientRect({ relativeTo: stage });
const scale = Math.min(
  stage.width() / (box.width + padding * 2),
  stage.height() / (box.height + padding * 2)
);


stage.setAttrs({
  x: -box.x * scale + padding * scale,
  y: -box.y * scale  + padding * scale,
  scaleX: scale,
  scaleY: scale
});

http://jsbin.com/kobilamoro/2/edit?js,output