次の方法で共有


クイック スタート: DOM ジェスチャおよび操作 (HTML)

[ この記事は、Windows ランタイム アプリを作成する Windows 8.x および Windows Phone 8.x 開発者を対象としています。Windows 10 向けの開発を行っている場合は、「最新のドキュメント」をご覧ください]

基本的なドキュメント オブジェクト モデル (DOM) のジェスチャ イベントの処理により、Windows のタッチ言語で記述されている基本的なジェスチャ (スライド、回転、サイズ変更など) の一部のユーザー エクスペリエンスをカスタマイズできます。

Windows 8.1 の変更点: Windows 8.1 では、ポインター入力 API に対するさまざまな変更や改良が行われています。詳しくは、「Windows 8.1 の API の変更点」をご覧ください。

JavaScript を使ってアプリを開発するのが初めての場合: 以下のトピックに目を通して、ここで説明されているテクノロジをよく理解できるようにしてください。

JavaScript を使った初めてのアプリの作成

JavaScript を使ったアプリのためのロードマップ

イベントについては、「クイック スタート: HTML コントロールの追加とイベントの処理」をご覧ください。

アプリの機能の概要:

この機能について詳しくは、「アプリの機能の概要」シリーズをご覧ください。

ユーザー操作の概要 (HTML)

ユーザー操作のカスタマイズの概要 (HTML)

ユーザー エクスペリエンス ガイドライン:

プラットフォーム コントロール ライブラリ (HTMLXAML) は、標準的な対話式操作、アニメーション化された物理的効果、視覚的フィードバックなど、完全なユーザー操作エクスペリエンスを提供しています。 操作のサポートをカスタマイズする必要がない場合は、これらのビルトイン コントロールを使います。

プラットフォーム コントロールでは十分に対応できない場合は、以下のユーザー操作ガイドラインに従うと、どの入力モードでも一貫性のある、魅力的でイマーシブな対話式操作エクスペリエンスを実現できます。これらのガイドラインは、主にタッチ入力を対象として説明していますが、タッチパッド、マウス、キーボード、スタイラスでの入力にも当てはまります。

サンプル: アプリのサンプルで、この機能の動作を実際に確かめることができます。

ユーザー操作のカスタマイズの概要のサンプルに関するページ

HTML のスクロール、パン、ズームのサンプルに関するページ

入力: DOM ポインター イベント処理のサンプルに関するページ

入力: インスタンス化できるジェスチャのサンプルに関するページ

目標: タッチ、マウス、ペン/スタイラスによる対話式操作からの入力と DOM ジェスチャ イベントを使って、変換、回転、拡大縮小の基本ジェスチャをリッスンし、処理する方法について理解する。

必要条件

クイック スタート: ポインター」をご覧ください。

JavaScript 用 Windows ライブラリのテンプレートが使われた JavaScript を使った基本的なアプリの作成経験が必要です。

このチュートリアルを行うには、次の作業を行う必要があります。

完了までの時間: 30 分.

ジェスチャ イベントとは

ジェスチャは、入力デバイス (タッチ画面上の 1 本以上の指、ペン/スタイラス デジタイザー、マウスなど) 上や、入力デバイスにより実行される物理的な動作や動きです。これらの自然な対話式操作は、システムとアプリの両方の要素に対する操作にマップされます。 詳しくは、「ジェスチャ、操作、対話的操作」をご覧ください。

Windows は、ジェスチャの基本セットに依存して UI を操作します。

ジェスチャ説明
タップタップ ジェスチャ

1 か所の接触が検出され、すぐに離れます。

要素をタップするとプライマリ操作が呼び出されます。

長押し長押しジェスチャ

1 か所の接触が検出され、そのまま動きません。

長押しにより、詳しい情報や説明を伝える視覚効果 (ヒントやコンテキスト メニューなど) が表示されます。操作はコミットされません。

スライドスライド ジェスチャ

1 か所以上の接触が検出され、同じ方向に動きます。

スライドは主にパン操作に使われますが、移動、描画、筆記などの操作に使うこともできます。

スワイプスワイプ ジェスチャ

1 か所以上の接触が検出され、同じ方向に少しだけ動きます。

スワイプにより選択、コマンド実行、移動を行います。

回転回転ジェスチャ

2 か所以上の接触が検出され、時計回りまたは反時計回りに回転します。

指を違う方向に動かすことにより回転します。

ピンチピンチ ジェスチャ

2 か所以上の接触が検出され、近づくように動きます。

ピンチにより縮小表示されます。

ストレッチストレッチ ジェスチャ

2 か所以上の接触が検出され、離れるように動きます。

ストレッチにより拡大表示されます。

これらのジェスチャと、Windows のタッチ言語との関係について詳しくは、「タッチ操作の設計」をご覧ください。

 

ジェスチャ検出により、アプリの操作モデルを拡張し、「クイック スタート: ポインター入力の処理」に記載されている基本的なポインター イベントをベースに構築することができます。 実際、アプリは多くの場合ジェスチャ イベント (タップの処理、スライドによるパンまたは移動、ピンチまたはストレッチによるズームなど) を使い、生のポインター データを使ってジェスチャの検出と処理をサポートします。

アプリでは、複数のジェスチャの同時処理 (ズームと回転など)、特定の要素をターゲットとするポインター接触のグループ化 (すべての接触を最初のまたは主要な接触のターゲットと関連付けるなど)、特定のジェスチャまたはポインター接触のターゲットとなる特定の要素の識別を行うことができます。

重要  独自の対話式操作サポートを実装する場合は、ユーザーはアプリの UI 要素を直接操作できる直感的なエクスペリエンスを期待しているということを心に留めておいてください。 プラットフォーム コントロール ライブラリ (HTMLXAML) でのカスタムの対話式操作をモデル化し、一貫性と見つけやすさを維持することをお勧めします。これらのライブラリのコントロールでは、標準的な対話式操作、アニメーション化された物理的効果、視覚的フィードバック、アクセシビリティなど、完全なユーザー操作エクスペリエンスが提供されます。はっきりとした明確に定義されている要件があり、基本的な対話式操作ではシナリオがサポートされない場合のみ、カスタムの対話式操作を作ってください。

 

UI を作る

この例では、ポインター入力、ジェスチャ検出、処理のターゲット オブジェクトとして四角形 (target) を使います。

四角形は、基本的な色ミキサーとして機能します。ターゲットの色は、RGB 色の選択 (赤、緑、青) と、回転ジェスチャによって報告されるターゲットの回転角度に基づいて変わります (回転の角度から赤色、緑色、または青色の値を計算します)。

ターゲット オブジェクト内の各ポインターとジェスチャ イベントの詳細と、ターゲットに適用される現在の変換マトリックスを表示します。

この例の HTML を次に示します。

<html>
<head>
    <meta charset="utf-8" />
    <title>PointerInput</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.2.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.2.0/js/ui.js"></script>

    <!-- BasicGesture references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
</head>
<body>
    <div class="TargetContainer" id="targetContainer">
        <div id="colorMixer">
            <input type="radio" name="color" value="R" title="Red" id="red" class="Red" /><label for="red" id="labelRed">Red</label>
            <input type="radio" name="color" value="G" title="Green" id="green" class="Green" /><label for="green" id="labelGreen">Green</label>
            <input type="radio" name="color" value="B" title="Blue" id="blue" class="Blue" /><label for="blue" id="labelBlue">Blue</label>
            <div id="targetLog"></div>
            <div id="eventLog"></div>
        </div>
    </div>
</body>
</html>

この例のカスケード スタイル シート (CSS) を次に示します。

  パンまたはズームの操作中はポインター イベントが発生しません。領域のパンとズームは、CSS プロパティ msTouchActionoverflow-ms-content-zooming を使って無効にできます。

 

body {
    overflow: hidden;
    position: relative;
}

div #targetContainer {
/*
Set the width and height properties of the target container to fill the viewport. 
You can set these properties to 100%, but we use 100vw (viewport width) and 100vh (viewport height).
See https://go.microsoft.com/fwlink/?LinkID=301480 for more detail on CSS units supported by Internet Explorer.
*/
    height: 100vw;
    width: 100vh;
    overflow: hidden;
    position: absolute;
}

