Zoom en tu propio lienzo de contenido

Algunas pinturas requieren que mires más de cerca para ver todos los detalles. Ahora, en lugar de una pintura, imagine un lienzo en blanco que se puede rellenar con imágenes y texto y descripciones dinámicas.

Encontramos a este increíble autor gracias a FlashGameLicense.com, el lugar para comprar y vender juegos Flash..

Nota: Este tutorial no tiene nada que ver con el elemento lienzo HTML5!


La demostración es una aplicación de visor que carga sus datos desde XML. El contenido se coloca en el "lienzo" y el usuario puede hacer zoom en el lienzo o hacer clic en cualquiera de las imágenes para centrarlo en la pantalla. Las configuraciones como el tamaño de página, el color / textura de fondo y otras configuraciones se cargan dinámicamente. Como bonificación el usuario puede crear múltiples páginas..

En este tutorial veremos los conceptos básicos de crear una aplicación como esta. Es recomendable mantener el código fuente a tu lado mientras lees el tutorial porque no se explican todas las partes. El código fuente está disponible para su uso con FlashDevelop o con Flash CS3 Professional y superior.


Nota: Abrir la aplicación localmente

Tenga en cuenta que antes de intentar abrir la aplicación desde su disco duro, deberá agregarla a la lista de "ubicaciones de confianza" especificada en el panel de Configuración de seguridad global que se muestra a continuación. De lo contrario, no se otorga acceso para capturar las imágenes de su disco duro. Esto no es necesario cuando se carga en un sitio web siempre que las imágenes se encuentren en el mismo servidor web.


Paso 1: Configuración del archivo XML

En caso de que no esté familiarizado con XML, consulte el AS3 101: XML de Dru Kepple. A continuación se muestran los datos XML correspondientes a una página con una imagen y un campo de texto. Los ajustes especificados aquí se aplican a todas las páginas. Como puede ver, crear varias páginas y agregarles contenido es fácil. A las imágenes puede agregar un título y una descripción que se ven cuando se pasa el mouse sobre el mouse. Se puede agregar texto de varias líneas y se puede personalizar el tamaño y el estilo. Cada campo de texto usa una fuente personalizada que se encuentra en el archivo .fla.

    0x000000 … / Images / 580 380 2000 1300 0xEEDEC0 0xC1C59C 10 10     Hola y bienvenidos a la demostración de la aplicación de lienzo. Utilizado como tema aquí son mis vacaciones a Copenhague. anno 2010. Siéntase libre de leer los textos y olfatear la cultura.  23 470 50   Iglesia y lago El bello entorno en Kastelskirken. Church_And_Lake.jpg 1 750 500   

Paso 2: La clase de documentos y lienzos

Utilice el siguiente código para configurar nuestra aplicación. FlashDevelop lo genera casi por completo utilizando la plantilla "Proyecto AS3". Principal es la clase de documento, que es la primera clase cargada al iniciar flash, y dentro Lona estamos construyendo nuestra aplicación.

 Clase pública Main extiende Sprite función pública Main (): void if (stage) init (); else addEventListener (Event.ADDED_TO_STAGE, init);  función privada init (e: Event = null): void removeEventListener (Event.ADDED_TO_STAGE, init); // punto de entrada var canvas: Canvas = new Canvas (this); 

Y una versión simplista de Canvas. Tenga en cuenta que usamos un contenedor de objetos de visualización como parámetro para agregar ese bit de control adicional para agregar / eliminar el Lienzo.

 el lienzo público de la clase extiende Sprite lienzo público de la función (contenedor: DisplayObjectContainer) // Guardar el parámetro localmente this.container = container; // Agregar al contenedor container.addChild (this); 

Paso 3: Usar el cargador masivo para cargar activos

En esta aplicación estamos utilizando los llamados BulkLoader: una biblioteca AS3 que tiene como objetivo hacer que la carga y la gestión de los requisitos de carga complejos sean más fáciles y rápidos. Cuando se carga por primera vez, lo usamos para capturar el archivo XML y una imagen de fondo. El siguiente código muestra cómo arrancar el BulkLoader y agregar dos elementos a la cola de carga. los Completar La función se llama cuando todos los elementos están cargados.

 // Init loader loader loader = new BulkLoader ("Canvas"); loader.add ("… /background.jpg", id: "background"); loader.add ("... /settings.xml", id: "xmldata"); // Eventos del cargador loader.addEventListener (BulkLoader.COMPLETE, Complete, false, 0, true); loader.addEventListener (BulkLoader.ERROR, HandleError, false, 0, true); // Iniciar loader loader.start ();

