mercoledì 4 aprile 2012

Zoom Rotate Image via javascript per Explorer Chrome e Firefox


Quando si ha necessità di visualizzare un file pdf all'interno di un browser, di solito si utilizza un plugin come l'Adobe Reader, mentre quando occorre visualizzare una tiff si ricorre normalmente ad un plugin di tipo Applet o ActiveX. In tutti i casi per effettuare zoom e/o il rotate del file ci si affida al plugin utilizzato per visualizzarlo.
Alcuni file come gif, jpg o png non necessitano di plugin perchè sono visualizzabili nativamente da un browser, ma per essi non è possibile effettuare zoom e/o il rotate direttamente dal browser.


In questo post viene proposta una soluzione che utilizza un javascript che ho chiamato imageZoomRotate.js . Questo script consente di effettuare lo zoom e/o il rotate di un img ovvero di una gif, jpg o png visualizzabile direttamente da browser mediante:



Lo script utilizza le librerie DXImageTransform per Internet Explorer
http://msdn.microsoft.com/en-us/library/ms532847(v=vs.85).aspx

Mentre per Firefox e Chrome impiega una tecnica basata sui Canvas
https://developer.mozilla.org/en/Canvas_tutorial


Sotto riporto il codice dello script.
I punti chiave del funzionamento dello script sono stati illustrati direttamente sul codice sotto forma di commento.


imageZoomRotate.js
function $(d) {
 return document.getElementById(d);
}

var zoomfactor = 0.20; // fattore di zoom 20%

function draw(imgId, rot, zoom) {

 // Recupero l'immagine o il vecchio canvas
 var obj = $(imgId);
  
 if (document.all && !window.opera) {  
  // INTERNET EXPLORER
  
  //si impedisce all'immagine di essere ridotta al di sotto di una 10x10 ponendo zoom=1.
  if(zoom < 1 && parseInt(obj.width) < 10 && parseInt(obj.height) < 10)
   zoom = 1;
   
  //si determinano height e width e angolo di rotazione
  var w = parseInt(obj.width) * zoom;
  var h = parseInt(obj.height) * zoom;
  obj.width  = w;
  obj.height = h;

  //si crea un canvas per un img assegnandogli i valori height e width e obj.src
  var angolo=((obj.angle==undefined?0:obj.angle) + rot) % 360;
  obj.angle = angolo;
  var canvas = document.createElement('img');
  canvas.src = obj.src;
  canvas.height = obj.height;
  canvas.width = obj.width;
  
  //si applica la rotazione mediante DXImageTransform
  var rotationStep = ((angolo+360)/90)%4
  canvas.style.filter ="progid:DXImageTransform.Microsoft.BasicImage(rotation=" + rotationStep + ");"
  canvas.angle = obj.angle;
 } 
 else {
  // MOZILLA FIREFOX
  
  // Creo il canvas con un oggeto Image all'interno
  var canvas = document.createElement('canvas');
  canvas.oImage = new Image();
  

  if(obj.oImage == null) {
   // Si tratta dell'oggetto Image, estraggo il src e lo associo all'immagine nel canvas
   canvas.oImage.src = obj.src;
   if(rot < 0)
    rot = 360 - Math.abs(rot);
   canvas.oImage.angle = rot;
   canvas.oImage.zf = zoom;
  }
  else {
   // Si tratta del vecchio canvas, estraggo il src dell'immagine associata
   // e lo associo all'immagine associata al nuovo canvas
   canvas.oImage.src = obj.oImage.src;
   canvas.oImage.angle = obj.oImage.angle + rot;
   if(canvas.oImage.angle >= 360)
    canvas.oImage.angle = canvas.oImage.angle - 360;
   if(canvas.oImage.angle < 0)
    canvas.oImage.angle = 360 - Math.abs(canvas.oImage.angle);
    
   canvas.oImage.zf = obj.oImage.zf * zoom;
  }
  
  var zf = canvas.oImage.zf;
  
  var w = canvas.oImage.width;
  var h = canvas.oImage.height;
  var costheta = Math.cos(Math.PI * canvas.oImage.angle / 180);
  var sintheta = Math.sin(Math.PI * canvas.oImage.angle / 180);
  
   
  // Assegno all'immagine contenuta nel canvas l'occupazione (w,h) durante la rotazione 
  canvas.oImage.width = Math.abs(costheta * w) + Math.abs(sintheta * h);
  canvas.oImage.height = Math.abs(costheta * h) + Math.abs(sintheta * w);
  
  // Assegno al canvas l'occupazione (w,h) durante la rotazione moltiplicata per il fattore di scala
  canvas.style.width = canvas.width = Math.abs(costheta * zf * w) + Math.abs(sintheta * zf * h);
  canvas.style.height = canvas.height = Math.abs(costheta * zf * h) + Math.abs(sintheta * zf * w);
   
  // Recupero il context dal canvas
  var context = canvas.getContext('2d');  
  context.scale(zf, zf);
   
  // Effettuo la traslazione Tx e Ty del contesto in uno 
  // dei 4 quadranti a seconda della rotazione richiesta
  if (canvas.oImage.angle <= 90) {
    context.translate(h*sintheta, 0);
  } 
  else if (canvas.oImage.angle <= 180) {
     var alpha = Math.PI * (canvas.oImage.angle-90) / 180;
    context.translate(w*Math.sin(alpha)+h*Math.cos(alpha),h*Math.sin(alpha));
  } 
  else if (canvas.oImage.angle <= 270) {
    var alpha = Math.PI * (canvas.oImage.angle-180) / 180;
    context.translate(w*Math.cos(alpha),h*Math.cos(alpha)+w*Math.sin(alpha));
  } 
  else {   
    context.translate(0,-w*sintheta);
  }
  
  // Ruoto il contesto della quantità richiesta e disegno l'immagine
  context.rotate(Math.PI * canvas.oImage.angle / 180);
  context.drawImage(canvas.oImage, 0, 0);

 }
  
 // Assegno al canvas l'id dell'obj e rimpiazzo il nuovo canvas al posto del vecchio
 // - al primo step esso è rappresentato dall'Image
 // - agli step successivi esso è rappresentato dal canvas creato allo step precedente
 canvas.id = obj.id;
 obj.parentNode.replaceChild(canvas, obj);
}

