Panel de zoom de imágenes en ActionScript 3
Este ejemplo es 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.
- 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“.
- 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.
- 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:
- 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.
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;
}[/as]
En función de estos valores moveremos la imagen grande bajo la máscara.
[as]function mueveVisorZona():void
{
mapaBig.x = mascara.x - distX;
mapaBig.y = mascara.y - distY;
}[/as]
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.
[as]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.zona.x=visor.mapaSmall.x+visor.mapaSmall.width-visor.zona.width;
}
if (visor.zona.y
visor.zona.y=visor.mapaSmall.y+visor.mapaSmall.height-visor.zona.height;
}
//mapaBig
if (mapaBig.x>0) {
mapaBig.x=0;
} else if (mapaBig.x
mapaBig.y=0;
} else if (mapaBig.y
Compártelo:
Visto 26.544 veces
Bastante bueno Zguillez. Sólo que el link de archivo.fla está roto.
@Rafeo: FIXED!
Ammm… No le arreglaste el drag.
@Bleend: errr si claro el drag errr *zguillez trata de buscar una excusa coherente…
Eso lo iba a postear cuando tuviese también arreglados un par de detalles más, como lo de la vuelta al panel con el mouse apretado y tal..
PD: tambien le quiero meter un controlador de zoom con un slide 😉
podrias poner este codigo…para flash8
gracias
pedro
pdt.(o un archivo flash)para la version8
@Pedro: Este ejemplo lo escribà en Actionscript 3, para abrirlo en Flash 8 tendrÃa que traducirlo todo a Actionscript 2… Te recomiendo actualizarte a Flash CS3, podrás trabajar en AS2 y AS3
Aquà tengo un ejemplo empezado en AS2, pero que le faltan algunos detalles
http://www.cristalab.com/zguillez/flash/as2/lupa/
Excelente! Solo una pregunta: ¿Porque el ejemplo no funciona si abres el swf generado a aprtir del fla usando el swf player? necesita estar en un servidor o dentro de flash (ctrl+f12) forzosamente para funcionar?
Yo lo queria correr desde un cd..
@Lince: DeberÃa funcionarte perfectamente. Asegúrate de que lo estas abriendo con el flash player 9.
Si, ese era el problema…Lo estaba abriendo con el reproductor 8…Duuuh :P!
Excelente trabajo nuevamente!
Cuando terminas el ejemplo en AS2, pues estoy interezado en adaptarlo a mi sitio web que está todo hecho en Flash 8 y por ahora no puedo actualizarlo a CS3. En realida es urgente! Gracias.
Guillermo, te pido si tubieras la amabilidad de orientarme con como convertir tu codigo AS3 a AS2, o almenos la parte que bloquea clip en la zona para que no se salga, muchas gracias
Tenes como hacer exactamiente lo mismo ejemplo adaptado para lo flex 3?.
Seria muy bueno y me ayudaria demasiado.
Muchas Gracias
Silva Developer
silva.developer@gmail.com
[…] ejemplo es, igual que hice en el post anterior, un ejemplo que he adaptado a Flex desde un ejemplo que hice hace tiempo para Flash. Se trata de un panel donde se ve un zoom de una parte de una […]
@Silva: Aqui tienes ese ejemplo adaptado a Flex:
http://www.codigoactionscript.org/panel-de-zoom-de-imagenes-en-flex/
😉
Hola, excelente trabajo con el panel es justo el codigo que estaba buscando!! Solo una petición, en un post comentas que trabajabas en un controlador de zoom con un slide para añadirlo al panel, lo añadiste?
Gracias!!
Hola!
Me agrada bastante esta solución hecha con AS3, pero no puedo descargar el archivo fla el link esta roto, ¿me puedes decir como lo puedo obtener por que me urge un poco para un proyecto escolar?
Hola Luis,
En el link inferior encontrarás el mismo tutorial con el archivo .fla en correctas condiciones!
http://www.cristalab.com/tips/panel-de-zoom-de-imagenes-en-actionscript-3-c46306l/
Saludos
Por favor el mismo archivo en AS2, es que se dejo en su momento parece que lo han borrado. Te juro que lo necesito como agua de mayo,estoy haciendo un mapa que se abre pinchado en cada provincia, pero se ven muy pequeños los nombres y habia pensado en hacer una ventana como lo que esta en este tutorial, pero todo el archivo que tengo esta en AS2, y por culpa de mi ignorancia no tengo ni idea de como hacer varios botones en AS3, por favor lo necesito os juro que estoy desesperado, cualquier ayuda es bienvenida.
Muchas gracias
Al final no he tenido mas remedio que aventurarme en el mundo del AS3, que por cierto poco tiene que ver con el AS2, o al menos he tenido que empezar por lo que creo que trae mas diferencias “los botones”. He conseguido hacer un par de botones que funcionen pero sigo con bastantes problemas,pero bueno poco a poco.
Lo que te queria preguntar es porque si cojo este archivo que en la linea de tiempo principal no da ningun problema, porque al meterlo en un MC al pinchar se desplaza el visor, por lo demás va perfecto.
Si me puedes ayudar te lo agradeceria.
Saludos a todos
Pues nada yo os sigo contando mi aventura:
Ya he conseguido que funcione, haciendo una llamada al swf desde la otra escena y asi no da problemas,pero queria hacerte otra pregunta aunque doy por hecho que no va a tener respuesta como las anteriores, pero por probar suerte:
¿ hay alguna manera de hacer que el visor empiece en el punto en el que yo quiera y no el la esquina superior izq ? es que yo al hacerlo he puesto un mapa real y justo en esta zona no hay nada.
Muchas gracias y a ver si hay suerte con la respuesta.
Un saludo
Hola Anibal.
Perdona que no te haya respondido antes, pero ando muy liado estos días y no he ido revisando los comentarios en el blog.
EL archivo .FLA en AS2 he de tenerlo por algún lado volveré a colgarlo y corregir el link en cuanto pueda.
Aunque ya veo que te aventuraste con la versión en AS3, bien hecho.
En cuanto a tu última pregunta, si que se puede hacer.
El visor es un MovieClip, con lo que puedes acceder a sus propiedades X y Y en cualquier momento y darles valor (por ejemplo al iniciar la aplicación). No te debería dar ningún tipo de problema.
Antes de nada muchas gracias por tu respuesta,al final lo tengo hecho casi todo lo que queria ya que necesitaba hacer un par de cambios para adaptarlo a lo que me pedian.
Respecto a la pregunta, para posicionar el visor en un punto es fácil, jajajaja si supieras lo que me ha costado, pero lo que no consigo es que el mapa(grande) empiece en el mismo punto en el que yo pongo el visor, el mapa empieza en la esquina superior izq como siempre y hasta que no empiezo a arrastar el visor no detecta donde esta; por lo que supongo que lo que hace que detecte es la funcion OnStartDrag, asi que habia pensado en hacer una funcion para que nada mas empezar ya detecte donde esta el visor, pero es ahi donde me he quedado (no soy capaz).He intentado llamar a las funciones desde el principio pero nada.
Me esta costando la vida pero si es verdad que estoy aprendiendo a golpes,pero una ayudita siempre es bien recibida jeje
Muchas gracias otra vez y perdona la parrafada.
@Anibal
Lo que propones de la función que al ejecutar posicione el mapa en la posición correcta es justamente lo que tienes que hacer 😉
No te debe de funcionar por que la ejecutas al iniciar la aplicación con lo que el mapa aun no está accesible. La tendrías que ejecutar en el Complete del Loader que estés utilizando.
Suerte 😉
necesito ayuda urgente… estoy desarrollando un header en flash y tengo este codigo pero me salen unos horrores ayuda por favor urgente
on (release)
{
function ()
{
\x03 = 2176 % 511 * true;
return (eval(“\x03”));
} // End of the function
var \x01 = -86 + \x04\x05();
while (\x01 = eval(“\x01”) – 14, eval(“\x01”) == 99)
{
\x01 = eval(“\x01”) + 127;
break;
} // end while
if (eval(“\x01”) == 32)
{
\x01 = eval(“\x01”) + 67;
if (false)
{
}
else
{
\x01 = eval(“\x01”) + 127;
} // end else if
} // end if
\x01 = eval(“\x01”) + 187;
if (eval(“\x01”) == 666)
{
\x01 = eval(“\x01”) – 338;
} // end if
if (eval(“\x01”) == 234)
{
\x01 = eval(“\x01”) + 344;
} // end if
if (eval(“\x01”) == 226)
{
\x01 = eval(“\x01”) + 102;
} // end if
\x01 = eval(“\x01”) + 53;
\x01 = eval(“\x01”) + 359;
var \x0f = 1;
\x01 = eval(“\x01”) – 506;
if (eval(“\x01”) == 762)
{
\x01 = eval(“\x01”) + 208;
} // end if
if (eval(“\x01”) == 765)
{
\x01 = eval(“\x01″) – 3;
if (!”\x0f”)
{
}
else
{
\x01 = eval(“\x01”) + 208;
} // end else if
} // end if
if (eval(“\x01”) == 970)
{
\x01 = eval(“\x01”) – 967;
}
else
{
if (eval(“\x01”) == 3)
{
\x01 = eval(“\x01”) – 3;
} // end if
} // end else if
}
on (rollOver)
{
if (_root.link != 1)
{
main_menu.item1.gotoAndPlay(“s1”);
} // end if
}
on (releaseOutside, rollOut)
{
if (_root.link != 1)
{
main_menu.item1.gotoAndPlay(“s2”);
} // end if
}