빠른 시작: SemanticZoom 추가(HTML)

[ 이 문서는 Windows 런타임 앱을 작성하는 Windows 8.x 및 Windows Phone 8.x 개발자를 대상으로 합니다. Windows 10용으로 개발하는 경우에는 최신 설명서를 참조하세요.]

SemanticZoom 컨트롤을 사용하여 동일한 콘텐츠의 확대 또는 축소 보기로 전환하는 방법을 알아봅니다.

사전 요구 사항

SemanticZoom 컨트롤이란?

SemanticZoom 컨트롤을 사용하여 동일한 콘텐츠의 두 보기 간에 전환할 수 있습니다. 두 보기 중 하나가 콘텐츠의 기본 보기입니다. 두 번째 보기는 동일한 콘텐츠를 사용자가 빠르게 탐색할 수 있는 방식으로 표현한 보기입니다. 예를 들면 주소록을 볼 때 사용자는 글자 하나를 확대하여 해당 글자와 연결된 이름을 볼 수 있습니다.

이러한 확대/축소 기능을 제공하기 위해 SemanticZoom 컨트롤은 다른 두 개의 컨트롤, 즉 확대 보기를 제공할 컨트롤과 축소 보기를 제공할 컨트롤을 사용합니다.

<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>

이러한 컨트롤은 IZoomableView 인터페이스를 구현하는 임의의 두 컨트롤일 수 있습니다. WinJS는 IZoomableView 인터페이스를 구현하는 컨트롤(ListView 컨트롤)을 제공합니다. 이 빠른 시작의 예제는 SemanticZoom을 두 ListView 컨트롤과 함께 사용하는 방법을 보여 줍니다.

시맨틱 줌을 광학 줌과 혼동하지 마세요. 두 확대 방식은 조작 방식과 기본 동작(확대 축소 비율에 따라 더 많이 또는 더 자세히 표시)은 같지만, 광학 줌은 사진처럼 개체나 콘텐츠 영역에 대해 배율을 조정하는 것을 의미합니다.

데이터 만들기

SemanticZoom을 사용하려면 그룹 정보를 포함하는 IListDataSource가 필요합니다. IListDataSource를 만드는 방법 중 하나는 WinJS.Binding.List를 만드는 것입니다. 각 WinJS.Binding.List에는 데이터가 포함된 IListDataSource를 반환하는 dataSource 속성이 있습니다.

  1. 프로젝트에 데이터를 포함할 새 JavaScript 파일을 추가합니다. 이름을 "data.js"로 지정합니다.

  2. 방금 만든 data.js 파일에서 ListView 컨트롤에 데이터를 제공할 기본 데이터 원본을 만듭니다. 다음 예제에서는 JSON 개체 배열(myData)에서 WinJS.Binding.List를 만듭니다.

    
    // 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);
    

    참고  이 데이터는 여러 이미지를 나타냅니다. 이미지를 가져오려면 ListView 그룹화 및 SemanticZoom 샘플(영문)을 다운로드한 다음 샘플의 이미지를 프로젝트에 복사합니다. 고유한 이미지를 사용할 수도 있습니다.—데이터에서 picture 속성의 값을 업데이트하면 됩니다.

     

      

    WinJS.Binding.List만 사용하도록 제한되지는 않습니다. StorageDataSource 또는 사용자 지정 VirtualizedDataSource를 사용할 수도 있습니다. 사용자 지정 데이터 원본을 만드는 방법에 대한 자세한 내용은 사용자 지정 데이터 원본을 만드는 방법을 참조하세요.

     

  3. 그룹화 정보를 포함하는 데이터 원본 버전을 만듭니다. WinJS.Binding.List를 사용하는 경우 해당 createGrouped 메서드를 호출하여 그룹화된 List 버전을 만들 수 있습니다. createGrouped 메서드는 다음 3개의 매개 변수를 사용합니다.

    • getGroupKey: 목록에 항목이 있을 경우 항목이 속하는 그룹 키를 반환하는 함수입니다.
    • getGroupData: 목록에 항목이 있을 경우 항목이 속하는 그룹을 나타내는 데이터 개체를 반환하는 함수입니다.
    • compareGroups: 두 그룹을 비교한 다음 첫 번째 그룹이 두 번째 그룹보다 작으면 0보다 작은 값을 반환하고, 그룹이 같으면 0을 반환하고, 첫 번째 그룹이 두 번째 그룹보다 크면 양수 값을 반환하는 함수입니다.

    다음 예제에서는 List.createGrouped 메서드를 사용하여 그룹화된 List 버전을 만듭니다. 이 메서드는 각 항목의 첫 글자를 사용하여 그룹을 정의합니다.

        // 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. 데이터를 프로그램의 다른 부분에서 액세스할 수 있게 합니다. 다음 예제에서는 WinJS.Namespace.define을 사용하여 그룹화된 목록을 공개적으로 액세스할 수 있게 합니다.

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

두 ListView 컨트롤 만들기

