Best way to implement zoom

I’ve implemented zooming into the game I’m working in a way I found that works, scaling the display layer up or down in response to the zoom request. I feel like this isn’t a great way to do it and I’m running into issues with it, making my view management more complicated than it seems is necessary.

I’m wondering if there is a recommended way of implementing zoom?

It’s a good way, why not? What issues do you run into?

The “I feel like this isn’t a great way” is all about the feel. It’s just a way I implemented that works, in another engine you might, for instance move the camera either closer or further away to achieve the same effect. So I was looking to see if there was a standard way or even another possible way.

The specific issue that I’ve run into that is causing me some grief is below:

I’m working on a desktop to I’ve implemented mouse control along with a cursor that’s on the screen regardless of the “zoom” of the display layer. I’ve implemented this as a separate layer which I’m calling the ui layer. I’ve just finished implementing a popover that displays in the ui layer but over a specific position in the display layer. This position must remain the same whether the display layer is subsequently zoomed or translated. I’ve handled the translation by also translating the appropriate popover objects at the same time.

For the zoom though… I’m not sure how to update the position of the popover in the ui layer to match the effect of the scaling of the display layer. I haven’t looked into solving this much yet, but I wasn’t sure that scaling was the only way to achieve a zoom effect and another way might be easier to work with.

Any suggestions on how to calculate and update the position of a popover in the ui layer such that it remains visually at the same position while the display layer is scaled?

I don’t think you should worry about this implementation. It’s a legit implementation and also probably the most used zoom method in 2D engines. Usually in 2D engines, most used design patterns and methods don’t move the camera around, just move and scale items so that certain effects are simulated.

Now for your UI problem, you will need to do some calculations depending on the anchor point of the layer or node that gets zoomed, but it shouldn’t be hard. I didn’t understand exactly what you want to achieve, so when you will try to solve the problem, if you won’t manage, try to come with a more detailed explanation, maybe an example sketch.

Alright, fair advice. I’ll report back here once I work out the correct process for mapping the locations between the popovers in the ui layer and the zooming of the display layer.

I’ve got this working now and it was really quite straightforward once I thought about it. What I did was:

  1. Converted the position of each UI node to its position in the display layer and held onto it
  2. Scaled the display layer
  3. Converted the saved display layer position for each into world coords and then into the ui layer’s node space
  4. Set the UI element to this calculated position
auto uiPos = uiLayer->convertToWorldSpace(uiElem->getPosition);
auto preScaleDisplayLayerPos = displayLayer->convertToNodeSpace(uiPos);
displayLayer->scale(amount);
auto scaledWorldPos = displayLayer->convertToWorldSpace(preScaleDisplayLayerPos);
auto finalUIPos = uiLayer->convertToNodeSpace(scaledWorldPos);
2 Likes

Hi @radman , I am also trying to implement zooming in/out, would you mind elaborating a little bit more on this?:

displayLayer->scale(amount);

Alos, how do you handle min and max scale, and boundaries when you zoom in/out near one of the edges of the layer? Thanks!

1 Like

Essentially you have the screen dimensions and position which are static and the layer position and dimensions which are variable relative to the screen. What I do is check after each zoom or movement if the relevant bounds of the layer have moved out of the viewable area of the screen (minx, miny, maxx, maxy of the layer). If they have then I set the position of the layer such that the maximum values are at the bounds of the screen.

Hope that helps.

Ok, thanks, I’ll get back to this post once I’ve done more work on the zooming.