Blog Archive

How to build a Pan & Zoom Plugin Using the Revealing Module Pattern

In one of our recent projects, we had to devise a solution for the virtual visitors of a large shopping mall, which has an overwhelming diversity of businesses, brands, activities and services. What we needed was a surface map that would interact with the user, so that they could search for points of interest, be taken there and shown key information on the fly. The source serving the map had to be dynamic and thus would be changed frequently and updated as a ‘dumb’ SVG file; the live map would have to adapt to the changes.

If you face a similar challenge, this article takes you through the steps of building a basic JavaScript plugin for interacting with an element which allows zooming and panning using your mouse. We will be using the Revealing Module design pattern (RMP) to write our plugin. (check this out if you want to read more on RMP).

Step 0 – Basic Prerequisites

Let’s call our plugin Moveit and get the HTML & CSS out of the way.

We need a fresh HTML document, in which to put 3 things: a button, a container that can be anything (in our case a <figure>) and a target that can also be anything (in our case an <img>):

Now the CSS, to style our box so that we can see our context better, and the button:

Step 1 – Initial Settings and Targets

We start our plugin by assigning a self-invoking function to an aptly named variable in which to hold all our logic, and expose only what we need. Let’s create a moveit.js file and start writing:

Now we want to build and hold our initial settings; we do this using an object literal. We will be using CSS3 transformations to manipulate our target, so we need to establish max and min values for the scale (zooming) and a step (how much we zoom at a time), to decide if transitions are allowed and choose the transition string. We then update moveit.js inside our function with:

We also need to hook our target and our button (which we will use to reset the target). Here I decided to go with HTML5 data-attributes for selectors, since I consider them easier to read in the code and less intrusive. Depending on your needs, you might want to go for classes or ids.
So we first update our HTML, adding the data-attributes. I went with “data-mi-target” for the target and “data-mi-reset” for the button:

We’re not interested in attribute values, we just want them present. Now let’s select them – update moveit.js, bellow the “settings” variable, like this:

So far, so good. Before we move on, though, let’s also include our new script in the HTML code, just before the tag:

Step 2 – Reference Points and Apply/Get Methods

We will be moving things around, so we need to get some reference points for positions and transformations. Add the following code to moveit.js:

Cool. Now let’s build methods that allow us to override default settings, see the settings object and apply transformations. In moveit.js we write:

Awesome! Now we need a method to call when we have some transform values and we want to apply them. We do that by going over the “transforms” object after updating it (we will write this later) and translating the objects pairs into CSS3 transforms. Add to moveit.js:

Step 3 – Zooming, Moving and Reset

It’s time for the good bits. First is zooming – we’ll build a function which will be called with a mouse scroll event, determine the scrolling direction using the events “deltaY” property and apply the transformation using our defined “settings.zoomStep” value. We also need to check min and max zoom values. Add to moveit.js:

Ok, let’s tackle moving next. We need multiple methods for this, so let’s start with a function which will take reference points at mouse click. Add to moveit.js:

Now we need to create the “move” function, which we attached to the “mousemove” event earlier. This function will track our mouse movement (while holding down the click) and translate it into transformations. Add to moveit.js:

Next, we need a function to restore reaction to our element and remove the listener which calls our “move” function. Add to moveit.js:

Voila! We have movement. Of course, nothing actually happens yet, because we’re not listening for events, so don’t panic. Next, we need a simple function that will reset our transforms. Add to moveit.js:

Goody! We’re almost done. All that’s left is listening for events and exposing a couple of our methods, so that we can call them from the outside when needed. First, we check if all the elements we need are present and if they are we add in their listeners. Add to moveit.js:

Awesome! Now, if everything was done right, we can move and interact with our element. Lastly, we expose a couple of methods, specifically applySettings snd getSettings, so we can override and check default settings if we need to. Add to moveit.js:

That’s all. Congrats’! You just wrote a plugin to pan and zoom stuff, using the Revealing Module Pattern. If you wish, you can download the whole source here.

This is a very basic starting point and from here on, there’s endless room to expand. If you like, you can check out our GitHub where we’re playing around with it; we added some stuff, and are experimenting with ways to accommodate touchscreens.
I hope this was helpful and/or fun for you.

Thanks for reading, see you next time!

Blog Archive