앞에서 언급했듯이 SemanticZoom 컨트롤에는 IZoomableView 인터페이스를 구현하는 추가 컨트롤 두 개가 필요합니다. 하나는 확대 보기를 제공하고 다른 하나는 축소 보기를 제공합니다.

  1. SemanticZoom가 포함될 HTML 페이지의 head 섹션에 앞 단계에서 만든 데이터 파일에 대한 참조를 추가합니다.

    
    
        <!-- Your data file. -->
        <script src="/js/data.js"></script>
    
  2. ListView 개체에 대한 템플릿 세 개를 정의합니다. 하나는 확대된 항목 보기에 사용되고, 다른 하나는 확대 보기의 그룹 헤더에 사용되고, 마지막 하나는 축소 보기의 그룹 헤더에 사용됩니다.

    <!-- 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. HTML에서 ListView 컨트롤 두 개를 정의합니다. 첫 번째 컨트롤은 확대 보기를 제공하고 두 번째 컨트롤은 축소 보기를 제공합니다.

    • 확대된 ListViewitemDataSource를 표시할 항목이 포함된 IListDataSource인 myData.groupedItemList.dataSource로 설정합니다. groupDataSource를 그룹 정보가 포함된 IListDataSource인 myData.groupedItemsList.groups.dataSource로 설정합니다.
    • 축소된 ListViewitemDataSource를 그룹 정보가 포함된 IListDataSource인 myData.groupedItemList.groups.dataSource로 설정합니다. ListView는 여기서 표시할 그룹 제목을 가져옵니다.

    이 예제에서는 ListView 컨트롤 두 개를 만들고 방금 만든 템플릿을 사용하도록 구성합니다.

    
    
        <!-- 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. CSS 파일에서 템플릿과 ListView 컨트롤에 대한 스타일을 정의합니다. 이 단계를 건너뛸 경우 앱이 실행되기는 하지만 멋지게 표시되지 않습니다.

    /* 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. 앱을 실행합니다. ListView 컨트롤 두 개가 표시됩니다.

    두 ListView 컨트롤

첫 번째 ListView는 확대된 보기를 제공하고 두 번째는 축소된 보기를 제공합니다. 둘 모두 가로 레이아웃을 사용합니다. 데이터의 확대된 보기 및 축소된 보기는 항상 동일한 레이아웃을 사용하는 것이 좋습니다.

SemanticZoom 컨트롤 추가

SemanticZoom 컨트롤을 만들고 이 컨트롤 안으로 ListView 컨트롤을 옮깁니다.

<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>

이제 앱을 실행하면 하나의 ListView가 표시되며 정의된 두 보기 간에 확대/축소할 수 있습니다.

SemanticZoom 컨트롤의 확대/축소 보기

참고  SemanticZoom 컨트롤의 자식 컨트롤에 테두리를 설정하지 마세요. SemanticZoom과 그 자식 컨트롤 위에 테두리를 설정하면 SemanticZoom 테두리와 보기 안에 있는 자식 컨트롤의 테두리가 둘 다 표시됩니다. 확대/축소할 때 자식 컨트롤의 테두리가 콘텐츠와 함께 확대/축소되면 보기에 좋지 않습니다. SemanticZoom 컨트롤에만 테두리를 설정하세요.

 

SemanticZoom 사용

두 보기 간에 확대/축소하려면

입력 메커니즘 축소 확대
터치 손가락을 모아 확대 손가락을 모아 탭하기
키보드 Ctrl + 빼기 기호, Enter Ctrl + 더하기 기호, Enter
마우스 Ctrl + 마우스 휠을 뒤로 회전 Ctrl + 마우스 휠을 앞으로 회전

 

SemanticZoom을 사용자 지정 컨트롤과 함께 사용

SemanticZoomListView가 아닌 다른 컨트롤과 함께 사용하려면 IZoomableView 인터페이스를 구현해야 합니다. 구현 방법을 보여 주는 샘플은 사용자 지정 컨트롤용 SemanticZoom 샘플을 참조하세요.

SemanticZoom의 응답성 유지

사용자가 SemanticZoom 확대 보기와 축소 보기 간에 빠르고 원활하게 전환할 수 있어야 합니다. 다시 말해서 SemanticZoom 컨트롤의 자식 컨트롤로 인해 데이터를 로드하는 동안 앱에 대기 시간이 발생하지 않아야 합니다. ListView(IZoomableView를 구현하도록 사용자 지정한 FlipView의 버전)를 SemanticZoom과 함께 사용하는 경우 컨트롤이 뷰에 표시되는 동안 항목을 사용하지 못하게 될 수 있는 경우 자리 표시자를 만드는 템플릿 작성 함수를 사용합니다. 항목 템플릿의 자리 표시자 사용에 대한 자세한 내용은 FlipView.itemTemplate을 참조하세요. 사용자 지정 컨트롤을 SemanticZoom과 함께 사용하는 경우 진행률 표시원을 구현하고 항목을 사용하지 못하게 될 수 있는 경우 자리 표시자를 사용합니다.

샘플

요약 및 다음 단계

ListView 컨트롤을 사용하여 확대 보기와 축소 보기를 제공하는 SemanticZoom을 만드는 방법을 배웠습니다.

이제 SemanticZoom 컨트롤에 대한 지침과 검사 목록을 읽고 SemanticZoom을 사용하는 경우와 사용 방법에 대해 알아보시기 바랍니다.

관련 항목

SemanticZoom 컨트롤 관련 지침 및 검사 목록

SemanticZoom

시맨틱 줌 샘플

ListView