Compartir a través de


Inicio rápido: Agregar un control SemanticZoom (HTML)

[ Este artículo está destinado a desarrolladores de Windows 8.x y Windows Phone 8.x que escriben aplicaciones de Windows Runtime. Si estás desarrollando para Windows 10, consulta la documentación más reciente ]

Aprende a usar el control SemanticZoom para usar el zoom entre dos vistas del mismo contenido.

Requisitos previos

¿Qué es un control SemanticZoom?

El control SemanticZoom permite al usuario cambiar entre dos vistas distintas del mismo contenido. Una de estas vistas es la vista principal del contenido. La otra es una vista del mismo contenido, representado de manera que permita al usuario navegar rápidamente por él. Por ejemplo, al visualizar una libreta de direcciones, el usuario puede acercar una letra y ver los nombres asociados a dicha letra.

Para proporcionar esta funcionalidad de ampliación, el control SemanticZoom usa otros dos controles: uno para proporcionar la vista acercada y otro para proporcionar la vista alejada

<div data-win-control="WinJS.UI.SemanticZoom">   
                
    <!-- The control that provides the zoomed-in view goes here. -->

    <!-- The control that provides the zoomed-out view goes here. -->

</div>

Estos controles pueden ser dos controles cualesquiera que implementen la interfaz IZoomableView. WinJS proporciona un control que implementa la interfaz IZoomableView: el control ListView. Los ejemplos de este inicio rápido muestran cómo usar el control SemanticZoom con dos controles ListView.

No confundas el zoom semántico con el zoom óptico. Aunque comparten la misma interacción y el comportamiento básico (muestran más o menos detalle en función de un factor de zoom), el zoom óptico se refiere al ajuste de ampliación de un área de contenido o un objeto, como una fotografía.

Crear tus datos

