Ampliar la perspectiva de tu Web con Deep Zoom Composer & Silverlight 3

Todos hemos visitado alguna web, en busca de un catálogo de productos. Cierto es, que a veces, nos gustaría tener de un solo vistazo todos los productos, para que más tarde pudiéramos seleccionar el deseado. Pero esto supondría tener un catálogo de dimensiones considerables.

En este artículo propongo una idea para conseguir que todo un catálogo de artículos esté disponible a la vista del usuario, eso sí, sin ocuparnos la pantalla por completo. Además dando la posibilidad de ver al detalle la imagen de cada uno de los artículos, simplemente con el scroll del ratón. Pero para conseguir este objetivo necesitamos la ayuda de dos brazos fuertes y ágiles, informáticamente hablando claro. Usaremos Silverlight 3 y Deep Zoom Composer.

Comenzamos abriendo Deep Zoom Composer, en la ventana inicial del programa elegimos nuevo proyecto, otorgando el nombre y la ubicación del mismo como podemos observar en la imagen:

 

1

 

Ahora importamos las imágenes, que van a ser el catálogo de los distintos artículos que vamos a ofrecer al usuario. En mi caso he elegido como artículos bicicletas y accesorios de las mismas. Para importar elegimos de las tres pestañas situadas en la parte superior la de Importar.

2

Luego haremos clic sobre añadir imágenes y seleccionamos las diferentes imágenes.

3

Una vez tengamos las imágenes seleccionadas vamos a componer nuestra imagen final. Para ellos seleccionamos la pestaña Componer. Seleccionamos las imágenes que se encuentran en la parte inferior de la pantalla y las arrastramos al área de diseño como podemos observar en la siguiente imagen:

4

Al importar las imágenes al área de diseño de la imagen final, estas se encuentran de forma desorganizada. Afortunadamente las podemos ordenar haciendo clic con el botón derecho sobre ellas y eligiendo Organizar->Organizar en un Grid.

5

Nos aparecerá una nueva ventana emergente en la que se ofrece la posibilidad de alinear las distintas fotografías. En mi caso elegiré la opción restringir por filas puesto que deseo alinear las diferentes imágenes de forma vertical. El número de filas que utilizo son cinco y el Pading tomará el valor cero, debido que no quiero que haya separación entre las diferentes columnas. Esta configuración la podéis variar a vuestro antojo, además antes de confirmar podéis aplicar las distintas configuraciones y ver de forma previa la composición de las distintas imágenes.

6

Presionamos ok y se realizarán los correspondientes cambios.

Es hora de realizar la exportación de nuestra composición de imágenes. Seleccionamos la pestaña Exportar de la parte superior del programa. Elegimos la pestaña personalizado en la parte derecha del programa y elegimos el formato Silverlight Deep Zoom. Introducimos un nombre para la composición y la ubicación de la misma. Por otro lado elegimos la plantilla Deep Zoom Navigation, que es la plantilla por defecto del programa. El formato es JPG la calidad 95 y el tamaño es de 800. Presionamos OK y se exportará nuestra composición de imágenes.

7

También tenemos la posibilidad de pre visualizar la composición final antes de exportarla, si la pre visualización de la composición es correcta, presionamos Exportar y se realizará la acción.

Ahora vamos a realizar la segunda parte del proyecto, que es la creación de una aplicación Silverlight en la que vamos a incluir la composición de imágenes creada con anterioridad. A su vez le otorgaremos las funcionalidades para que el usuario pueda visionar con todo detalle cada producto.

Abrimos Visual Studio 2008, seleccionamos Proyecto->Nuevo Proyecto. En la ventana emergente seleccionamos Silverlight en el área Tipo de Proyecto. Seguidamente en el área de plantillas elegimos Aplicación Silverlight. Introducimos el nombre del proyecto y la ubicación presionamos Aceptar y se creará un nuevo proyecto Silverlight 3.

8

Una vez construido nuestro proyecto debemos construir una nueva solución F6. De este modo se cargará el archivo .xap del lado del cliente, dentro de la carpeta BIN. Nos situamos en el proyecto creado con anterioridad de Deep Zoom Composer. Copiamos la carpeta GeneratedImages en la carpeta BIN.

