Jump to content

Pinch to zoom


Batzi
 Share

Recommended Posts

So I added HammerJS in my project and got it working. I am trying to zoom in/out to/from a specific point when I am pinching in/out.

 

Basically I need to calculate the midpoint between my 2 fingers. So I did something like this

var x1 = game.input.pointer1.worldX;var y1 = game.input.pointer1.worldY;var x2 = game.input.pointer2.worldX;var y2 = game.input.pointer2.worldY;var middleX = (x1+x2)/2;var middleY = (y1+y2)/2;

This gives me the point I need to zoom in/out to/from.

 

Keep in mind I using scale to do so and I am doing something like

if(pinchin){scale-=0.05;}else if(pinchout){scale+=0.05;}

I also have a group of sprites that I am scaling everytime pinch is executed.

 

Here's the tricky part, that middle point (x,y) that I am getting changes on scale so I need to get the point after the scale and move the camera accordingly.

 

If I do something like

game.camera.x = middleX * scale;game.camera.y = middleY * scale;

It doesn't really work well. In fact, it is not accurate at all and the camera moves in a weird way.

 

 

How would you do it and what am I missing?

 

 

Link to comment
Share on other sites

Well, i'm not sure but i think it's because you're using game.input.pointer*.world* 

In my current project, my phaser game is not fullscreen and pointer coordinates are always like that 0 < worldX < GameWidth & 0 < worldY < GameHeight

Just try do display pointers coordinates for corners at different scales. 

Link to comment
Share on other sites

Can you please elaborate a bit more on that point?

Of course  ;)

 

Step 1: Make a run at scale 1 (no scale), click on top-left corner and display pointer coordinates (worldX, worldY), it should be nearly (0, 0). Then click on bottom-right corner and display pointer coordinates

Step 2: Make a run at scale 2, click on top-left corner and display pointer coordinates. Click on bottom-right corner and display pointer coordinates (for me values are same for steps 1 & 2).

Step 3: well, take a break  :D

Link to comment
Share on other sites

Of course  ;)

 

Step 1: Make a run at scale 1 (no scale), click on top-left corner and display pointer coordinates (worldX, worldY), it should be nearly (0, 0). Then click on bottom-right corner and display pointer coordinates

Step 2: Make a run at scale 2, click on top-left corner and display pointer coordinates. Click on bottom-right corner and display pointer coordinates (for me values are same for steps 1 & 2).

Step 3: well, take a break  :D

If you place your finger on the map and the coordinates of your finger in game are (20,30) and you do a scale, it should not remain the same coords in game. The camera is moving on scale.

Link to comment
Share on other sites

I understand what you want to do, but not sure Phaser framework understand things like us  :lol:

 

Try to scale without moving camera and check coordinates to ensure things are varying the way you think. 

Going to zoom to the cursor's coords. Easier for me to test.

 

EDIT

 

I was reading this article http://gamedev.stackexchange.com/questions/9330/zoom-to-cursor-calculation

 

Second answer at the bottom of the page suggests a solution and here's a sample of the code

var newX = (cursor.X * newZoomLevel) - mouseinWorld.X;var newY = mouseinWorld.Y - ((cursor.Y - screen.Height) * newZoomLevel)

What is the difference between cursor.X and mouseinWorld.X?

 

Is it this

game.input.activePointer.x;game.input.mousePointer.x;game.input.mousePointer.worldX;
Link to comment
Share on other sites

In your first post, you compute middle of fingers like this: 

var x1 = game.input.pointer1.worldX;var y1 = game.input.pointer1.worldY;var x2 = game.input.pointer2.worldX;var y2 = game.input.pointer2.worldY;var middleX = (x1+x2)/2;var middleY = (y1+y2)/2;

For me, the middle of fingers is relative to the cursor position (you move your fingers on what you see on screen).

Then, you have to place this point on the whole scene using current translation and scale (you know how much your sprite is moved and zoomed). Then you can compute new zoom factor and new camera position. 

Link to comment
Share on other sites

In your first post, you compute middle of fingers like this: 

var x1 = game.input.pointer1.worldX;var y1 = game.input.pointer1.worldY;var x2 = game.input.pointer2.worldX;var y2 = game.input.pointer2.worldY;var middleX = (x1+x2)/2;var middleY = (y1+y2)/2;

