How to Add a Widget that we can Zoom In and Out on a Web Page When We Spin the Mouse Wheel Like on Google Maps with JavaScript?

Sometimes, we want to create a widget on a web page where we can zoom in and out on something as we can do on Google Maps with JavaScript.

In this article, we’ll look at how to create a widget that we can zoom in and out with the mouse wheel as we can do on Google Maps with JavaScript.

Draw the Image We can Zoom In and Out on the Canvas with JavaScript

We can draw the image we want to be able to zoom in and out on the canvas with JavaScript.

Then we can listen to the wheel event and transform the canvas image when we move the mouse wheel to let us zoom the image in and out.

For instance, we can write the following HTML:

<canvas id="canvas" width="600" height="200"></canvas>

Then we can write the following JavaScript code to draw the image on the canvas and zoom the image in and out as we move the mouse wheel:

const zoomIntensity = 0.2;

const canvas = document.getElementById("canvas");
let context = canvas.getContext("2d");
const width = 600;
const height = 200;

let scale = 1;
let originx = 0;
let originy = 0;
let visibleWidth = width;
let visibleHeight = height;

const draw = () => {
  context.fillStyle = "white";
  context.fillRect(originx, originy, width / scale, height / scale);
  context.fillStyle = "black";
  context.fillRect(50, 50, 100, 100);
  window.requestAnimationFrame(draw);
}
draw();

canvas.onwheel = (event) => {
  event.preventDefault();
  const mousex = event.clientX - canvas.offsetLeft;
  const mousey = event.clientY - canvas.offsetTop;
  const wheel = event.deltaY < 0 ? 1 : -1;
  const zoom = Math.exp(wheel * zoomIntensity);
  context.translate(originx, originy);
  originx -= mousex / (scale * zoom) - mousex / scale;
  originy -= mousey / (scale * zoom) - mousey / scale;
  context.scale(zoom, zoom);
  context.translate(-originx, -originy);
  scale *= zoom;
  visibleWidth = width / scale;
  visibleHeight = height / scale;
}

We have the draw function that clears the screen to white with the first and 2nd lines.

Then we call fillStyle and fillRect to draw a black square.

And then we call window.requestAnimationFrame to redraw the canvas.

Once we defined the draw function, we call it to start the initial draw.

Next, we set the canvas.onwheel property to a function that zoom the image in and out when we move the mouse wheel.

In the function, we first call event.preventDefault() to stop the default behavior when the mouse wheel moves.

Then we get the mouse offset with:

const mousex = event.clientX - canvas.offsetLeft;
const mousey = event.clientY - canvas.offsetTop;

Next, we write the following to normalize mouse movement to avoid unusual jumps:

const wheel = event.deltaY < 0 ? 1 : -1;

Then we get the zoom factor with:

const zoom = Math.exp(wheel * zoomIntensity);

And then we translate the visible origin so that it’s at the context’s origin with:

context.translate(originx, originy);

Then we compute the new origin after the zoom is done with:

originx -= mousex/(scale*zoom) - mousex/scale;
originy -= mousey/(scale*zoom) - mousey/scale;

Next, we call context.scale(zoom, zoom) to scale the image around the origin.

And then we translate the image to offset the visible origin so that it’s at the proper position after zoom:

context.translate(-originx, -originy);

And finally, we update the dimensions after zoom with:

scale *= zoom;
visibleWidth = width / scale;
visibleHeight = height / scale;

Now when we move the mouse wheel, the black square should zoom in and out.

Conclusion

We can add a widget with an image that we can zoom in and out by drawing an image on the canvas and translating and scaling the image when we move the mouse wheel.