9

 

 

Ahora vamos a introducir el objeto que nos permite en .Net escalar las imágenes. Para ello abrimos el archivo MainPage.xaml e introducimos el citado objeto como podemos observar en el siguiente fragmento de código:

Code Snippet
  1. <UserControl x:Class=»CatalogoArticulos.MainPage»
  2.    xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»
  3.    xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»
  4.    xmlns:d=»http://schemas.microsoft.com/expression/blend/2008″ xmlns:mc=»http://schemas.openxmlformats.org/markup-compatibility/2006″
  5.    mc:Ignorable=»d» d:DesignWidth=»640″ d:DesignHeight=»480″>
  6.         <Grid x:Name=»LayoutRoot»>
  7.             <MultiScaleImage x:Name=»Escalar» Source=»../GeneratedImages/dzc_output.xml»/>
  8.         </Grid>
  9.     </UserControl>

Como podemos observar el origen del objeto que nos permite escalar las diferentes imágenes, lo obtenemos de la carpeta previamente copiada. En concreto del archivo dzc_output.xml. Que es la composición de imágenes exportadas en la primera parte de este artículo.

Si ejecutamos el proyecto (F5), podemos observar como se cargan las imágenes pero lamentablemente no tenemos control sobre los eventos del ratón para poder aumentar las imágenes y verlas con todo detalle.