For me, the middle of fingers is relative to the cursor position (you move your fingers on what you see on screen).

Then, you have to place this point on the whole scene using current translation and scale (you know how much your sprite is moved and zoomed). Then you can compute new zoom factor and new camera position. 

The coords I posted are for the mousewheel function which is logging the cursor's coords. I am trying to do it using the mousewheel cause it is easier for me to test and console log. The logic shouldn't be that different from wheel to pinch.

 

So if we take the mouse pointer's coords (input.mousePointer.x/y), I want to zoom to that point, the cursor.

 

Would you deal with it like pinch? (move cursor on what I see on screen)

 

If so, on scale, that x/y is not changing.

Link to comment
Share on other sites

Well, i try to explain how i handle this in my current project. So i had to implement: tap on image, 2 fingers scroll & pinch to zoom.

 

I have to display a 800*600px image in a 350*262px game. (game and image are homothetic)

 

so i do this:

- compute "screen ratio": image.width / game.width

- image fully displayed on screen = scale 1 (you see the whole image without scrolling)

- when scrolled, keep translation values in array = trans[x, y]

- when pinch:  out -> scale * 1.1, in -> scale / 1.1

- pointers positions: use (X, Y) and not (worldX, worldY) and compute position on "full size image" (means 800*600px in my case) with this formula:

Ximage = (Xpointer * ratio - trans[x]) / scale

 

So, pointer position is something like that: 0<Xpointer<350 and i "map" it to 0<Ximage<800 

 

I hope it will help.

Link to comment
Share on other sites

Well, i try to explain how i handle this in my current project. So i had to implement: tap on image, 2 fingers scroll & pinch to zoom.

 

I have to display a 800*600px image in a 350*262px game. (game and image are homothetic)

 

so i do this:

- compute "screen ratio": image.width / game.width

- image fully displayed on screen = scale 1 (you see the whole image without scrolling)

- when scrolled, keep translation values in array = trans[x, y]

- when pinch:  out -> scale * 1.1, in -> scale / 1.1

- pointers positions: use (X, Y) and not (worldX, worldY) and compute position on "full size image" (means 800*600px in my case) with this formula:

Ximage = (Xpointer * ratio - trans[x]) / scale

 

So, pointer position is something like that: 0<Xpointer<350 and i "map" it to 0<Ximage<800 

 

I hope it will help.

Thank you for taking the time to explain your method. Quick question, the XImage is the new x of the camera? Are you using the camera at all?

 

EDIT: What do you mean with when scrolled and translation values in array? Can you elaborate that point please? Thank you! :)

Link to comment
Share on other sites

My case is a bit different from yours but the "idea of zooming" is the same. In my project, i don't move camera, i just zoom & move an image (using a sprite). 

But i think i can keep image in fixed position and move camera, the logic will stay identical. No? (it's monday morning, my brain is still sleeping :lol: )

 

Anyway, just look this image:

KaRaG.png

 

On img2,  you see half image so you can scroll to right to see the remaining. In my project, i keep track of this scroll value (it's what i called translation). 

So camera's position is center of screen and i move image according to scrolling and zoom. When i click on image, i convert pointers positions ("what i see") to image position ("reality"). 

 

Don't sure it's crystal clear (again, it's monday morning  :huh:  )

Link to comment
Share on other sites

My case is a bit different from yours but the "idea of zooming" is the same. In my project, i don't move camera, i just zoom & move an image (using a sprite). 

But i think i can keep image in fixed position and move camera, the logic will stay identical. No? (it's monday morning, my brain is still sleeping :lol: )

 

Anyway, just look this image:

KaRaG.png

 

On img2,  you see half image so you can scroll to right to see the remaining. In my project, i keep track of this scroll value (it's what i called translation). 

So camera's position is center of screen and i move image according to scrolling and zoom. When i click on image, i convert pointers positions ("what i see") to image position ("reality"). 

 

Don't sure it's crystal clear (again, it's monday morning  :huh:  )

Are you zooming to a specific point in img2? Can you zoom in to let's say the letter 'e' in that image?

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...