Para usar un control SemanticZoom, necesitas un IListDataSource que contenga información de grupo. Un modo de crear un IListDataSource consiste en crear un objeto WinJS.Binding.List. Cada WinJS.Binding.List tiene una propiedad dataSource que devuelve un IListDataSource que contiene tus datos.

  1. Agrega un nuevo archivo JavaScript al proyecto para que contenga los datos. Asígnale el nombre "data.js".

  2. En el archivo data.js que acabas de crear, crea el origen de datos subyacente que proporcionará datos a tus controles ListView. En este ejemplo, se crea un objeto WinJS.Binding.List a partir de una matriz de objetos JSON (myData):

    
    // Start of data.js
    (function () {
        "use strict";
    
    
    
        var myData = [
        { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png" },
        { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png" },
        { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png" },
        { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png" },
        { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png" },
        { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png" },
        { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png" },
        { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png" },
        { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png" },
        { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png" },
        { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png" },
        { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png" },
        { title: "Orangy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Orangy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Absolutely Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Absolutely Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Triple Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Triple Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Double Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Double Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Double Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Green Mint", text: "Gelato", picture: "images/60Mint.png" }
        ];
    
        // Create a WinJS.Binding.List from the array. 
        var itemsList = new WinJS.Binding.List(myData);
    

    Nota  Estos datos hacen referencia a varias imágenes. Para obtener las imágenes, descarga la Muestra de agrupación de ListView y SemanticZoom y después copia las imágenes de la muestra en tu proyecto. También puedes usar tus propias imágenes —pero asegúrate de actualizar el valor de la propiedad picture en los datos.

     

    Sugerencia  

    No tienes por qué limitarte a usar un WinJS.Binding.List: también podrías usar un StorageDataSource o un VirtualizedDataSource personalizado. Para ver más información sobre cómo crear un origen de datos personalizado, consulta el tema sobre cómo crear un origen de datos personalizado.

     

  3. Crea una versión del origen de datos que contenga información de agrupación. Si estás usando un WinJS.Binding.List, puedes llamar a su método createGrouped para que cree una versión agrupada del objeto List. El método createGrouped toma 3 parámetros.

    • getGroupKey: una función que, según un elemento dado de la lista, devuelve la clave de grupo a la que pertenece el elemento.
    • getGroupData: una función que, según un elemento dado de la lista, devuelve el objeto de datos que representa el grupo al que pertenece el elemento.
    • compareGroups: una función que compara dos grupos y devuelve un valor menor que cero si el primer grupo es menor que el segundo; devuelve cero si los grupos son iguales, y devuelve un valor positivo si el primer grupo es mayor que el segundo.

    Este ejemplo usa el método List.createGrouped para crear una versión agrupada de List. Usa la primera letra de cada título de elemento para definir los grupos.

        // Sorts the groups.
        function compareGroups(leftKey, rightKey) {
            return leftKey.charCodeAt(0) - rightKey.charCodeAt(0);
        }
    
        // Returns the group key that an item belongs to.
        function getGroupKey(dataItem) {
            return dataItem.title.toUpperCase().charAt(0);
        }
    
        // Returns the title for a group.
        function getGroupData(dataItem) {
            return {
                title: dataItem.title.toUpperCase().charAt(0)
            };
        }
    
        // Create the groups for the ListView from the item data and the grouping functions
        var groupedItemsList = itemsList.createGrouped(getGroupKey, getGroupData, compareGroups);
    
  4. Haz que tus datos sean accesibles para otras partes del programa. En este ejemplo se usa WinJS.Namespace.define para que la lista agrupada sea accesible al público.

        WinJS.Namespace.define("myData",
            {
                groupedItemsList: groupedItemsList
            }); 
    
    
    })(); // End of data.js
    

Crear dos controles ListView

Tal y como hemos dicho antes, el control SemanticZoom requiere dos controles más con los que se implementa la interfaz IZoomableView: uno de ellos proporciona la vista ampliada y el otro, la vista alejada.

  1. En la sección head de la página HTML que va a contener el SemanticZoom, agrega una referencia al archivo de datos que creaste en el paso anterior.

    
    
        <!-- Your data file. -->
        <script src="/js/data.js"></script>
    
  2. Define tres plantillas para tus objetos ListView: una para la vista ampliada de elementos, otra para los encabezados de grupo en la vista ampliada y otra para los encabezados de grupo en la vista alejada.

    <!-- Template for the group headers in the zoomed-in view. -->
    <div id="headerTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
        <div class="simpleHeaderItem">
            <h1 data-win-bind="innerText: title"></h1>
        </div>
    </div>
    
    <!-- Template for the ListView items in the zoomed-in view. -->
    <div id="mediumListIconTextTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
        <div class="mediumListIconTextItem">
            <img class="mediumListIconTextItem-Image" data-win-bind="src: picture" />
            <div class="mediumListIconTextItem-Detail">
                <h4 data-win-bind="innerText: title"></h4>
                <h6 data-win-bind="innerText: text"></h6>
            </div>
        </div>
    </div>
    
    <!-- Template for the zoomed out view of the semantic view. -->
    <div id="semanticZoomTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
        <div class="semanticZoomItem">
            <h1 class="semanticZoomItem-Text" data-win-bind="innerText: title"></h1>
        </div>
    </div>
    
  3. Define dos controles ListView en tu HTML. El primer control proporciona la vista acercada y el segundo, la vista alejada.

    • Establece el itemDataSource de la vista ListView ampliada en myData.groupedItemList.dataSource, que es el IListDataSource que contiene los elementos que se van a mostrar. Establece su groupDataSource en myData.groupedItemsList.groups.dataSource, que es el IListDataSource que contiene la información de grupo.
    • En cuanto a la vista ListView alejada, establece su itemDataSource en myData.groupedItemList.groups.dataSource, que es la vista IListDataSource que contiene la información de grupo. De ahí es de donde ListView obtiene los títulos de grupo que mostrar.

    En este ejemplo se crean dos controles ListView y se configuran para usar las plantillas que acabamos de crear.

    
    
        <!-- The zoomed-in view. -->    
        <div id="zoomedInListView"
            data-win-control="WinJS.UI.ListView" 
            data-win-options="{ itemDataSource: myData.groupedItemsList.dataSource, itemTemplate: select('#mediumListIconTextTemplate'), groupHeaderTemplate: select('#headerTemplate'), groupDataSource: myData.groupedItemsList.groups.dataSource, selectionMode: 'none', tapBehavior: 'none', swipeBehavior: 'none' }"
        ></div>
    
        <!--- The zoomed-out view. -->
        <div id="zoomedOutListView"
            data-win-control="WinJS.UI.ListView"
            data-win-options="{ itemDataSource: myData.groupedItemsList.groups.dataSource, itemTemplate: select('#semanticZoomTemplate'), selectionMode: 'none', tapBehavior: 'invoke', swipeBehavior: 'none' }"
        ></div>
    
  4. En tu archivo CSS, define los estilos de las plantillas y los controles ListView. Si no realizas este paso, la aplicación se ejecutará sin problemas, pero tendrá peor apariencia.

    /* Template for headers in the zoomed-in ListView */
    .simpleHeaderItem
    {
        width: 50px;
        height: 50px;
        padding: 8px;
    }   
    
    /* Template for items in the zoomed-in ListView */  
    .mediumListIconTextItem
    {
        width: 282px;
        height: 70px;
        padding: 5px;
        overflow: hidden;
        display: -ms-grid;
    }
    
        .mediumListIconTextItem img.mediumListIconTextItem-Image 
        {
            width: 60px;
            height: 60px;
            margin: 5px;
            -ms-grid-column: 1;
        }
    
        .mediumListIconTextItem .mediumListIconTextItem-Detail
        {
            margin: 5px;
            -ms-grid-column: 2;
        }
    
    /* Template for items in the zoomed-out ListView */
    .semanticZoomItem
    {
        width: 130px;
        height: 130px;
        background-color: rgba(38, 160, 218, 1.0);
    }   
    
        .semanticZoomItem .semanticZoomItem-Text
        {
            padding: 10px;
            line-height: 150px;
            white-space: nowrap;
            color: white;
        }
    
    /* CSS for the zoomed-in ListView */
    #zoomedInListView
    {
        width: 600px;
        height: 300px;
        border: solid 2px rgba(0, 0, 0, 0.13);
    }
    
    #semanticZoomDiv 
    {
        width: 600px;
        height: 300px;
        border: solid 2px rgba(0, 0, 0, 0.13);
    }
    
  5. Ejecuta la aplicación. Verás dos controles ListView:

    Dos controles ListView

El primer control ListView proporciona la vista acercada y el segundo proporciona la vista alejada. Observa que ambos usan un diseño horizontal. Te recomendamos que las vistas acercada y alejada de los datos siempre usen el mismo diseño.

Agregar el control SemanticZoom

En el marcado, crea el control SemanticZoom y mueve los controles ListView dentro de él.

<div id="semanticZoomDiv" data-win-control="WinJS.UI.SemanticZoom">   
            
    <!-- The zoomed-in view. -->    
    <div id="zoomedInListView"
        data-win-control="WinJS.UI.ListView" 
        data-win-options="{ itemDataSource: myData.groupedItemsList.dataSource, itemTemplate: select('#mediumListIconTextTemplate'), groupHeaderTemplate: select('#headerTemplate'), groupDataSource: myData.groupedItemsList.groups.dataSource, selectionMode: 'none', tapBehavior: 'none', swipeBehavior: 'none' }"
    ></div>

    <!--- The zoomed-out view. -->
    <div id="zoomedOutListView"
        data-win-control="WinJS.UI.ListView"
        data-win-options="{ itemDataSource: myData.groupedItemsList.groups.dataSource, itemTemplate: select('#semanticZoomTemplate'), selectionMode: 'none', tapBehavior: 'invoke', swipeBehavior: 'none' }"
    ></div>

</div>

Cuando ejecutes la aplicación, verás una sola ListView y podrás usar el zoom entre las dos vistas que definiste.

Vista alejada y vista acercada del control SemanticZoom

Nota  No configures un borde en los controles secundarios del control SemanticZoom. Si configuras bordes en SemanticZoom y en sus controles secundarios, se verán tanto el borde de SemanticZoom como el del control secundario que está en la vista. Al acercar o alejar la vista, los bordes del control secundario se ajustarán a escala junto con el contenido y no tendrán un buen aspecto. Configura un solo borde en el control SemanticZoom.

 

Usar el control SemanticZoom

Para usar el zoom entre las dos vistas:

Mecanismo de entrada Alejar Acercar
Función táctil Alejar con los dedos Acercar o alejar con los dedos, pulsar
Teclado Ctrl + Signo menos, Entrar Ctrl + Signo más, Entrar
Mouse Ctrl + Girar la rueda del ratón hacia atrás Ctrl + Girar la rueda del ratón hacia delante

 

Uso de SemanticZoom con un control personalizado

Para usar el control SemanticZoom con un control distinto de ListView, debes implementar la interfaz IZoomableView. Para ver un ejemplo que muestre el procedimiento, consulta la muestra de SemanticZoom para controles personalizados.

Hacer que el control SemanticZoom siga respondiendo

Para el usuario es importante poder alternar de forma rápida y sencilla entre las vistas acercada y alejada de un control SemanticZoom. Esto significa que los controles secundarios del control SemanticZoom no deben hacer esperar a la aplicación mientras cargan los datos. Al usar el control ListView (o una versión del control FlipView que personalizaste para implementar IZoomableView) con el SemanticZoom, usa una función de plantilla que cree marcadores de posición cuando exista la posibilidad de que los elementos no estén disponibles en el momento en que el control aparezca en pantalla. Para obtener más información sobre cómo usar marcadores de posición en plantillas de elementos, consulta FlipView.itemTemplate. Si usas un control personalizado con SemanticZoom, implementa un círculo de progreso y usa marcadores de posición en caso de que algunos elementos no vayan a estar disponibles.

Muestras

Resumen y siguientes pasos

Aprendiste a crear un SemanticZoom que usa dos controles ListView para crear sus vistas acercadas y alejadas.

A continuación, aprenderás cuándo y cómo usar el SemanticZoom en Directrices y lista de comprobación de controles SemanticZoom.

Temas relacionados

Directrices y lista de comprobación de controles SemanticZoom

SemanticZoom

Muestra de zoom semántico

ListView