Paso 4: Salvando los Activos Cargados

Guardamos los activos cargados dentro de la clase para su uso posterior. los BulkLoader proporciona una manera fácil de agarrar los artículos que necesitamos. Simplemente llame a la función correspondiente al tipo de objeto y use la cadena de ID del objeto. Las variables estáticas se utilizan para que los datos XML estén disponibles globalmente (por ejemplo, para acceder a una variable estática utilizando Canvas.viewerWidth). los camino La variable especifica dónde se ubicarán las imágenes cargadas externamente. Las imágenes solo se pueden cargar desde el propio servidor web debido a restricciones de seguridad.

 // Obtener imagen de fondo g_background = (loader.getBitmap ("background")). BitmapData; // Obtener datos XML xmldata = loader.getXML ("xmldata"); // Establecer vars estáticos para un fácil acceso viewerWidth = int (xmldata.settings.viewer_width); viewerHeight = int (xmldata.settings.viewer_height); viewerBgColor = uint (xmldata.settings.viewer_bg_color); path = String (xmldata.settings.image_path); customFont = new customFontClass (); contentWidth = int (xmldata.settings.content_width); contentHeight = int (xmldata.settings.content_height); // Eliminar el escucha completo loader.removeEventListener (BulkLoader.COMPLETE, Complete); // Eliminar todas las referencias de datos almacenadas en el cargador loader.clear (); // Eliminar el cargador de la memoria loader = null; // Configurar el visor InitialiseViewer ();

Paso 5: Presentación de la cámara virtual

Como puede o no haber adivinado, la aplicación utiliza una cámara virtual para extraer una parte del lienzo y mostrarla al usuario. La cámara aplica la escala y la traducción a un contenedor de objetos de visualización de manera que solo se ve en la pantalla el área debajo de la cámara. La siguiente demostración le da una mejor idea de cómo funciona.

El código fuente de esta demostración también se incluye en el archivo. Vamos a explicar este ejemplo comenzando con la configuración de los ajustes. Nos gustaría que la región del visor sea de 305 x 230, y la región de contenido, que son las dimensiones de la imagen de la flor, debería intentar mantener la relación de aspecto de la región del espectador para que no se deforme demasiado. Nuestra flor es de 1000 x 750, que está lo suficientemente cerca. Para mostrar la flor completa en la región del visor, la cámara debe tener el mismo tamaño que la flor, que es 1000 x 750..

El siguiente código establece la configuración de la dimensión. En este ejemplo están codificados, pero de lo contrario se toma de XML.

 // Configuraciones viewerWidth = 305; visorHeight = 230; contentWidth = 1000; contentHeight = 750;

A continuación creamos un contenedor de visor. La opción scrollRect se utiliza para recortar cualquier cosa fuera de un rectángulo especificado. Esto es muy útil ya que solo se debe mostrar una parte del lienzo cuando se hace zoom. Es una solución mejor que, por ejemplo, colocar un borde negro alrededor de la aplicación..

 // Visor contenedor viewerContainer = new Sprite (); viewerContainer.scrollRect = new Rectangle (0,0, viewerWidth, viewerHeight); addChild (viewerContainer);

Al contenedor del visor añadimos otra. Duende llamado espectador. La función de espectador es simplemente actuar como un contenedor para cualquier cosa que deba servir como contenido para la cámara. Facilita la adición de varios elementos a la región de contenido.

 // Scroll de la página var viewerScroller: Sprite = new Sprite (); viewerContainer.addChild (viewerScroller);

Añadir contenido a la espectador. En este caso la imagen de la flor..

 // Contenido contenido = nuevo Sprite (); viewerScroller.addChild (contenido); var bmp: Bitmap = nueva imagen (); content.addChild (bmp);

Ahora agregue el Cámara clase. Aunque todavía tenemos que hacer el Cámara clase, su constructor tomará las dimensiones del espectador como parámetro, y la función Poner un objectivo tiene el contenido Duende como parametro Posicionamos el Cámara En medio del contenido y dale una primera actualización..

 // Agregar cámara virtual = cámara nueva (viewerWidth, viewerHeight); cam.SetTarget (viewerScroller); cam.x = contentWidth / 2; cam.y = contentHeight / 2; cam.Update ();

