This code shows one method of zooming in on the mouse position in a 2D world, rather than the "camera center".
Uses minor functions from Matrix1 DLLs (i.e. "clamp").
Use the mousewheel in this demo to see what I mean:
sync on
sync rate 0
global camZoom#
camZoom# = 1
#constant CAM_MAX_ZOOM 4.0
#constant CAM_MIN_ZOOM 0.5
#constant LINESPACEWORLD 20
#constant WORLDSIZE 980
global camWorldX#
camWorldX# = 0
global camWorldY#
camWorldY# = 0
do
cls rgb(255, 255, 255)
//Zoom logic
mmz = mousemovez()
if (mmz)
oldZoom# = camZoom#
//Update the zoom level
camZoom# = clamp(camZoom# + mmz / 1000.0, CAM_MIN_ZOOM, CAM_MAX_ZOOM)
//Figure out how much to move the camera to compensate for zooming
relZoom# = camZoom# / oldZoom#
camMoveRatio# = 0
if (relZoom# < 1)
camMoveRatio# = -(1 / relZoom#)+1
else
camMoveRatio# = relZoom#-1
endif
//Base the compensation off of whichever zoom is bigger, the old or the new
//Those zeros represent wherever the camera "wants" to zoom from
//My camera is centered in the top left
distanceFromCenterX# = (mousex() - 0) / max(camZoom#, oldZoom#)
distanceFromCenterY# = (mousey() - 0) / max(camZoom#, oldZoom#)
//Finally, move the camera
inc camWorldX#, distanceFromCenterX# * camMoveRatio#
inc camWorldY#, distanceFromCenterY# * camMoveRatio#
endif
//Just draw some stuff so we can see what's going on
for x = 0 to WORLDSIZE / LINESPACEWORLD
for y = 0 to WORLDSIZE / LINESPACEWORLD
ink rgb((x mod 10)*25, (y mod 10)*25, (x*y mod 50)*5)
box WorldToScreenX(x*LINESPACEWORLD), WorldToScreenY(y*LINESPACEWORLD), WorldToScreenX((x+1)*LINESPACEWORLD), WorldToScreenY((y+1)*LINESPACEWORLD)
next y
next x
sync
loop
end
//Helpers to convert from screen coordinates to "world" coordinates
function WorldToScreenX(wpos as float)
spos = (wpos - camWorldX#) * camZoom#
endfunction spos
function WorldToScreenY(wpos as float)
spos = (wpos - camWorldY#) * camZoom#
endfunction spos
function ScreenToWorldX(spos as float)
wpos = spos / camZoom# + camWorldX#
endfunction wpos
function ScreenToWorldY(spos as float)
wpos = spos / camZoom# + camWorldY#
endfunction wpos