div #colorMixer {
/*
A manipulation-blocking element is defined as an element that explicitly 
blocks direct manipulation via declarative markup, and instead fires gesture 
events such as MSGestureStart, MSGestureChange, and MSGestureEnd.
*/
    touch-action: none;
    -ms-transform-origin: 0px 0px;
    position: absolute;
    background-color: black;
    border-color: white;
    border-width: thick;
    border-style: solid;
}

div #colorSelector {
    position: relative;
}

div #eventLog {
    -ms-overflow-style:scrollbar;
}

input.Red {
    background-color: rgb(255,0,0);
}

input.Green {
    background-color: rgb(0,255,0);
}

input.Blue {
    background-color: rgb(0,0,255);
}

ポインター イベントとジェスチャ イベントをリッスンする

次のコードでは、色ミキサーと色セレクターを設定し、さまざまなイベント リスナーを宣言します。

ほとんどの場合は、選んだ言語フレームワークのポインター イベント ハンドラーのイベント引数を介してポインター情報を取得することをお勧めします。

アプリに必要なポインターの詳細をイベント引数が公開していない場合は、getCurrentPointgetIntermediatePoints メソッドか、currentPointintermediatePoints プロパティを通じて、イベント引数の拡張ポインター データにアクセスできます。ポインター データのコンテキストを指定できるので、getCurrentPointgetIntermediatePoints メソッドを使うことをお勧めします。

まず、グローバル変数を宣言し、ターゲットの状態を追跡するためのデータ オブジェクト (colorInfo) を定義し、色ミキサー (target) と RGB 色セレクターの両方を初期化します。

var _width = 640;
var _height = 640;

var _pointerInfo;
var _targetLog;

var _selectedColor;
var _colorRed, _colorGreen, _colorBlue;

// Color-specific data object.
//   value: The color value (r, g, or b)
//   rotation: The rotation value used to calculate color value.
//   matrix: The transform matrix of the target.
function colorInfo(value, rotation, matrix) {
    this.value = value;
    this.rotation = rotation;
    this.matrix = matrix;
}

function initialize() {
    // Configure the target.
    setTarget();

    // Initialize color tracking.
    setColors();
}

次に、色ミキサーを設定し、ジェスチャ認識エンジン (msGesture) をオブジェクトに関連付け、さまざまなイベント リスナーを宣言します。

ヒント  この例では、ジェスチャ認識エンジンに 1 つのオブジェクトだけが関連付けられています。多数の操作対象オブジェクトがあるアプリ (ジグソー パズルなど) の場合は、ターゲット オブジェクトでポインター入力が検出されたときにだけジェスチャ認識エンジンを動的に作ることを検討してください。ジェスチャ認識エンジンは、操作が完了したら破棄できます (その例については、入力: インスタンス化できるジェスチャのサンプルに関するページをご覧ください)。ジェスチャ認識エンジンの作成と破棄のオーバーヘッドを避けるには、初期化時にジェスチャ認識エンジンの小規模なプールを作り、必要に応じてそれらを動的に割り当てます。

 

// Configure the interaction target.
function setTarget() {
    //  Set up the target position, size, and transform.
    colorMixer.style.width = _width + "px";
    colorMixer.style.height = _height + "px";
    colorMixer.style.msTransform = (new MSCSSMatrix()).
        translate((window.innerWidth - parseInt(colorMixer.style.width)) / 2.0,
        (window.innerHeight - parseInt(colorMixer.style.height)) / 2.0);

    // Create gesture recognizer.
    var msGesture = new MSGesture();
    msGesture.target = colorMixer;
    colorMixer.gesture = msGesture;
    // Expando property for handling multiple pointer devices.
    colorMixer.gesture.pointerType = null;

    // Expando property to track pointers.
    colorMixer.pointers = [];

    // Declare event handlers.
    colorMixer.addEventListener("pointerdown", onPointerDown, false);
    colorMixer.addEventListener("pointerup", onPointerUp, false);
    colorMixer.addEventListener("pointercancel", onPointerCancel, false);
    colorMixer.addEventListener("lostpointercapture", onLostPointerCapture, false);
    colorMixer.addEventListener("MSGestureChange", onMSGestureChange, false);
    colorMixer.addEventListener("MSGestureTap", onMSGestureTap, false);
    colorMixer.addEventListener("MSGestureEnd", onMSGestureEnd, false);
    colorMixer.addEventListener("MSGestureHold", onMSGestureHold, false);
}

