Haciendo zoom con html5

Rutas
Solucionex
15
Nov 24

Una de las muchas cosas que nos trajo html5 es el elemento canvas para dibujar gráficos mediante javascript, vamos a ver un pequeño ejemplo de como usarlo para hacer zoom en una imagen.

Lo primero el elemento canvas en nuestra página.

<canvas id="zoom" width="1200" height="400" data-x="0" data-y="0" data-zoom="50" data-img="https://cdn2.picryl.com/photo/2013/12/03/8-of-old-spain-and-new-spain-11195626095-3f7039-1024.jpg"></canvas>

En este elemento hemos configurado varios parámetros: data-x y data-y son las coordenadas del punto superior izquierdo desde el que vamos a hacer zoom en la imagen original, data-zoom es el procentaje de zoom que vamos a hacer en la imagen y data-img es la ruta de la imagen que vamos a usar.

Con esta informacion ya podemos crear la función javascript que va a dibujar la imagen con el zoom correspondiente en el canvas

const img = new Image();
let canvas;

function draw() {
 const ctx    = canvas.getContext("2d");
 const zoom   = canvas.dataset.zoom;
 const width  = canvas.width  * (zoom / 100);
 const height = canvas.height * (zoom / 100);
 const x      = Math.min(canvas.dataset.x, img.width  - width );
 const y      = Math.min(canvas.dataset.y, img.height - height);
 // Background
 ctx.fillStyle = "white";
 ctx.fillRect(0, 0, canvas.width, canvas.height);
 // Draw the image with the corresponding zoom and position
 ctx.drawImage(img, x, y, width, height, 0, 0, canvas.width, canvas.height);
}


Tenemos dos variables globales img que es donde hemos cargado la imagen original y canvas que es donde tenemos la referencia a nuestro elemento canvas en la página, dentro de la función draw obtenemos el canvas y el contexto del canvas que vamos a usar para dibujar. Zoom es el porcentaje de zoom que vamos a aplicar, width y height son el ancho y el alto en pixeles de la imagen original que queremos mostrar correspondiente al zoom que tenemos establecido y x e y son las coordenadas superior izquierda desde donde vamos a mostrar ese zoom sin salirnos por la derecha ni por abajo. Después de calcular los parámetros necesarios borramos todo lo que había en el canvas pintándolo entero de blanco y después utilizamos la función drawImage para dibujar la parte deseada de la imagen con su zoom correspondiente.

Con esto podemos añadir un par de métodos mas que nos van a dar cierta interactividad con el zoom

function move(x, y) {
 canvas.dataset.x = Math.min(Math.max(1 * canvas.dataset.x + x, 0), canvas.width);
 canvas.dataset.y = Math.min(Math.max(1 * canvas.dataset.y + y, 0), canvas.height);
 draw();
}
function zoom(change) {
 canvas.dataset.zoom = Math.min(Math.max(1 * canvas.dataset.zoom + change, 10), 200);   
 draw();
}

La función move se encarga de desplazar el punto superior izquierdo a partir del cual vamos a mostrar la imagen, sin permitir que estos se salgan del tamaño de la imagen y despues de eso dibuja la imagen.
La función zoom se encarga de modificar el zoom de la imagen manteniendolo entre el 10 y el 200% y despues de eso vuelve a dibujar la imagen.

Con todo esto ya solo nos que da añadir la función para cargar la imagen y conectar las funciones move y zoom a eventos de teclado para darle interactividad al zoom.

window.onload = function(e) {
 canvas = document.getElementById('zoom');
 if (canvas) {
   img.addEventListener("load", () => {
     draw();
     canvas.addEventListener("wheel", e => {
       e.preventDefault();
       zoom(e.deltaY > 0 ? 25 : -25);
     });
     document.addEventListener("keydown", e => {
       e.preventDefault();
       switch (e.keyCode) {
         case 37: move(-50, 0); break;
         case 38: move(0, -50); break;
         case 39: move(50, 0);  break;
         case 40: move(0, 50);  break;
       }
     });
   });
   img.src = canvas.dataset.img;
 }
}

Cargamos la imagen con la línea img.src = canvas.dataset.img. Una vez cargada se va a ejecutar el evento load de la imagen que es donde dibujamos la imagen por primera vez y le añadimos los eventos que nos permiten controlar el zoom de la imagen con la rueda del ratón y la posición de la imagen con las flechas del teclado.

Con esto tenemos una forma rudimentaria de hacer zoom sobre una imagen que no solo no necesita de librerías externas o aplicaciones como flash, sino que además es compatible con todos los navegadores actuales de forma nativa.

A partir de aquí lo que faltaría sería añadir estilos, la posibilidad de desplazarse por la imagen mediante arastrando con el ratón, suavizar la forma en que se hace zoom o se desplaza por la imagen, botones HTML que permitan interactuar con el zoom sobre la imagen, lo bueno es que con los métodos move y zoom añadir estas funcionalidades no debería ser muy complicado.