Zoom the view while keeping focus on mouse or object position.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
GameMaker Example/Zoom with Target Focus.gmx
Graphics
README.md

README.md

Zooming-with-Target-Focus

This is an algorithm that maintains the proportions between a given object and the edges of the view while zooming.

Try out the algoritm here (mouse as the focal object and mouse scroll to zoom): http://pennpierson.com/gm_zoom/

Or download and play with the GameMaker source files.


Algorithm Steps:

  1. Find the proportional position of the object.
  2. Apply zoom to view.
  3. Set view x and y coordinates such that the proportional positioning is maintained for the object.

Example

Example

Both the X ande Y values are calculated the exact same way, so to save space and for clarity, only the X values are calculated/shown here.

  • XO ~~ View x origin
  • XV ~~ View width
  • X ~~ Focus object x coordinate
  • XA ~~ Distance between XO and X
  • XP ~~ Proportional distance between XO and X
  • Zoom ~~ Amount of zoom
  • Default_X ~~ Width of view when zoom is 1
X Origin View Width Object X Distance to origin Proportional distance to origin
Default Zoom XO XD X XA = X / XO XP = XA / XD
Applied Zoom XOzoom = X - XAzoom XV = XD * Zoom Constant XAzoom = XV * XP Constant

#GameMaker Studio Code

This is the code for the camera object. The target is set to obj_cursor (which copies the mouse position), but you can set the target to whatever you want, or you can swap out some of the code to have it directly follow the mouse.

Create Event

/// Initialize variables

zoom = 1; // Initial zoom level
default_width = 400; // Initial view width
default_height = 300; // Initial view width
zoom_increment = 0.1; // How much to zoom by
target = obj_cursor; // Target to keep focus on when zooming

Step Event

/// Get inputs

mouse_scroll_up = mouse_wheel_up();
mouse_scroll_down = mouse_wheel_down();
mouse_scrolling = false;
if mouse_scroll_up or mouse_scroll_down {
    mouse_scrolling = true;
    }
/// Zooming

// If scrolling, apply it to the zoom variable
zoom += (mouse_scroll_up - mouse_scroll_down) * zoom_increment;

// Make sure zoom doesn't reach or fall below 0
if zoom < zoom_increment {
    zoom = zoom_increment;
    }
else if zoom > 10 { // Make sure it doesn't get too large
    zoom = 10;
    }

// INFO
// view_xview[0] ~~ x origin of view
// view_yview[0] ~~ y origin of view
// view_wview[0] ~~ width of view
// view_hview[0] ~~ height of view

if mouse_scrolling { // If scrolling/zoooming
    // Get the distance from the target to the orgigin.
    target_x_abs = target.x - view_xview[0];
    target_y_abs = target.y - view_yview[0];
    // Find the proportional from the object to the origin.
    target_x_p = target_x_abs / view_wview[0];
    target_y_p = target_y_abs / view_hview[0];

    // Set zoom
    view_wview[0] = default_width * zoom;
    view_hview[0] = default_height * zoom;
    
    // Calculate what the new distance from the target to the origin should be.
    target_x_new_abs = view_wview[0] * target_x_p;
    target_y_new_abs = view_hview[0] * target_y_p;
    // Set the origin based on where the object should be.
    view_xview[0] = target.x - target_x_new_abs;
    view_yview[0] = target.y - target_y_new_abs;
    }