Mensur Grišević Mensur Grišević - 5 months ago 67
Javascript Question

Zoom to cursor position PIXI.js

I'm working on a game and I want to implement a zooming feature.
The game is built with PIXI.js.

I have a PIXI.Stage and a PIXI.DisplayObjectContainer added to it.
My problem is that I don't have the slightest idea on how to focus the DisplayobjectContainer to where my mouseCursor is, when scaling it.
The default scaling factor is 1.
I change it by 0.03 or -0.03 per tick.

Thank you in advance.

Answer

Well, I may be kind of late, but this is how I do it. This is part of a bigger system and I adapted the code to the awnser, so if this doesn't work by itself please tell and I will try to help:

//call this just at the start to register event callbacks
cameraInit:function() {
    map.mousemove = map.touchmove = function(data) {
        globalMousePosition = data.getLocalPosition(pixiWindow);
    }
}

//call this every frame
cameraUpdate:function() {

    if (Math.abs(mapScaleTarget - map.scale.x) >= 0.02) {
        if(!zoom_on_prev_frame){
            //zoom started, do something you want here
        }

        localMousePosition = views.toLocal(globalMousePosition);

        if (map.scale.x > mapScaleTarget) {
            map.scale.x -= zoomSpeed;
            map.scale.y -= zoomSpeed;
        } else {
            map.scale.x += zoomSpeed;
            map.scale.y += zoomSpeed;
        }

        map.position.x = -(localMousePosition.x * map.scale.x) + globalMousePosition.x;
        map.position.y = -(localMousePosition.y * map.scale.x) + globalMousePosition.y;

        zoom_on_prev_frame = true;
    }else{
        if(zoom_on_prev_frame){ 
            //zoom ended, do something you want here
            zoom_on_prev_frame = false;
        }
    }
}

So, there are 4 variables that I am using that are not declared here.

zoomSpeed - is the percentage that is zoomed each frame (0.03 in your case).

mapScaleTarget - is the target you are aiming to get to with the zoom. (so, if your scale is 0.3 and you set it to 1.0, it will zoom zoomSpeed each frame until the scale is 1.0)

pixiWindow - is a DisplayObjectContainer that is basically the father of everything and you never touch

map - is a DisplayObjectContainer, child of pixiWindow, and the actual object you are scaling.

This basically works by repositioning the layer after it scales, so the position of the mouse before the zoom stays the same after the zoom. The reason why a parent and child objects are used is because then you can have objects that are not scaled (like GUI elements) by simply making them children of pixiWindow and not of map.

If you want a early example of this when I started working on this problem you have this here with similar code, but however also includes drag to move the map and correct window resizing (can see the code by inspecting the page):

http://dl.dropboxusercontent.com/u/23574503/pixitests/index.html

I know this is a more complicated awnser that would maybe be needed for a simple case, but hope this helps.

Comments