androidlibgdx

How to zoom Actor in ScrollPane in libGDX


I have game field which is a Group with Actors. The Group located in Table which is located in ScrollPane. I have two Buttons to zoom in and zoom out the game field. Here is my code how I do it:

    TextButton zoomInBtn = new TextButton("+", menuBtnStyle);
    zoomInBtn.addListener(new ClickListener() {
        @Override
        public void clicked(InputEvent event, float x, float y) {
            float width = fieldGroup.getWidth();
            float height = fieldGroup.getHeight();
            float newWidth = width + width * 0.1f;
            if (newWidth > myWorld.getMaxWidth()) {
                newWidth = myWorld.getMaxWidth();
            }
            float newHeight = height * newWidth / width;
            fieldGroup.setWidth(newWidth);
            fieldGroup.setHeight(newHeight);
            myWorld.setWidth(Math.round(newWidth));
            fieldGroup.reinitialiseChildren();
            Cell cell = fieldTable.getCell(fieldGroup);
            cell.clearActor();
            cell.setActor(fieldGroup);
        }
    });
    TextButton zoomOutBtn = new TextButton("-", menuBtnStyle);
    zoomOutBtn.addListener(new ClickListener() {
        @Override
        public void clicked(InputEvent event, float x, float y) {
            float width = fieldGroup.getWidth();
            float height = fieldGroup.getHeight();
            float newWidth = width - width * 0.1f;
            if (newWidth < myWorld.getMinWidth()) {
                newWidth = myWorld.getMinWidth();
            }
            float newHeight = height * newWidth / width;
            Actor widget = scrollPane.getWidget();
            
            fieldGroup.setWidth(newWidth);
            fieldGroup.setHeight(newHeight);
            myWorld.setWidth(Math.round(newWidth));
            fieldGroup.reinitialiseChildren();
            Cell cell = fieldTable.getCell(fieldGroup);
            cell.clearActor();
            cell.setActor(fieldGroup);
        }
    });

I change the size of my fieldGroup with Image Actors in it. And then reading it to Table.

The problem is: when I zoom with buttons it always zoom around left corner. I want it to zoom from canter of ScrollPane. I know that I can do it with Orthographic Camera, but it would be difficult, I think, to make it movements so smooth as ScrollPane. So maybe there is some way to do it with ScrollPane.


Solution

  • Every time you zoom in or out you would have to change the x and y position of the group relative to the zoom. You can do this using the setScrollx (and y) of your scroll pane.

    You need to set so that the middle of the part you are viewing stays in the middle of the scrollpane. You can work out middle of newWidth by dividing it by 2. If the scrollPane is fullScreen you can half the value obtained by Gdx.graphics.getwidth();. The difference between these two is then the value which will keep the middles aligned.

    newXvalue =(newWidth/2) - ((Gdx.graphics.getWidth())/2);
    scrollPane.setScrollx(newXvalue);
    

    The same should be done for y.

    Note: if you want to zoom and move at same time, this will not work, I would recommend using orthographic camera with a gesture listener for that.