Jump to content

Camera Zoom to Mouse Pointer


Recommended Posts

So, I've looked at a ton of examples on zooming, but it's not quite what I'm looking for.  What I want is to have the camera zoom in on the mouse pointer and then be bound to the world.  So if the bounds aren't hit, it should zoom in and the object under your mouse should be the same distance from the center of the camera.


I've got a Fiddle Here: http://jsfiddle.net/5wex2cdn/1EDIT:  I forgot to hit update <=


I think my math is just incorrect or I'm not accounting for something.  The idea is that I take the worldState group and scale that.  In CAMERA.zoom_mousewheel() it takes the mouse pointer, gets the distance from the center of the screen and then scales the world (while taking into account previous scale factor and next scale factor to get the relative scaling.)  And then it adds the Adjustment distance after scaling the non-UI game group.  


I've been racking my brain on this and I know I'm just missing something simple here, so if anyone wants to take a look and perhaps can see what I'm missing, the camera JUST doesn't work quite right.  


This current iteration is the closest I've gotten it, but I know it's not doing what I expect it to.  The fiddle also has flick movement added in so but you can ignore that outside of the mousewheel stuff.  Also there are probably functions for pinch zoom in the CAMERA.js section, but that's not implemented/worked on yet.  Once I figure out the math I'll work on the touch controls.


Thanks and nice to meet you all since I'm new here!


-Jason Carter / WakeskaterX

Link to comment
Share on other sites

i would love to see your approach but the linked jsfiddle doesn't support zooming..  there is just panning the world...  


as you probably already found out i also tried to wrap my head around this..  http://www.html5gamedevs.com/topic/8762-zoom-outin-camera-as-seen-in-angry-birds/



here is btw. a testexample where the camera is bound to the world - it zooms in at the very center of the camera atm.   the moment i try to zoom in at the mouse pointer it gets really weird ^^


Link to comment
Share on other sites

Hey Value,  I actually saw your post when I was researching it but it only had touch support so far and I'm testing mouse wheel first.


OOPS!  I forgot to actually update the fiddle, that was the original forked one off my old fiddle.  I've updated the link and it should support zooming.



As you can see it is also a bit wonky.  I think this is just due to math errors.  I know I'm missing something but my brain keeps seeing the same thing hah!

Link to comment
Share on other sites

i see..  i just updated the fiddle to support mousewheel zoom (didn't know that this is now possible) and tried (again) to get the map to zoom to a specific point or better..  to get the camera center to keep a relative distance to this point..  no luck on my side :)   can't be that hard.. i guess it's just a knot in my brain ^^

Link to comment
Share on other sites

Nice!  I like the easing.  Although the way I was trying to implement this wouldn't work fairly well.  So what I was doing was taking the previous map location and getting the center point and then adjusting the worldState scale and camera location to point to the same location as the previous point, but adjusted to match the distance that the point the mouse is at is from the center of the camera view.


Now that I've had an alcoholic beverage or two though, I think I know what I'm doing wrong.  I need to adjust the camera in the OTHER direction that matches the distance the mouse is from the center in the previous scale less the distance the mouse is from the center in the new scale.


HMM!! I'll wait until I'm sober tomorrow and re-read this to see if that makes any sense!

Link to comment
Share on other sites

So my slightly drunk brain had the right idea:




What I needed to do was take the difference of the scales.  And get that Vector from the center of the camera to the mouse position, and adjust the camera by the difference vector to bring the location that SHOULD be there to the same point as the mouse position.


IMAGE for clarity:



So Vector C is the new location once you just scale down the world and set the camera point to the same scaled point.  So THEN you need to adjust the center point by Vector D (actually in the same direction, not in the opposite one, but you get the idea.


And Voila!  It's working decently well!  Because the world binds, it makes it a little wonky but with easing this would probably look better.



EDIT:  Here's the latest one with HammerJS added, I can't get the pinch to work on my phone, but I tried to replicate the math, you can test it if you want.

Link to comment
Share on other sites

i have to admit i dont get the math :)   i tried the jsfiddle (copied it to play with it )  and i'm unsure about the result..  it looks like it does the right thing but not exactly..    if i move the mousepointer to the top left of one of the boxes and start scrolling the point in the topleft of the box should stay inside the camera view .. right??    i think the target should be zooming like it can be seen on google maps https://www.google.at/maps/


unfortunaltely i have so much other things to do right now but i will definitely come back to your code and have a deeper look into it..  thx btw.   :)

Link to comment
Share on other sites

oke.. i couldn't help myself and wastet (again) some time on this .. haha..    http://jsfiddle.net/valueerror/pdx0px0w/


basically i just implemented what you did (with easing) but i added the rescale factor (this is just a try because of the lack of knowledge)    


the problem i saw (only visible with large differences in the scale factors..  is that the adjustment isn't happening fast enough..  actually it always describes a curve instead of a line.. i guess this is because worldScale is a percentage and therefore the larger the map the larger are the first steps and the smaller are the last steps compared to the first ones..    if i zoom in with 10% every step on a 10000px map the first step will be 1000px the second 900px. and so on..


it kinda works.. but there is still something completely wrong.. it must be so obvious but it feels like i'm blind for it..

Link to comment
Share on other sites

oh.. well..  wasted another 30 minutes and kinda figured it out now..  it works like google maps now:





give it a try..  place the box on an edge and try to zoom in exactly at the box.. it should work now without losing the box in the camera view and the cameramovement looks linear now :)



edit:  and i added "pinch to zoom" too...   this probably needs  a little bit of tuning (if you release the fingers before the targeted zoom factor is reached the camera stops adjusting and therefore focuses on a wrong point.. this is is because of the easing - should be an easy fix but enough for today - for now just set     var easing = 0;  and it works perfectly )

:ph34r:  :ph34r: 

Link to comment
Share on other sites

  • 1 year later...

Add this to your mousewheel zoom:

{  // wheelzoom
            zoompoint.x = game.input.mousePointer.worldX;
            zoompoint.y = game.input.mousePointer.worldY;
            snap = 40;
            zoompoint.x = zoompoint.x - (zoompoint.x % snap);
            zoompoint.y = zoompoint.y - (zoompoint.y % snap);

Adjust the snap depending on the worldsize. I haven't quite done that logic, but some mouses (laptops in my case) are super sensitive to slight movement of the mouse n scrolling via the touch leads to slight jitter. The snap takes into consideration slight mouse movement. You might make this a bit better by debugging the snap grid and taking into consideration world scale vs the camera bounds. But for my specific use case this did the trick for me.

Link to comment
Share on other sites

  • 5 months later...

  • Recently Browsing   0 members

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