Con todo este código en su lugar, podemos renderizar y manipular la cámara. Dentro de una Evento.ENTER_FRAME bucle puedes correr cam.Update () para actualizar la vista de la cámara. Sin embargo, es más eficiente actualizar solo sobre un cambio. Cambiando cam.x y cam.y Puede mover la cámara alrededor, y cambiando cam.scaleX y escala de cámara Puedes cambiar la escala. Esto es exactamente lo que hacen las teclas del teclado en el ejemplo.


Paso 6: Cámara de clase A una mirada más cercana

Aquí echamos un vistazo a las partes internas de la Cámara. En la función de constructor, agregamos algunos gráficos que son necesarios para la manipulación de la escala de escala de la cámara. También almacenamos las dimensiones de contenido del visor localmente dentro de la clase.

 función pública Cámara (ancho: int, altura: int, initialZoom: Número = 1) // Sprite usado para dar a la cámara un ancho y alto. g = nueva forma (); g.graphics.drawRect (0, 0, 10, 10); g.graphics.endFill (); addChild (g); // Establecer las dimensiones del rectángulo del visor tw = ancho; th = altura; // Zoom inicial this.scaleX = this.scaleY = initialZoom; 

A continuación, adjunte la cámara a un objeto. La cámara se convierte en la misma escala que el objeto..

 función pública SetTarget (target: Sprite): void this.target = target; // ajustar las dimensiones de la cámara g.width = target.width; g.height = target.height; 

Esta es la parte más interesante y el motor de la cámara. La escala y la traducción se aplican al objeto adjunto a la cámara al darle una nueva matriz de transformación. Revisar la Matriz Clase en la documentación de AS3 para obtener más información sobre el uso de matrices..

 Actualización de la función pública (): void cw = this.width; ch = this.height; tscaleX = tw / cw; tscaleY = th / ch; // poner nuevos valores de escala mat.a = tscaleX; mat.d = tscaleY; // Poner nuevos valores de posición (traducción). // la posición de la cámara se hace negativa, porque, por ejemplo, cuando la cámara se mueve hacia la derecha, la página debe moverse hacia la izquierda para acomodarse. // se agregan cw y ch para mover la página al centro del área de visualización // todas las posiciones se escalan en consecuencia mat.tx = (-mat.tx + cw / 2) * tscaleX; mat.ty = (-mat.ty + ch / 2) * tscaleY; target.transform.matrix = mat; 

Paso 7: Configuración del visor

Volvemos a nuestra aplicación. En este paso sentamos las bases de los llamados Página Objetos que contienen el lienzo con imágenes y texto. Primero, crea un fondo para toda la aplicación. El color se especifica a partir de XML..

 // Fondo var bg: Sprite = new Sprite (); bg.graphics.beginFill (xmldata.settings.bgcolor); bg.graphics.drawRect (0, 0, stage.stageWidth, stage.stageHeight); bg.graphics.endFill (); addChild (bg);

Como en el ejemplo con el Cámara y la flor, estamos usando pageContainer y pageScroller y Cámara. Esto debería parecer bastante familiar..

El siguiente es agregar todos los Página objetos requeridos como se especifica en el XML. En nuestro ejemplo solo hemos creado una página. Tenga en cuenta que el Página La clase aún no existe, ya que estamos creando este siguiente paso.. páginas es una matriz que contendrá todo Página referencias para su uso posterior.

Parámetros utilizados por Página son

  • pageScroller: la Duende a lo que el Página se agregará a
  • pag: un objeto de datos XML que contiene toda la información dentro de una página determinada (todas las imágenes y texto)
  • g_background: la textura de fondo
 // Agregar páginas pages = new Array (xmldata.page.length ()); para cada (var p: XML en xmldata.page) var id: int = int (p.attributes () [0]); pages [id] = nueva página (pageScroller, p, g_background); 

Paso 8: Creando una página

A continuación se muestra el constructor de Página. Simplemente guardamos todos los parámetros localmente en la clase para su uso posterior.

 Página de función pública (contenedor: DisplayObjectContainer, datos: XML, fondo: BitmapData) this.id = id; this.container = contenedor; esto.data = datos; this.background = fondo; this.title = String (data.attributes () [1]); 

Ahora un poco más cosas interesantes. los Carga funcion de Página comienza tomando la textura de fondo que cargamos antes y envolviéndola sobre el lienzo. Para hacer esto necesitamos saber el tamaño de la imagen de fondo que estamos haciendo en bucle y el tamaño de todo el lienzo. Crear un Duende llamado g_background que funciona como un contenedor gráfico. Agregue un color de fondo sólido para evitar que se muestren líneas entre las imágenes de mapa de bits..

 var b: int = background.width; var h: int = background.height; var trueWidth: int = Canvas.contentWidth; var trueHeight: int = Canvas.contentHeight; // capa de fondo g_background = new Sprite (); addChild (g_background); // Un color de fondo sólido var bg: Sprite = new Sprite (); bg.graphics.beginFill (Canvas.viewerBgColor); bg.graphics.drawRect (0, 0, trueWidth, trueHeight); bg.graphics.endFill (); g_background.addChild (bg);

Envolver la textura de fondo utiliza dos bucles, solo verticalmente y uno horizontalmente. Se mantiene en bucle hasta que se alcanza el borde. Todas las fichas en una posición uniforme (como (2,2), (4,2), (4,6), etc.) se voltean usando escalaX o escalable. Esto hace que la textura fluya hacia la siguiente sin problemas. La verificación de si un número es par se hace usando el operador de módulo (%). Si el resto de un número después de dividir por 2 es cero, entonces ese número debe ser par. Alrededor de los bordes recortamos cualquier textura que salga de las dimensiones del contenido como se especifica en verdadero ancho y ciertoHeight. Es importante que el Página el objeto mantiene este tamaño ya que al hacerlo más grande cambiará la relación de aspecto y causará que la pantalla se deforme.

 // Añadir imagen de fondo en bucle var i: int, j: int; mientras (i * b < trueWidth)  j = 0; while (j * h < trueHeight)  // new bitmap var s:Bitmap = new Bitmap(background); // position s.x = i * b; s.y = j * h; // alternate horizontal and vertical flip if (i % 2 != 0)  s.scaleX *= -1; s.x += b;  if (j % 2 != 0)  s.scaleY *= -1; s.y += h;  // clip if (i * b + b > verdadero ancho || j * h + h> trueHeight) var clipw: int = Math.min (trueWidth - i * b, b); var cliph: int = Math.min (trueHeight - j * h, h); var nbd: BitmapData = new BitmapData (clipw, cliph); nbd.copyPixels (background, new Rectangle (0, 0, clipw, cliph), new Point ()); s.bitmapData = nbd; if (s.scaleX == -1) s.x - = b - clipw; if (en la escalaY == -1) s.y - = h - cliph;  // agregar mapa de bits para mostrar la lista g_background.addChild (s); j ++;  i ++; 

El resultado de la repetición de fondo debe ser algo como esto. Se agregan bordes oscuros para mayor claridad.


Paso 9: Cargando texto

Comencemos nuestro viaje de llenado de páginas agregando texto. Ir a través de todas las entradas XML etiquetadas como "texto" y pasar sus datos a la Añadir texto función.

 text = new Array (); para cada (var text: XML en data.text) AddText (texto); 

los Añadir texto La función se ve así. La primera parte del código valida los datos XML. En caso de que algunos campos no estén rellenados, se agregará un valor estándar.. Texto rápido es una clase usada para crear un campo de texto con ciertas opciones. Finalmente, el texto debe ser excluido de la interacción del mouse usando mouseEnabled = falso y mouseChildren = falso.

 función privada AddText (texto: XML): void if (! text.font) text.font = null; if (! text.size) text.size = 12; if (! text.color) text.color = 0x000000; if (! text.bold) text.bold = 0; if (! text.italic) text.italic = 0; var qt: QuickText = new QuickText (text.x, text.y, String (text.content), Canvas.customFont, int (text.size), uint (text.color), Boolean (text.bold), Boolean ( text.italic)); qt.blendMode = BlendMode.LAYER; texts.push (qt); addChild (qt); qt.mouseEnabled = false; qt.mouseChildren = false; 

La siguiente imagen muestra todas las opciones del Texto rápido clase:

Y el resultado de la nueva página incluye texto:


Paso 10: Cargando Imágenes

El primer paso aquí es crear Imagen Objetos que contendrán los datos XML, el mapa de bits y algún texto descriptivo. Los oyentes se aplican directamente a la interacción del ratón. Todos estos Imagen Los objetos se almacenan en una matriz para un fácil acceso posterior..

 // toma todas las imágenes de imágenes = nueva matriz (); para cada (var imagen: XML en data.image) // nuevo objeto de imagen con información en él var picture: Picture = new Picture (image); imágenes.push (imagen); // agregar oyentes a picture picture.addEventListener (MouseEvent.MOUSE_OVER, PictureMouseOver); picture.addEventListener (MouseEvent.MOUSE_OUT, PictureMouseOut); picture.addEventListener (MouseEvent.MOUSE_DOWN, PictureMouseDown); 

Y aquí está la versión básica de la Imagen clase, simplemente manteniendo los datos XML. Imagen se extiende Duende, Ya podemos posicionarlo en algún lugar. La configuración de la escala se verifica antes de usarse, porque si el usuario la omite en el XML devolverá 0. El valor estándar para la escala es 1.

 Función pública Imagen (datos: XML) title = data.title; description = data.description; url = data.url; page = data.page; x = data.x; y = data.y; if (Number (data.scale)! = 0) imgscale = Number (data.scale); 

Crear un nuevo BulkLoader Al igual que la primera vez, pero ahora para cargar lotes de imágenes. Vamos a cargar 5 imágenes a la vez y las mostraremos cuando estén listas. Seguirá obteniendo nuevas imágenes hasta que todas estén listas. La función Completar Se llama al finalizar cada lote..

 // Crear un cargador a granel. loader = new BulkLoader ("page" + id); loader.addEventListener (BulkLoader.COMPLETE, Complete, false, 0, true);

// establece la cantidad total de imágenes totalPictures = pictures.length; // toma las primeras 5 imágenes o la cantidad total de imágenes si hay menos. i = 0; mientras yo < Math.min(totalPictures,5)) loader.add(String(Canvas.path + pictures[i].url), id: "img" + i ); i++; // Start loader loader.start();

Paso 11: Cargando imágenes (continuación)

En este paso ponemos los datos cargados dentro. Imagen objetos. los artículos La propiedad del cargador contiene todos los objetos que se han cargado. Recorra todos esos objetos y verifique si son una imagen. Cada Mapa de bits se le da a la correspondiente Imagen objeto y el Imagen Se añade al lienzo. También eliminamos la imagen cargada de la lista de elementos del cargador para evitar conflictos con un lote posterior de imágenes cargadas.

 // Imagen por lotes cargada. guardar los datos en objetos de imagen individuales. i = amountPicturesLoaded; para cada (var item: LoadingItem en loader.items) if (item.isImage ()) pictures [i] .SetImage (loader.getBitmap (item.id)); loader.remove (item.id); AddPicture (imágenes [i]); i ++; amountPicturesLoaded ++; 

Y una mirada más cercana a la SetImage funcion de Imagen.

 función pública SetImage (ob: Bitmap): void // si no se cargan datos de imagen, no muestra nada si (ob == nulo) devuelve; // guarda los datos dentro de la clase img = ob; // muestra la imagen addChild (img); // escala img.scaleX = img.scaleY = imgscale; 

Y agregar una imagen al lienzo es tan fácil como llamar addChild.

 función privada AddPicture (pict: Picture): void addChild (pict); 

El resultado ahora se convierte en:


Paso 12: Agregar la página

Agregar algo a la vista de la cámara se hace agregando un niño a la espectador envase. Hemos añadido el espectador a cada Página objeto como parámetro para que podamos agregarlo como un niño llamando a la Show() funcion de Página.

 función pública Show (): void container.addChild (this); 

Volver a la Lona class y llame a las funciones Load () y Show () cuando nos gustaría mostrarle al usuario una página. En caso de que el Página ya está cargado, Carga() Volverá directamente por lo que no se realizan acciones innecesarias. La corriente Página que estamos mostrando se guarda en la clase como página. Esta referencia será importante para la interacción de la página..

 función privada ShowPage (nr: int): void // hide page old if (page) page.Hide (); // establecer nueva página page = pages [nr]; page.Load (); page.Show (); 

Paso 13: Modos de Zoom

Ahora que hemos creado nuestra página con imágenes y texto, es necesario escalarla para que quepa dentro de nuestra región de visor. Estamos utilizando las variables estáticas públicas. enfocar y magnifyStep para este propósito. magnifyStep es una matriz que contiene todos los diferentes valores de escala de la cámara y enfocar es la posición actual de magnifyStep La cámara está escalada a Para saber qué valor de escala se necesita para ajustar el contenido dentro del visor, necesitamos saber la proporción entre el contenido y las regiones del visor. Para tener en cuenta las relaciones de aspecto incorrectas, tomamos la relación mínima entre el ancho y las alturas de la siguiente manera:

 // Set magnify steplist magnifyStepList [0] = Math.min (viewerWidth / contentWidth, viewerHeight / contentHeight);

Nos gustaría hacer un zoom al hacer clic en el lienzo. Agrega un evento de ratón al hitfield de Página. El hitfield es básicamente los gráficos en el fondo de Página y porque es una Duende Podemos ponerle la interacción con el ratón..

 page.hitField.addEventListener (MouseEvent.MOUSE_DOWN, MouseZoomIn);

Al hacer clic con el mouse, nos gustaría que la cámara se reduzca a la posición de zoom en el magnifyStepList y pasar al punto en el lienzo en el que hicimos clic. Recuerde del ejemplo que a medida que la cámara se hace más pequeña (escala), el zoom en el lienzo se hace más grande. Es por esto que disminuimos el zoom entero por el valor uno. Obtener la posición del mouse que seleccionamos en el lienzo es fácil usando page.mouseX y page.mouseY. Flash convierte automáticamente los números para que aparezcan como locales, lo que significa que si la página es, por ejemplo, 2000 px reducida en un 50% y hace clic a mitad de camino, devuelve 1000 px, aunque la posición del ratón en las coordenadas de la escala es mucho menor.

 función privada MouseZoomIn (e: MouseEvent): void var pt: Point; if (! cam.bZooming && zoom> 0) // Zoom in one step zoom--; // Nuevo punto de cámara. Corregir los límites. pt = punto nuevo (page.mouseX, page.mouseY); CameraBounds (pt); cam.Zoom (pt.x, pt.y, magnifyStepList [zoom]); 

Paso 14: Corrigiendo la posición de la cámara

Para mantener el área de la cámara dentro del lienzo, deberemos corregir la posición dentro de los límites de la cámara. Mirando el ejemplo de la cámara de nuevo para una demostración de esto. La cámara está centrada alrededor de sí misma, por lo que la posición horizontal, por ejemplo, deberá permanecer dentro 0 + ancho medio de la cámara y contenido ancho - cámara de ancho medio. Una forma confiable de calcular el ancho de la cámara cuando se amplía la imagen es contentWidth / 2 * magnifyStepList [zoom], porque la cámara en su condición inicial no ampliada tiene el tamaño contenido ancho (mismo tamaño que el lienzo).

 Función privada CameraBounds (pt: Point): void // horizontalmente if (pt.x < contentWidth/2 * magnifyStepList[zoom]) pt.x = contentWidth/2 * magnifyStepList[zoom]; else if (pt.x > contentWidth - contentWidth / 2 * magnifyStepList [zoom]) pt.x = contentWidth - contentWidth / 2 * magnifyStepList [zoom]; // verticalmente si (pt.y < contentHeight/2 * magnifyStepList[zoom]) pt.y = contentHeight/2 * magnifyStepList[zoom]; else if (pt.y > contentHeight - contentHeight / 2 * magnifyStepList [zoom]) pt.y = contentHeight - contentHeight / 2 * magnifyStepList [zoom]; 

En la imagen de abajo se muestra la cámara y el lienzo, con zoom una vez. Las líneas rojas muestran los bordes que la cámara no puede cruzar y debe permanecer dentro.


Paso 15: Hacer que el zoom funcione

El zoom se realiza agregando escala a la cámara. Estamos usando el Tweener clase y la "EasyOutQuint" Transición para que esto suceda de una manera suave.. bZooming es una variable que se usa para ver si la cámara ya está enfocada o no. No puede hacer zoom en la página nuevamente mientras aún está ocupada escalando hacia arriba o hacia abajo. En cada actualización de la cámara la función. Actualizar Se llama, que realiza la escala en el contenido..

 Función pública Zoom (newx: int, newy: int, newscale: Number): void bZooming = true; Tweener.addTween (este, tiempo: 2, x: newx, y: newy, transición: "easeOutQuint", scaleX: newscale, scaleY: newscale, onComplete: function (): void bZooming = false;, onUpdate: Update ); 