function rotateLeft() {
 draw('immagine', -90, 1);
}
 
function rotateRight() {
 draw('immagine', 90, 1);
}
 
function zoomIn() {
 var zoom = 1 + zoomfactor;
 draw('immagine', 0, zoom);
}
 
function zoomOut() {
 var zoom = 1 - zoomfactor;
 draw('immagine', 0, zoom);
}

function adjust() {
 imgId = 'immagine';
 var ws = document.body.clientWidth;
 var imgObj = document.getElementById(imgId);
 var wi;
 if (document.all && !window.opera) {  
  // INTERNET EXPLORER}
  if(imgObj.angle==undefined || imgObj.angle==0 || imgObj.angle==180)
   wi = imgObj.width;
  else
   wi = imgObj.height;
 }
 else {
  // MOZILLA FIREFOX
  wi = imgObj.clientWidth; 
 } 
 var zoom = ws/wi;
 draw(imgId, 0, zoom);
}


Per prima cosa occore impostare il fattore di zoom zoomfactor che viene utilizzato ogni volta che si preme ZoomIn o ZoomOut, in questo caso è 0.20 ovvero il 20%.
Le funzioni principali sono le seguenti:

rotateLeft() Effettua la rotazione antioraria di 90° dell'immagine
rotateRight() Effettua la rotazione oraria di 90° dell'immagine
zoomIn() Ingrandisce l'immagine di una quantità percentuale pari a zoomfactor
zoomOut() Riduce l'immagine di una quantità percentuale pari a zoomfactor
adjust() Adatta l'immagine alla larghezza della finestra del browser


Sotto è riportato un esempio di pagina html che permette di utilizzare lo script ed effettuare zoom e rotate sull'immagine mucca.jpg file: ZoomRotate.html

 

Ruota in senso antiorario Ruota in senso orario Riduci Ingrandisci Adatta documento allo schermo


Premendo il tasto di rotazione oraria legato alla rotateRight() si ottiene:


Effettuando nuovamente la rotateRight()
Seguita da una adjust() di ottiene:


Nessun commento:

Posta un commento