最後に、RGB 色セレクター (イベント リスナーを含む) と colorInfo オブジェクトを初期化します。

// Initialize values and event listeners for color tracking.
function setColors() {
    var m = new MSCSSMatrix(colorMixer.style.msTransform);
    _colorRed = new colorInfo(0, 0, m);
    _colorGreen = new colorInfo(0, 0, m);
    _colorBlue = new colorInfo(0, 0, m);

    document.getElementById("red").addEventListener("click", onColorChange, false);
    document.getElementById("green").addEventListener("click", onColorChange, false);
    document.getElementById("blue").addEventListener("click", onColorChange, false);
}

// Re-draw target based on transform matrix associated with color selection.
function onColorChange(e) {
    switch (e.target.id) {
        case "red":
            colorMixer.style.msTransform = _colorRed.matrix;
            break;
        case "green":
            colorMixer.style.msTransform = _colorGreen.matrix;
            break;
        case "blue":
            colorMixer.style.msTransform = _colorBlue.matrix;
            break;
    }
    _selectedColor = e.target.id;

    eventLog.innerText = "Color change";
    targetLog.innerText = colorMixer.style.msTransform;
}

ポインター ダウン イベントを処理する

ポインター ダウン イベントで、選んだ RGB 色を取得し、addPointer メソッドを呼び出してポインターをジェスチャ認識エンジンに関連付けます。シーケンスと pointerType を追跡し、必要に応じてポインターとジェスチャ認識エンジンをもう一度関連付けます。

色が選ばれていない場合、ポインター イベントを無視します。

// Pointer down handler: Attach the pointer to a gesture object.
function onPointerDown(e) {
    // Do not attach pointer if no color selected.
    if (_selectedColor === undefined)
        return;
    _selectedColor = getSelectedColor();

    // Process pointer.
    if (e.target === this) {
        this.style.borderStyle = "double";
        //  Attach first contact and track device.
        if (this.gesture.pointerType === null) {
            this.gesture.addPointer(e.pointerId);
            this.gesture.pointerType = e.pointerType;
        }
            // Attach subsequent contacts from same device.
        else if (e.pointerType === this.gesture.pointerType) {
            this.gesture.addPointer(e.pointerId);
        }
            // New gesture recognizer for new pointer type.
        else {
            var msGesture = new MSGesture();
            msGesture.target = e.target;
            e.target.gesture = msGesture;
            e.target.gesture.pointerType = e.pointerType;
            e.target.gesture.addPointer(e.pointerId);
        }
    }
    eventLog.innerText = "Pointer down";
}

// Get the current color.
function getSelectedColor() {
    var colorSelection = document.getElementsByName("color");
    for (var i = 0; i < colorSelection.length; i++) {
        if (colorSelection[i].checked)
            return colorSelection[i].id;
    }
}

ジェスチャ イベントを処理する

このコードでは、移動 (スライドまたはスワイプ)、回転、拡大縮小 (ピンチまたはストレッチ) のジェスチャを処理します。