Paso 16: Una mirada más cercana a las imágenes

Recuerda que hemos añadido MouseEvent Oyentes a todas las imágenes dentro de la página. Lo que nos gustaría hacer es ampliar una imagen cuando se hace clic en una de ellas y asegurarnos de que encaja bien en la región del visor. Las imágenes más pequeñas que la región del visor real no deben escalarse más allá de su resolución.

 función privada PictureMouseDown (e: MouseEvent): void var newScale: Number; var screenRatio: Number = Canvas.viewerWidth / Canvas.viewerHeight; var imgW: Number = Math.max (e.target.width * 1.05, Canvas.viewerWidth); var imgH: Number = Math.max (e.target.height * 1.05, Canvas.viewerHeight); var imgRatio: Number = e.target.img.width / e.target.img.height // Calcular la escala de la imagen si (imgRatio < 1) newScale = imgH / Canvas.contentHeight; else newScale = imgW / Canvas.contentWidth; Canvas.cam.Zoom(e.target.x + e.target.width/2, e.target.y + e.target.height/2, newScale); Canvas.cam.bLocked = true; PictureMouseDisable(); 

El concepto básico aquí es que primero debe determinarse la relación de aspecto de una imagen. Si el ancho de una imagen es mayor que la altura, entonces imgRatio < 1 se mantendrá verdadero y viceversa si la altura es mayor que el ancho. Siempre escalaremos a la parte más grande de una imagen, lo que significa que si la imagen es, por ejemplo, 200x400px, trataremos la imagen como un cuadrado de 400x400. Otra adición aquí es que primero escalamos la imagen con 1.05, lo que significa que la imagen se vuelve un 5% más grande. De esta manera, la imagen no toca los lados cuando se acerca. Para calcular la escala de una imagen en comparación con el tamaño del contenido, la dividimos por la altura o el ancho del contenido..

Llama a Enfocar Función de la cámara y moverse a la mitad de la imagen en la que nos estamos enfocando y aplicar la nueva escala que hemos calculado..

Aquí está el proceso de zoom de la imagen que se muestra en acción. Observe cómo la cámara se mantiene dentro de los límites de la página y cómo encaja perfectamente toda la imagen, incluida la descripción, dentro de la pantalla.


Paso 17: Desplazar la página

Si no lo ha notado, al ampliar una página, puede mover el cursor del mouse hacia los bordes de la pantalla para desplazarse y ver más de la página. El código que se muestra a continuación puede parecerte un poco extraño; Es algo que he escrito hace un tiempo para un motor de juego de estilo RTS y lo he estado reutilizando desde entonces para cualquier cosa que necesite desplazamiento. Los principios básicos aquí es que usted verifica dónde está la posición del mouse, y en caso de que se mueva sin un cierto rango alrededor de los tamaños (mouse_scroll_areax_reduced y mouse_scroll_areay_reduced) entonces comenzará a moverse hacia un lado a una velocidad proporcional a la distancia que se encuentre dentro de ese rango. Cuando el cursor del mouse no está dentro del rango, se arrastrará el desplazamiento para disminuir la velocidad eventualmente.

 // Obtenga la cantidad de desplazamientos necesarios según la posición del mouse mx = viewerContainer.mouseX; my = viewerContainer.mouseY; si (mx) < mouse_scroll_areax && mx > 0) scrollAmountX = ((((mx - mouse_scroll_areax) / mouse_scroll_areax_reduced) * mouse_scroll_factor) + .5) << 0;  else if ((viewerContainer.width - mx) < mouse_scroll_areax && mx < viewerContainer.width)  scrollAmountX = (((1 - (viewerContainer.width - mx) / mouse_scroll_areax_reduced) * mouse_scroll_factor) + .5) << 0;  if (my < mouse_scroll_areay && my > 0) scrollAmountY = ((((my - mouse_scroll_areay) / mouse_scroll_areay_reduced) * mouse_scroll_factor) + .5) << 0;  else if ((viewerContainer.height - my) < mouse_scroll_areay && my < viewerContainer.height)  scrollAmountY = (((1 - (viewerContainer.height - my) / mouse_scroll_areay_reduced) * mouse_scroll_factor) + .5) << 0;  // Put drag on the scroll,