Comunidad de diseño web y desarrollo en internet

Panel de zoom de imágenes en ActionScript 3

Este tip es un ejemplo del estilo de "Zoom con lupa", aunque en esta ocasión es un zoom sobre una imagen con un panel de visualización al estilo de Photoshop.

El ejemplo es el siguiente:


Arrastra la zona roja del panel para desplazar la imagen


Para realizar este ejemplo necesitaremos la imagen a dos tamaños, una grande que colocaremos dentro de una máscara, y otra pequeña que colocaremos dentro de un MovieClip que utilizaremos como visor.



La imagen grande la colocaremos dentro de un clip al que llamaremos "mapaBig", y su mascara será otro clip al que llamaremos "mascara".

En cuanto al clip de visor lo llamaremos "visor" y la imagen pequeña "mapaSmall". Este clip contendrá tambien un botón que situaremos en la parte superior del panel que nos servirá para agarrar y mover el panel, este botón se llamará "botDrag". Tambien tendremos otro movieclip llamado "zona" formado por un rectángulo de color rojo y un botón invisible con el nombre "botZona".

Unas vez con la estructura de clips montada iremos a por el código. Todo este irá en el primer fotograma.

Empezaremos creandonos unas funciones para realizar el arrastre de la zona de zoom. Haremos que estas funciones nos sirvan tanto para el drag de la zona como para el drag del panel.

Código :

var visor_fx:Boolean = false;
//-----------------------------------------------
visor.botDrag.addEventListener(MouseEvent.MOUSE_DOWN, onStartDrag);
visor.botDrag.addEventListener(MouseEvent.MOUSE_UP, onStopDrag);
visor.botDrag.addEventListener(MouseEvent.MOUSE_OUT, onStopDrag);
visor.zona.botZona.addEventListener(MouseEvent.MOUSE_DOWN, onStartDrag);
visor.zona.botZona.addEventListener(MouseEvent.MOUSE_UP, onStopDrag);
visor.zona.botZona.addEventListener(MouseEvent.MOUSE_OUT, onStopDrag);
//-----------------------------------------------
function onStartDrag(e:Event):void
{
   var clip:MovieClip = e.target.parent;
   clip.startDrag();
   visor_fx = true;
}
function onStopDrag(e:Event):void
{
   e.target.parent.stopDrag();
   visor_fx = false;
}

Las funciones recuperan como parametro (target.parent) el clip que han de arrastrar dependiendo del clip que lanzó el evento.

También creamos una variable "visor_fx" que nos indica si estamos arrastrando algo en ese momento. Esto lo hacemos para posteriormente crear una función que se ejecute cada vez que movamos el mouse pero que solo ejecute las funciones internas en el caso de estar arrastrando el clip de "zona".

Código :

this.addEventListener(MouseEvent.MOUSE_MOVE, MouseMove);
//-----------------------------------------------
function MouseMove(e:Event):void
{
   if (visor_fx == true) {
      calculaDist();
      mueveVisorZona();
      controlaPosiciones();
   }
}


Aparte del arrastre haremos que al clicar sobre la imagen pequeña la zona se sitúe directamente en esa posición.

Código :

visor.mapaSmall.addEventListener(MouseEvent.MOUSE_DOWN, onPosicionaZona);
//-----------------------------------------------
function onPosicionaZona(e:Event):void
{
   var clip:MovieClip = e.target.parent;
   clip.zona.x = mouseX-clip.x- clip.zona.width/2
   clip.zona.y = mouseY-clip.y- clip.zona.height/2
   calculaDist();
   mueveVisorZona();
   controlaPosiciones();
}


Ahora vamos con las funciones que realizaran el desplazamiento de la imagen grande en función de la posición del clip "zona" sobre la imagen pequeña. Empezaremos creando unas variables:

Código :

var porcentajeX:Number = 100 / (mapaBig.width / visor.mapaSmall.width);
var porcentajeY:Number = 100 / (mapaBig.height / visor.mapaSmall.height);
visor.zona.width = mascara.width * porcentajeX / 100;
visor.zona.height = mascara.height * porcentajeY / 100;
var distX:Number = 0;
var distY:Number = 0;


La variable porcentajeX/Y calcula el porcentaje de escalado entre las dos imágenes. Una vez sabemos este porcentaje escalamos el clip "zona" a la misma escala en relación a la imagen pequeña.

También creamos dos variables distX/Y que contendrán la distancia de corrección de la imagen grande en relación al visor, las dejaremos a 0 ya que haremos una función para calcular esa distancia.

Código :

function calculaDist():void
{
   distX = (visor.zona.x - visor.mapaSmall.x) / porcentajeX * 100;
   distY = (visor.zona.y - visor.mapaSmall.y) / porcentajeY * 100;

   distX = (distX<0)?0:distX;
   distY = (distY<0)?0:distY;
}


En función de estos valores moveremos la imagen grande bajo la máscara.

Código :

function mueveVisorZona():void
{
   mapaBig.x = mascara.x - distX;
   mapaBig.y = mascara.y - distY;
}


Solo queda crear una función que controle que al arrastrar no desplacemos el clip de zona fuera del visor, o el visor fuera de la película.

Código :

function controlaPosiciones():void
{
   //visor
   if (visor.x<0) {
      visor.x=0;
   } else if (visor.x>stage.stageWidth-visor.width) {
      visor.x=stage.stageWidth-visor.width;
   }
   if (visor.y<0) {
      visor.y=0;
   } else if (visor.y>stage.stageHeight-visor.height) {
      visor.y=stage.stageHeight-visor.height;
   }
   //zona
   if (visor.zona.x<visor.mapaSmall.x) {
      visor.zona.x=visor.mapaSmall.x;
   } else if (visor.zona.x>visor.mapaSmall.x+visor.mapaSmall.width-visor.zona.width) {
      visor.zona.x=visor.mapaSmall.x+visor.mapaSmall.width-visor.zona.width;
   }
   if (visor.zona.y<visor.mapaSmall.y) {
      visor.zona.y=visor.mapaSmall.y;
   } else if (visor.zona.y>visor.mapaSmall.y+visor.mapaSmall.height-visor.zona.height) {
      visor.zona.y=visor.mapaSmall.y+visor.mapaSmall.height-visor.zona.height;
   }
   //mapaBig
   if (mapaBig.x>0) {
      mapaBig.x=0;
   } else if (mapaBig.x<mascara.width-mapaBig.width) {
      mapaBig.x=mascara.width-mapaBig.width;
   }
   if (mapaBig.y>0) {
      mapaBig.y=0;
   } else if (mapaBig.y<mascara.height-mapaBig.height) {
      mapaBig.y=mascara.height-mapaBig.height;
   }
}


Y listo, ejemplo acabado ^^

Aqui el archivo .fla

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate