Recently, I was tinkering on a side-project where I wanted to build a sort of canvas of very large dimensions that I could zoom in on and pan around, similar to zooming and panning around in a map application.
In this post, I'm going to detail how I built this in React and what challenges I had to overcome in doing so. The components I was building were only intended to be used in a desktop browser, so on touch-enabled devices, the examples have been replaced with illustrative video clips.
In my first attempts at building this pannable and zoomable canvas, I bound the canvas's pan and zoom state directly to the canvas's DOM element itself. Ultimately, this caused a lot problems, because there were certain elements visually laid out on the canvas that I either did not want to scale, or did not want to pan (such as some user interface elements on the canvas).
Ultimately, I decided to try an approach that decoupled the desired pan and zoom state entirely from the canvas component itself. Instead of binding the pan and zoom state to the canvas, I wanted to create a React context that reported the user's desired pan and zoom state, but didn't actually manipulate the DOM in any way.