クイック スタート: SemanticZoom の追加 (HTML)
[ この記事は、Windows ランタイム アプリを作成する Windows 8.x および Windows Phone 8.x 開発者を対象としています。Windows 10 向けの開発を行っている場合は、「最新のドキュメント」をご覧ください]
SemanticZoom コントロールを使って、拡大表示と縮小表示という 2 種類の方法で同じコンテンツを表示する方法について説明します。
必要条件
- JavaScript コントロール用 Windows ライブラリを使う、JavaScript で開発された基本的な Windows ストア アプリの作成経験が必要です。WinJS のコントロールを使う手順については、「クイック スタート: WinJS コントロールとスタイルの追加」をご覧ください。
- このクイック スタートの内容を理解するには、ListView コントロールの使い方を理解している必要があります。ListView コントロールの概要については、「クイック スタート: ListView の追加」をご覧ください。
- SemanticZoom コントロールを使うには、グループ化された ListView の作成方法を理解している必要があります。詳しくは、「ListView 内の項目をグループ化する方法」をご覧ください。
SemanticZoom コントロールとは
SemanticZoom コントロールを使うと、同じコンテンツの 2 つの異なる表示を切り替えることができます。その 1 つは、コンテンツのメイン表示です。もう 1 つは、ユーザーがコンテンツ内を簡単に移動できる方法で表現した、同じコンテンツの表示です。たとえば、アドレス帳を表示しているときに、ユーザーは文字を拡大表示して、その文字に関連付けられている名前を調べることができます。
ズーム機能を備えるために、SemanticZoom コントロールは 2 つの他のコントロールを使います。その 1 つで拡大表示を実行し、もう 1 つで縮小表示を実行します。
<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 インターフェイスを実装する任意の 2 つのコントロールを使うことができます。WinJS には、IZoomableView インターフェイスを実装するコントロールが 1 つ用意されています。ListView コントロールです。このクイック スタートでは、2 つの ListView コントロールが使われている SemanticZoom の使い方の例を示します。
セマンティック ズームと光学式ズームを混同しないように気を付けてください。操作方法と基本的な動作 (ズーム係数に基づいて詳しく表示したり簡単に表示したりする動作) は同じですが、光学式ズームでは、コンテンツ領域またはオブジェクトの倍率調整を写真のように行います。
データの作成
SemanticZoom を使うには、グループ情報が含まれる IListDataSource が必要です。 IListDataSource を作る 1 つの方法は、WinJS.Binding.List を作ることです。各 WinJS.Binding.List の dataSource プロパティは、データを含む IListDataSource を返します。
データを格納するために、新しい JavaScript ファイルをプロジェクトに追加します。"data.js" という名前を付けます。
作った 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 も使うことができます。カスタム データ ソースの作成について詳しくは、「カスタム データ ソースを作成する方法」をご覧ください。
グループ化情報が含まれるデータ ソースを作成します。 WinJS.Binding.List を使う場合は、その createGrouped メソッドを呼び出すと、グループ化された List を作成できます。createGrouped メソッドには、次の 3 つのパラメーターがあります。
- getGroupKey: 項目がリスト内にある場合に、その項目が属するグループのキーを返す関数です。
- getGroupData: 項目がリスト内にある場合に、その項目が属するグループを表すデータ オブジェクトを返す関数です。
- compareGroups: 2 つのグループを比較し、1 つ目のグループの項目数が 2 つ目のグループの項目数未満の場合は負の値、グループの項目数が等しい場合はゼロ、1 つ目のグループの項目数が 2 つ目のグループの項目数を超える場合は正の値を返す関数です。
この例では、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);
プログラム内の他の部分からデータにアクセスできるようにします。この例では、WinJS.Namespace.define を使って、グループ化されたリストにパブリックにアクセスできるようにします。
WinJS.Namespace.define("myData", { groupedItemsList: groupedItemsList }); })(); // End of data.js
2 つの ListView コントロールの作成
既に説明したように、SemanticZoom コントロールを使うには、IZoomableView インターフェイスを実装する 2 つのコントロールが追加で必要になります。その 1 つで拡大表示を実行し、もう 1 つで縮小表示を実行します。
SemanticZoom が含まれている HTML ページの head セクションに、前の手順で作ったデータ ファイルへの参照を追加します。
<!-- Your data file. --> <script src="/js/data.js"></script>
ListView オブジェクト用に 3 つのテンプレートを定義します。1 つは項目の拡大表示用、もう 1 つは拡大表示のグループ見出し用、最後の 1 つは縮小表示のグループ見出し用です。
<!-- 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>
HTML で 2 つの ListView コントロールを定義します。1 つ目のコントロールで拡大表示、2 つ目のコントロールで縮小表示を実行します。
- 拡大表示の ListView 用の itemDataSource を myData.groupedItemList.dataSource に設定します。これは、表示する項目が格納されている IListDataSource です。また、その groupDataSource を myData.groupedItemsList.groups.dataSource に設定します。これは、グループ情報が格納されている IListDataSource です。
- 縮小表示の ListView の itemDataSource を myData.groupedItemList.groups.dataSource に設定します。これは、グループ情報が格納されている IListDataSource です。ListView は、表示するグループ タイトルをここから取得します。
この例では、2 つの 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>
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); }
アプリを実行します。2 つの ListView コントロールが表示されます。
1 つ目の ListView は拡大表示を提供し、2 つ目は縮小表示を提供します。どちらも横長のレイアウトを使うことに注意してください。データの拡大表示と縮小表示では常に同じレイアウトを使うことをお勧めします。
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 が 1 つだけ表示されます。また、定義した 2 つの表示の間でズームを実行できます。
注 SemanticZoom コントロールの子コントロールに対しては、境界線を設定しないでください。 SemanticZoom コントロールとその子コントロールの両方に対して境界線を設定すると、SemanticZoom の境界線と、その中に表示される子コントロールの境界線の両方が表示されます。拡大表示または縮小表示を実行すると、子コントロールの境界線がコンテンツに合わせて拡大または縮小されるため、見た目が良くありません。SemanticZoom コントロールに対してのみ境界線を設定してください。
SemanticZoom の使用
2 種類の表示の間でのズームの方法:
入力方法 | 縮小 | 拡大 |
---|---|---|
タッチ | ピンチ アウト | ピンチ、タップ |
キーボード | Ctrl + マイナス記号、Enter キー | Ctrl + プラス記号、Enter キー |
マウス | Ctrl + マウス ホイールを下方向へ回す | Ctrl + マウス ホイールを上方向へ回す |
SemanticZoom とカスタム コントロールの使用
SemanticZoom を、ListView 以外のコントロールと共に使うには、IZoomableView インターフェイスを実装する必要があります。この方法のサンプルについては、カスタム コントロール用の SemanticZoom のサンプルに関するページをご覧ください。
SemanticZoom の応答性の維持
SemanticZoom の拡大表示と縮小表示をユーザーがすばやくスムーズに切り替えられるようにすることが重要です。このためには、SemanticZoom コントロールの子コントロールによるデータの読み込みをアプリが待つことがないようにします。ListView (または、IZoomableView を実装するようにカスタマイズした FlipView) を SemanticZoom と一緒に使う場合、コントロールが表示されるまでに項目が利用できるようにならない可能性があるときは、プレースホルダーを作るテンプレート関数を使います。項目テンプレートでのプレースホルダーの使い方について詳しくは、「FlipView.itemTemplate」をご覧ください。カスタム コントロールと SemanticZoom を使う場合は、進行状況サークルを実装し、項目が利用できない場合はプレースホルダーを使います。
サンプル
要約と次のステップ
2 つの ListView コントロールを使って拡大表示と縮小表示を実行する SemanticZoom の作成方法について説明しました。
次は、SemanticZoom を使う場合とその方法について、「SemanticZoom コントロールのガイドラインとチェック リスト」をご覧ください。