// Gesture change handler: Process gestures for translation, rotation, and scaling.
// For this example, we don't track pointer movements.
function onMSGestureChange(e) {
    // Get the target associated with the gesture event.
    var elt = e.gestureObject.target;
    // Get the matrix transform for the target.
    var matrix = new MSCSSMatrix(elt.style.msTransform);

    // Process gestures for translation, rotation, and scaling.
    e.target.style.msTransform = matrix.
        translate(e.offsetX, e.offsetY).
        translate(e.translationX, e.translationY).
        rotate(e.rotation * 180 / Math.PI).
        scale(e.scale).
        translate(-e.offsetX, -e.offsetY);

    // Mix the colors based on rotation value.
    switch (_selectedColor) {
        case "red":
            _colorRed.rotation += ((e.rotation * 180 / Math.PI));
            _colorRed.rotation = _colorRed.rotation % 360;
            targetLog.innerText = _colorRed.rotation.toString();
            if (_colorRed.rotation >= 0)
                _colorRed.value = parseInt(Math.abs(_colorRed.rotation) * (256 / 360));
            else
                _colorRed.value = parseInt((360 - Math.abs(_colorRed.rotation)) * (256 / 360));
            document.getElementById("labelRed").innerText = _colorRed.value.toString();
            _colorRed.matrix = matrix;
            break;
        case "green":
            _colorGreen.rotation += ((e.rotation * 180 / Math.PI));
            _colorGreen.rotation = _colorGreen.rotation % 360;
            targetLog.innerText = _colorGreen.rotation.toString();
            if (_colorGreen.rotation >= 0)
                _colorGreen.value = parseInt(Math.abs(_colorGreen.rotation) * (256 / 360));
            else
                _colorGreen.value = parseInt((360 - Math.abs(_colorGreen.rotation)) * (256 / 360));
            document.getElementById("labelGreen").innerText = _colorGreen.value.toString();
            _colorGreen.matrix = matrix;
            break;
        case "blue":
            _colorBlue.rotation += ((e.rotation * 180 / Math.PI));
            _colorBlue.rotation = _colorBlue.rotation % 360;
            if (_colorBlue.rotation >= 0)
                _colorBlue.value = parseInt(Math.abs(_colorBlue.rotation) * (256 / 360));
            else
                _colorBlue.value = parseInt((360 - Math.abs(_colorBlue.rotation)) * (256 / 360));
            document.getElementById("labelBlue").innerText = _colorBlue.value.toString();
            _colorBlue.matrix = matrix;
            break;
    }
    e.target.style.backgroundColor = "rgb(" + _colorRed.value + ", " + _colorGreen.value + ", " + _colorBlue.value + ")";
    targetLog.innerText = e.target.style.msTransform;
    eventLog.innerText = "Gesture change";
}

必要に応じて、その他のイベントを処理する

この例では、ここで処理した他のイベントのみを報告します。より堅牢なアプリでは追加機能を提供します。

// Tap gesture handler: Display event.
// The touch language described in Touch interaction design (https://go.microsoft.com/fwlink/?LinkID=268162),
// specifies that the tap gesture should invoke an elements primary action (such as launching an application 
// or executing a command). 
// The primary action in this sample (color mixing) is performed through the rotation gesture.
function onMSGestureTap(e) {
    eventLog.innerText = "Gesture tap";
}

// Gesture end handler: Display event.
function onMSGestureEnd(e) {
    if (e.target === this) {
        this.style.borderStyle = "solid";
    }
    eventLog.innerText = "Gesture end";
}

// Hold gesture handler: Display event.
function onMSGestureHold(e) {
    eventLog.innerText = "Gesture hold";
}

// Pointer up handler: Display event.
function onPointerUp(e) {
    eventLog.innerText = "Pointer up";
}

// Pointer cancel handler: Display event.
function onPointerCancel(e) {
    eventLog.innerText = "Pointer canceled";
}

// Pointer capture lost handler: Display event.
function onLostPointerCapture(e) {
    eventLog.innerText = "Pointer capture lost";
}

さらに複雑なサンプルへのリンクについては、このページの最後にある関連トピックをご覧ください。

完全な例

DOM ジェスチャおよび操作のコード一式」をご覧ください。

要約と次のステップ

このクイック スタートでは、JavaScript を使った Windows ストア アプリでの基本的なジェスチャ イベントの処理について説明しました。

ポインター イベントと組み合わせて使われる基本的なジェスチャ認識は、移動 (スライドまたはスワイプ)、回転、拡大縮小 (ピンチまたはストレッチ) などの単純な対話式操作の管理に便利です。

より複雑な対話式操作の処理とフル カスタマイズされたユーザー操作エクスペリエンスの提供については、「クイック スタート: 静的ジェスチャ」と「クイック スタート: 操作ジェスチャ」をご覧ください。

Windows 8 のタッチ言語について詳しくは、「タッチ操作の設計」をご覧ください。

関連トピック

開発者向け

ユーザー操作への応答

Windows ストア アプリの開発 (JavaScript と HTML)

クイック スタート: ポインター

クイック スタート: 静的ジェスチャ

クイック スタート: 操作ジェスチャ

デザイナー向け

タッチ操作の設計