Es por esta razón que debemos abrir el archivo MainPage.xaml.cs e incluir el  siguiente fragmento de código para poder controlar los distintos comportamientos del objetos escalar:

 

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Documents;
  8. using System.Windows.Input;
  9. using System.Windows.Media;
  10. using System.Windows.Media.Animation;
  11. using System.Windows.Shapes;
  12.  
  13. namespace CatalogoArticulos
  14. {
  15.     public partial class MainPage : UserControl
  16.     {
  17.         double zoom = 1;
  18.         bool duringDrag = false;
  19.         bool mouseDown = false;
  20.         Point lastMouseDownPos = new Point();
  21.         Point lastMousePos = new Point();
  22.         Point lastMouseViewPort = new Point();
  23.  
  24.  
  25.         public double ZoomFactor
  26.         {
  27.             //establecimiento del valor de ampliación
  28.             get { return zoom; }
  29.             set { zoom = value; }
  30.         }
  31.         public MainPage()
  32.         {
  33.             InitializeComponent();
  34.             //controlar el movimiento decendente del ratón
  35.             //al presionar el botón izquierdo
  36.             this.MouseLeftButtonDown +=
  37.         delegate(object sender, MouseButtonEventArgs e)
  38.         {
  39.             lastMouseDownPos = e.GetPosition(Escalar);
  40.             lastMouseViewPort = Escalar.ViewportOrigin;
  41.  
  42.             mouseDown = true;
  43.  
  44.             Escalar.CaptureMouse();
  45.         };
  46.             //controlar el movimiento ascendente del ratón
  47.             //al presionar el botón izquierdo
  48.             this.MouseLeftButtonUp += delegate(object sender, MouseButtonEventArgs e)
  49.             {
  50.                 if (!duringDrag)
  51.                 {
  52.                     bool shiftDown =
  53.                       (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;
  54.                     double newzoom = zoom;
  55.  
  56.                     if (shiftDown)
  57.                     {
  58.                         newzoom /= 2;
  59.                     }
  60.                     else
  61.                     {
  62.                         newzoom *= 2;
  63.                     }
  64.  
  65.                     Zoom(newzoom, Escalar.ElementToLogicalPoint(this.lastMousePos));
  66.                 }
  67.                 duringDrag = false;
  68.                 mouseDown = false;
  69.  
  70.                 Escalar.ReleaseMouseCapture();//actualización del objeto que nos permite escalar las imagenes
  71.             };
  72.             //localizamos la posición del puntero
  73.             //a trevés del evento MouseMove
  74.             this.MouseMove += delegate(object sender, MouseEventArgs e)
  75.             {
  76.                 lastMousePos = e.GetPosition(Escalar);
  77.                 if (mouseDown && !duringDrag)
  78.                 {
  79.                     duringDrag = true;
  80.                     double w = Escalar.ViewportWidth;
  81.                     Point o = new Point(Escalar.ViewportOrigin.X, Escalar.ViewportOrigin.Y);
  82.                     Escalar.UseSprings = false;
  83.                     Escalar.ViewportOrigin = new Point(o.X, o.Y);
  84.                     Escalar.ViewportWidth = w;
  85.                     zoom = 1 / w;
  86.                     Escalar.UseSprings = true;
  87.                 }
  88.  
  89.                 if (duringDrag)
  90.                 {
  91.                     Point newPoint = lastMouseViewPort;
  92.                     newPoint.X += (lastMouseDownPos.X – lastMousePos.X) /
  93.                       Escalar.ActualWidth * Escalar.ViewportWidth;
  94.                     newPoint.Y += (lastMouseDownPos.Y – lastMousePos.Y) /
  95.                       Escalar.ActualWidth * Escalar.ViewportWidth;
  96.                     Escalar.ViewportOrigin = newPoint;
  97.                 }
  98.             };
  99.             //llamada a la clase Helper con los paremetros de aumento
  100.             new MouseWheelHelper(this).Moved +=
  101.               delegate(object sender, MouseWheelEventArgs e)
  102.               {
  103.                   e.Handled = true;
  104.  
  105.                   double newzoom = zoom;
  106.  
  107.                   if (e.Delta < 0)
  108.                       newzoom /= 1.3;
  109.                   else
  110.                       newzoom *= 1.3;
  111.  
  112.                   Zoom(newzoom, Escalar.ElementToLogicalPoint(this.lastMousePos));
  113.                   Escalar.CaptureMouse();
  114.               };
  115.         }
  116.         //rango de aumento
  117.         private void Zoom(double newzoom, Point p)
  118.         {
  119.             if (newzoom < 0.5)
  120.             {
  121.                 newzoom = 0.5;
  122.             }
  123.  
  124.             Escalar.ZoomAboutLogicalPoint(newzoom / zoom, p.X, p.Y);
  125.             zoom = newzoom;
  126.         }
  127.     }
  128. }

 

 

 

En este fragmento de código se hace una llamada a la clase MouseWheelHelper, que permite realizar el escalado de las diferentes imágenes. El contenido de esta clase lo podéis descargar aquí. Ahora solo tenemos que situarnos en nuestro proyecto, presionar sobre él con el botón derecho y elegir Añadir->Nuevo elemento.

10

Seguidamente en la ventana emergente en el área de plantillas elegimos la plantilla clase y la nombramos como MouseWheelHelper.cs.

11

Dentro de la misma incluiremos  el contenido de la clase que hemos descargado con anterioridad. De esto modo conseguiremos que nuestro proyecto controle los eventos del ratón de forma correcta.

Finalmente ejecutamos nuestra aplicación F5, podemos observar tenemos todo el catálogo de artículos en una sola vista, si bien es cierto que podemos aumentar cada articulo y verlo con detalle sin perder calidad a la hora de realizar dicha acción.

12   13

De este modo podemos crear aplicaciones, en las que necesitemos un reducido espacio a la hora de situarlo en nuestra web. Sin embargo no ofreceremos posibilidad al usuario para poder tener una vista diferente de los distintos artículos que se ofertan en la misma. Todo utilizando la eficiencia de Silverlight 3 y la flexibilidad y creatividad de Deep Zoom Composer.

Problema Al actualizar Silverlight 3 “unable to start debugging Silverlight”

Recientemente he tenido un problema al actualizar Silverlight 2 a Silverlight 3. He instalado todos los programas y complementos que requiere Microsoft desde la página de inicio de Silverlight 3 get started. He creado diversos proyectos y hasta aquí no tengo ningún problema pero cuando trato de depurar mis proyectos me ocurre el error “unable to start debugging Silverlight”

1 

El problema radicaba en que tenía distintas versiones del SDK instaladas en mi equipo.

2

La solución pasa por desinstalar el SDK de Silverlight 2 y el plugin de la misma versión e instalar las Silverlight 3 Tools for visual Studio 2008 sp1, de este modo la próxima vez que depure mi proyecto no tuve ningún problema.