Skip to content

Instantly share code, notes, and snippets.

@aolo2
Last active January 17, 2024 10:48
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aolo2/a373363419bd5a9283977ab9f8841f78 to your computer and use it in GitHub Desktop.
Save aolo2/a373363419bd5a9283977ab9f8841f78 to your computer and use it in GitHub Desktop.
zoom around the mouse
// What we want is the mouse position to stay the same relative to the zoomable object (it's a map in this example)
// To do that we solve the equation "oldMouseRelativePos = newMouseRelativePos" to find the value of newMapOffset.
// We know the values of oldZoom, newZoom, oldMapOffset and mousePos
//
// It is assumed that canvas->screen (something you would use in OpenGL, for example) transform is "(p - offset) / zoom",
// meaning screen->canvas (something you would use in Canvas2D) transform is "p / zoom - offset".
// mousePos is assumed to be in some kind of screen coordinates
// mapZoom is assumed to be zooming relative to the top left corner of the map
//
// "map relative mouse position" is:
// mousePos / zoom - offset
// The equation:
// mousePos / oldZoom - oldMapOffset = mousePos / newZoom - newMapOffset
//
// The solution:
// newMapOffset = oldMapOffset + mousePos / newZoom - mousePos / oldZoom
mapOffset.x += mousePos.x / mapZoom - mousePos.x / oldZoom;
mapOffset.y += mousePos.y / mapZoom - mousePos.y / oldZoom;
// Using the same logic, if we are doing scale and translate in reverse order, the formula becomes
mapOffset.x = mousePos.x - (mousePos.x - mapOffset.x) * mapZoom / oldZoom;
mapOffset.y = mousePos.y - (mousePos.y - mapOffset.y) * mapZoom / oldZoom;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment